/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrScissorState_DEFINED
#define GrScissorState_DEFINED

#include "include/core/SkRect.h"

/**
 * The scissor state is stored as the scissor rectangle and the backing store bounds of the render
 * target that the scissor will apply to. If the render target is approximate fit and the padded
 * content should not be modified, the clip should apply the render target context's logical bounds
 * as part of the scissor (e.g. when stenciling). This puts the onus on the render target context
 * to intentionally discard the scissor at its logical bounds when drawing into the padded content
 * is acceptable (e.g. color-only updates).
 */
class GrScissorState {
public:
    // The disabled scissor state for a render target of the given size.
    explicit GrScissorState(const SkISize& rtDims)
            : fRTSize(rtDims)
            , fRect(SkIRect::MakeSize(rtDims)) {}

    void setDisabled() { fRect = SkIRect::MakeSize(fRTSize); }
    bool set(const SkIRect& rect) {
        this->setDisabled();
        return this->intersect(rect);
    }

    bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) {
        if (!fRect.intersect(rect)) {
            fRect.setEmpty();
            return false;
        } else {
            return true;
        }
    }

    // If the scissor was configured for the backing store dimensions and it's acceptable to
    // draw outside the logical dimensions of the target, this will discard the scissor test if
    // the test wouldn't modify the logical dimensions.
    bool relaxTest(const SkISize& logicalDimensions) {
        SkASSERT(logicalDimensions.fWidth <= fRTSize.fWidth &&
                 logicalDimensions.fHeight <= fRTSize.fHeight);
        if (fRect.fLeft == 0 && fRect.fTop == 0 && fRect.fRight >= logicalDimensions.fWidth &&
            fRect.fBottom >= logicalDimensions.fHeight) {
            this->setDisabled();
            return true;
        } else {
            return false;
        }
    }

    bool operator==(const GrScissorState& other) const {
        return fRTSize == other.fRTSize && fRect == other.fRect;
    }
    bool operator!=(const GrScissorState& other) const { return !(*this == other); }

    bool enabled() const {
        SkASSERT(fRect.isEmpty() || SkIRect::MakeSize(fRTSize).contains(fRect));
        // This is equivalent to a strict contains check on SkIRect::MakeSize(rtSize) w/o creating
        // the render target bounding rectangle.
        return fRect.fLeft > 0 || fRect.fTop > 0 ||
               fRect.fRight < fRTSize.fWidth || fRect.fBottom < fRTSize.fHeight;
    }

    // Will always be equal to or contained in the rt bounds, or empty if scissor rectangles were
    // added that did not intersect with the render target or prior scissor.
    const SkIRect& rect() const {
        SkASSERT(fRect.isEmpty() || SkIRect::MakeSize(fRTSize).contains(fRect));
        return fRect;
    }

private:
    // The scissor is considered enabled if the rectangle does not cover the render target
    SkISize fRTSize;
    SkIRect fRect;
};

#endif
