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

#include "include/core/SkPath.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkRegionPriv.h"

SkRasterClip::SkRasterClip(const SkRasterClip& that)
        : fIsBW(that.fIsBW)
        , fIsEmpty(that.fIsEmpty)
        , fIsRect(that.fIsRect)
        , fShader(that.fShader)
{
    AUTO_RASTERCLIP_VALIDATE(that);

    if (fIsBW) {
        fBW = that.fBW;
    } else {
        fAA = that.fAA;
    }

    SkDEBUGCODE(this->validate();)
}

SkRasterClip& SkRasterClip::operator=(const SkRasterClip& that) {
    AUTO_RASTERCLIP_VALIDATE(that);

    fIsBW = that.fIsBW;
    if (fIsBW) {
        fBW = that.fBW;
    } else {
        fAA = that.fAA;
    }

    fIsEmpty = that.isEmpty();
    fIsRect = that.isRect();
    fShader = that.fShader;
    SkDEBUGCODE(this->validate();)
    return *this;
}

SkRasterClip::SkRasterClip(const SkRegion& rgn) : fBW(rgn) {
    fIsBW = true;
    fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
    fIsRect = !fIsEmpty;
    SkDEBUGCODE(this->validate();)
}

SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
    fIsBW = true;
    fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
    fIsRect = !fIsEmpty;
    SkDEBUGCODE(this->validate();)
}

SkRasterClip::SkRasterClip() {
    fIsBW = true;
    fIsEmpty = true;
    fIsRect = false;
    SkDEBUGCODE(this->validate();)
}

SkRasterClip::SkRasterClip(const SkPath& path, const SkIRect& bounds, bool doAA) {
    SkRegion clip(bounds);
    if (doAA) {
        fIsBW = false;
        fAA.setPath(path, &clip, true);
    } else {
        fIsBW = true;
        fBW.setPath(path, clip);
    }
    fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
    fIsRect = this->computeIsRect();
    SkDEBUGCODE(this->validate();)
}

SkRasterClip::~SkRasterClip() {
    SkDEBUGCODE(this->validate();)
}

bool SkRasterClip::setEmpty() {
    AUTO_RASTERCLIP_VALIDATE(*this);

    fIsBW = true;
    fBW.setEmpty();
    fAA.setEmpty();
    fIsEmpty = true;
    fIsRect = false;
    return false;
}

bool SkRasterClip::setRect(const SkIRect& rect) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    fIsBW = true;
    fAA.setEmpty();
    fIsRect = fBW.setRect(rect);
    fIsEmpty = !fIsRect;
    return fIsRect;
}

/////////////////////////////////////////////////////////////////////////////////////

bool SkRasterClip::op(const SkIRect& rect, SkClipOp op) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    if (fIsBW) {
        fBW.op(rect, (SkRegion::Op) op);
    } else {
        fAA.op(rect, (SkRegion::Op) op);
    }
    return this->updateCacheAndReturnNonEmpty();
}

bool SkRasterClip::op(const SkRegion& rgn, SkClipOp op) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    if (fIsBW) {
        (void)fBW.op(rgn, (SkRegion::Op) op);
    } else {
        SkAAClip tmp;
        tmp.setRegion(rgn);
        (void)fAA.op(tmp, (SkRegion::Op) op);
    }
    return this->updateCacheAndReturnNonEmpty();
}

/**
 *  Our antialiasing currently has a granularity of 1/4 of a pixel along each
 *  axis. Thus we can treat an axis coordinate as an integer if it differs
 *  from its nearest int by < half of that value (1/8 in this case).
 */
static bool nearly_integral(SkScalar x) {
    static const SkScalar domain = SK_Scalar1 / 4;
    static const SkScalar halfDomain = domain / 2;

    x += halfDomain;
    return x - SkScalarFloorToScalar(x) < domain;
}

bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    const bool isScaleTrans = matrix.isScaleTranslate();
    if (!isScaleTrans) {
        return this->op(SkPath::Rect(localRect), matrix, op, doAA);
    }

    SkRect devRect = matrix.mapRect(localRect);
    if (fIsBW && doAA) {
        // check that the rect really needs aa, or is it close enought to
        // integer boundaries that we can just treat it as a BW rect?
        if (nearly_integral(devRect.fLeft) && nearly_integral(devRect.fTop) &&
            nearly_integral(devRect.fRight) && nearly_integral(devRect.fBottom)) {
            doAA = false;
        }
    }

    if (fIsBW && !doAA) {
        (void)fBW.op(devRect.round(), (SkRegion::Op) op);
    } else {
        if (fIsBW) {
            this->convertToAA();
        }
        (void)fAA.op(devRect, (SkRegion::Op) op, doAA);
    }
    return this->updateCacheAndReturnNonEmpty();
}

bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
    return this->op(SkPath::RRect(rrect), matrix, op, doAA);
}

bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, SkClipOp op, bool doAA) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    SkPath devPath;
    path.transform(matrix, &devPath);

    // Since op is either intersect or difference, the clip is always shrinking; that means we can
    // always use our current bounds as the limiting factor for region/aaclip operations.
    if (this->isRect() && op == SkClipOp::kIntersect) {
        // However, in the relatively common case of intersecting a new path with a rectangular
        // clip, it's faster to convert the path into a region/aa-mask in place than evaluate the
        // actual intersection. See skbug.com/12398
        SkRegion clip(this->getBounds());
        if (doAA && fIsBW) {
            this->convertToAA();
        }
        if (fIsBW) {
            fBW.setPath(devPath, clip);
        } else {
            fAA.setPath(devPath, &clip, doAA);
        }
        return this->updateCacheAndReturnNonEmpty();
    } else {
        return this->op(SkRasterClip(devPath, this->getBounds(), doAA), op);
    }
}

bool SkRasterClip::op(sk_sp<SkShader> sh) {
    AUTO_RASTERCLIP_VALIDATE(*this);

    if (!fShader) {
        fShader = sh;
    } else {
        fShader = SkShaders::Blend(SkBlendMode::kSrcIn, sh, fShader);
    }
    return !this->isEmpty();
}

bool SkRasterClip::op(const SkRasterClip& clip, SkClipOp op) {
    AUTO_RASTERCLIP_VALIDATE(*this);
    clip.validate();

    if (this->isBW() && clip.isBW()) {
        (void)fBW.op(clip.fBW, (SkRegion::Op) op);
    } else {
        SkAAClip tmp;
        const SkAAClip* other;

        if (this->isBW()) {
            this->convertToAA();
        }
        if (clip.isBW()) {
            tmp.setRegion(clip.bwRgn());
            other = &tmp;
        } else {
            other = &clip.aaRgn();
        }
        (void)fAA.op(*other, (SkRegion::Op) op);
    }
    return this->updateCacheAndReturnNonEmpty();
}

void SkRasterClip::translate(int dx, int dy, SkRasterClip* dst) const {
    if (nullptr == dst) {
        return;
    }

    AUTO_RASTERCLIP_VALIDATE(*this);

    if (this->isEmpty()) {
        dst->setEmpty();
        return;
    }
    if (0 == (dx | dy)) {
        *dst = *this;
        return;
    }

    dst->fIsBW = fIsBW;
    if (fIsBW) {
        fBW.translate(dx, dy, &dst->fBW);
        dst->fAA.setEmpty();
    } else {
        fAA.translate(dx, dy, &dst->fAA);
        dst->fBW.setEmpty();
    }
    dst->updateCacheAndReturnNonEmpty();
}

void SkRasterClip::convertToAA() {
    AUTO_RASTERCLIP_VALIDATE(*this);

    SkASSERT(fIsBW);
    fAA.setRegion(fBW);
    fIsBW = false;

    // since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize"
    // ourselves back to BW.
    (void)this->updateCacheAndReturnNonEmpty(false);
}

#ifdef SK_DEBUG
void SkRasterClip::validate() const {
    // can't ever assert that fBW is empty, since we may have called forceGetBW
    if (fIsBW) {
        SkASSERT(fAA.isEmpty());
    }

    SkRegionPriv::Validate(fBW);
    fAA.validate();

    SkASSERT(this->computeIsEmpty() == fIsEmpty);
    SkASSERT(this->computeIsRect() == fIsRect);
}
#endif

///////////////////////////////////////////////////////////////////////////////

SkAAClipBlitterWrapper::SkAAClipBlitterWrapper() {
    SkDEBUGCODE(fClipRgn = nullptr;)
    SkDEBUGCODE(fBlitter = nullptr;)
}

SkAAClipBlitterWrapper::SkAAClipBlitterWrapper(const SkRasterClip& clip,
                                               SkBlitter* blitter) {
    this->init(clip, blitter);
}

SkAAClipBlitterWrapper::SkAAClipBlitterWrapper(const SkAAClip* aaclip,
                                               SkBlitter* blitter) {
    SkASSERT(blitter);
    SkASSERT(aaclip);
    fBWRgn.setRect(aaclip->getBounds());
    fAABlitter.init(blitter, aaclip);
    // now our return values
    fClipRgn = &fBWRgn;
    fBlitter = &fAABlitter;
}

void SkAAClipBlitterWrapper::init(const SkRasterClip& clip, SkBlitter* blitter) {
    SkASSERT(blitter);
    if (clip.isBW()) {
        fClipRgn = &clip.bwRgn();
        fBlitter = blitter;
    } else {
        const SkAAClip& aaclip = clip.aaRgn();
        fBWRgn.setRect(aaclip.getBounds());
        fAABlitter.init(blitter, &aaclip);
        // now our return values
        fClipRgn = &fBWRgn;
        fBlitter = &fAABlitter;
    }
}
