void SkRasterClip::translate(int dx, int dy, SkRasterClip* dst) const { if (NULL == 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(); } }
bool SkRasterClip::setRect(const SkIRect& rect) { AUTO_RASTERCLIP_VALIDATE(*this); fIsBW = true; fAA.setEmpty(); return fBW.setRect(rect); }
void SkRasterClip::convertToAA() { AUTO_RASTERCLIP_VALIDATE(*this); SkASSERT(fIsBW); fAA.setRegion(fBW); fIsBW = false; }
bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& bounds, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (fForceConservativeRects) { SkIRect ir; switch (mutate_conservative_op(&op, path.isInverseFillType())) { case kDoNothing_MutateResult: return !this->isEmpty(); case kReplaceClippedAgainstGlobalBounds_MutateResult: ir = bounds; break; case kContinue_MutateResult: { SkRect bounds = path.getBounds(); matrix.mapRect(&bounds); ir = bounds.roundOut(); break; } } return this->op(ir, op); } // base is used to limit the size (and therefore memory allocation) of the // region that results from scan converting devPath. SkRegion base; SkPath devPath; if (matrix.isIdentity()) { devPath = path; } else { path.transform(matrix, &devPath); devPath.setIsVolatile(true); } if (SkRegion::kIntersect_Op == op) { // since we are intersect, we can do better (tighter) with currRgn's // bounds, than just using the device. However, if currRgn is complex, // our region blitter may hork, so we do that case in two steps. if (this->isRect()) { // FIXME: we should also be able to do this when this->isBW(), // but relaxing the test above triggers GM asserts in // SkRgnBuilder::blitH(). We need to investigate what's going on. return this->setPath(devPath, this->bwRgn(), doAA); } else { base.setRect(this->getBounds()); SkRasterClip clip(fForceConservativeRects); clip.setPath(devPath, base, doAA); return this->op(clip, op); } } else { base.setRect(bounds); if (SkRegion::kReplace_Op == op) { return this->setPath(devPath, base, doAA); } else { SkRasterClip clip(fForceConservativeRects); clip.setPath(devPath, base, doAA); return this->op(clip, op); } } }
const SkRegion& SkRasterClip::forceGetBW() { AUTO_RASTERCLIP_VALIDATE(*this); if (!fIsBW) { fBW.setRect(fAA.getBounds()); } return fBW; }
bool SkRasterClip::setEmpty() { AUTO_RASTERCLIP_VALIDATE(*this); fIsBW = true; fBW.setEmpty(); fAA.setEmpty(); return false; }
SkRasterClip::SkRasterClip(const SkRasterClip& src) { AUTO_RASTERCLIP_VALIDATE(src); fIsBW = src.fIsBW; if (fIsBW) { fBW = src.fBW; } else { fAA = src.fAA; } }
bool SkRasterClip::op(const SkRegion& rgn, SkRegion::Op op) { AUTO_RASTERCLIP_VALIDATE(*this); if (fIsBW) { return fBW.op(rgn, op); } else { SkAAClip tmp; tmp.setRegion(rgn); return fAA.op(tmp, op); } }
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); }
bool SkRasterClip::op(const SkRegion& rgn, SkRegion::Op op) { AUTO_RASTERCLIP_VALIDATE(*this); if (fIsBW) { (void)fBW.op(rgn, op); } else { SkAAClip tmp; tmp.setRegion(rgn); (void)fAA.op(tmp, op); } return this->updateCacheAndReturnNonEmpty(); }
bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkIRect& bounds, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); SkRect devRect; if (fForceConservativeRects) { SkIRect ir; switch (mutate_conservative_op(&op, false)) { case kDoNothing_MutateResult: return !this->isEmpty(); case kReplaceClippedAgainstGlobalBounds_MutateResult: ir = bounds; break; case kContinue_MutateResult: matrix.mapRect(&devRect, localRect); ir = devRect.roundOut(); break; } return this->op(ir, op); } const bool isScaleTrans = matrix.isScaleTranslate(); if (!isScaleTrans) { SkPath path; path.addRect(localRect); path.setIsVolatile(true); return this->op(path, matrix, bounds, op, doAA); } matrix.mapRect(&devRect, 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) { SkIRect ir; devRect.round(&ir); (void)fBW.op(ir, op); } else { if (fIsBW) { this->convertToAA(); } (void)fAA.op(devRect, op, doAA); } return this->updateCacheAndReturnNonEmpty(); }
SkRasterClip::SkRasterClip(const SkRasterClip& src) { AUTO_RASTERCLIP_VALIDATE(src); fIsBW = src.fIsBW; if (fIsBW) { fBW = src.fBW; } else { fAA = src.fAA; } fIsEmpty = src.isEmpty(); fIsRect = src.isRect(); SkDEBUGCODE(this->validate();) }
bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (this->isBW() && !doAA) { return fBW.setPath(path, clip); } else { // TODO: since we are going to over-write fAA completely (aren't we?) // we should just clear our BW data (if any) and set fIsAA=true if (this->isBW()) { this->convertToAA(); } return fAA.setPath(path, &clip, doAA); } }
bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& devBounds, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); SkIRect bounds(devBounds); this->applyClipRestriction(op, &bounds); // base is used to limit the size (and therefore memory allocation) of the // region that results from scan converting devPath. SkRegion base; SkPath devPath; if (matrix.isIdentity()) { devPath = path; } else { path.transform(matrix, &devPath); devPath.setIsVolatile(true); } if (SkRegion::kIntersect_Op == op) { // since we are intersect, we can do better (tighter) with currRgn's // bounds, than just using the device. However, if currRgn is complex, // our region blitter may hork, so we do that case in two steps. if (this->isRect()) { // FIXME: we should also be able to do this when this->isBW(), // but relaxing the test above triggers GM asserts in // SkRgnBuilder::blitH(). We need to investigate what's going on. return this->setPath(devPath, this->bwRgn(), doAA); } else { base.setRect(this->getBounds()); SkRasterClip clip; clip.setPath(devPath, base, doAA); return this->op(clip, op); } } else { base.setRect(bounds); if (SkRegion::kReplace_Op == op) { return this->setPath(devPath, base, doAA); } else { SkRasterClip clip; clip.setPath(devPath, base, doAA); return this->op(clip, op); } } }
bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (fForceConservativeRects) { return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType()); } if (this->isBW() && !doAA) { (void)fBW.setPath(path, clip); } else { // TODO: since we are going to over-write fAA completely (aren't we?) // we should just clear our BW data (if any) and set fIsAA=true if (this->isBW()) { this->convertToAA(); } (void)fAA.setPath(path, &clip, doAA); } return this->updateCacheAndReturnNonEmpty(); }
bool SkRasterClip::op(const SkRect& r, const SkISize& size, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (fForceConservativeRects) { SkIRect ir; switch (mutate_conservative_op(&op, false)) { case kDoNothing_MutateResult: return !this->isEmpty(); case kReplaceClippedAgainstGlobalBounds_MutateResult: ir = SkIRect::MakeSize(size); break; case kContinue_MutateResult: ir = r.roundOut(); break; } return this->op(ir, op); } 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(r.fLeft) && nearly_integral(r.fTop) && nearly_integral(r.fRight) && nearly_integral(r.fBottom)) { doAA = false; } } if (fIsBW && !doAA) { SkIRect ir; r.round(&ir); (void)fBW.op(ir, op); } else { if (fIsBW) { this->convertToAA(); } (void)fAA.op(r, op, doAA); } return this->updateCacheAndReturnNonEmpty(); }
bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (doAA) { // check that the rect really needs aa if (is_integral(r.fLeft) && is_integral(r.fTop) && is_integral(r.fRight) && is_integral(r.fBottom)) { doAA = false; } } if (fIsBW && !doAA) { SkIRect ir; r.round(&ir); return fBW.op(ir, op); } else { if (fIsBW) { this->convertToAA(); } return fAA.op(r, op, doAA); } }
bool SkRasterClip::op(const SkRasterClip& clip, SkRegion::Op op) { AUTO_RASTERCLIP_VALIDATE(*this); clip.validate(); if (this->isBW() && clip.isBW()) { return fBW.op(clip.fBW, 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(); } return fAA.op(*other, op); } }
bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkIRect& devBounds, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); SkRect devRect; const bool isScaleTrans = matrix.isScaleTranslate(); if (!isScaleTrans) { SkPath path; path.addRect(localRect); path.setIsVolatile(true); return this->op(path, matrix, devBounds, op, doAA); } matrix.mapRect(&devRect, 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) { SkIRect ir; devRect.round(&ir); this->applyClipRestriction(op, &ir); (void)fBW.op(ir, op); } else { if (fIsBW) { this->convertToAA(); } this->applyClipRestriction(op, &devRect); (void)fAA.op(devRect, op, doAA); } return this->updateCacheAndReturnNonEmpty(); }
bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); 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(r.fLeft) && nearly_integral(r.fTop) && nearly_integral(r.fRight) && nearly_integral(r.fBottom)) { doAA = false; } } if (fIsBW && !doAA) { SkIRect ir; r.round(&ir); (void)fBW.op(ir, op); } else { if (fIsBW) { this->convertToAA(); } (void)fAA.op(r, op, doAA); } return this->updateCacheAndReturnNonEmpty(); }
bool SkRasterClip::op(const SkIRect& rect, SkRegion::Op op) { AUTO_RASTERCLIP_VALIDATE(*this); return fIsBW ? fBW.op(rect, op) : fAA.op(rect, op); }
SkRasterClip::~SkRasterClip() { AUTO_RASTERCLIP_VALIDATE(*this); }
bool SkRasterClip::op(const SkIRect& rect, SkRegion::Op op) { AUTO_RASTERCLIP_VALIDATE(*this); fIsBW ? fBW.op(rect, op) : fAA.op(rect, op); return this->updateCacheAndReturnNonEmpty(); }