aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkRasterClip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkRasterClip.cpp')
-rw-r--r--src/core/SkRasterClip.cpp56
1 files changed, 40 insertions, 16 deletions
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index 88bfbafc36..1090c66f34 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -185,18 +185,20 @@ bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA)
return this->updateCacheAndReturnNonEmpty();
}
-bool SkRasterClip::op(const SkRRect& rrect, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRect& bounds,
+ SkRegion::Op op, bool doAA) {
if (fForceConservativeRects) {
- return this->op(rrect.getBounds(), bounds, op, doAA);
+ return this->op(rrect.getBounds(), matrix, bounds, op, doAA);
}
SkPath path;
path.addRRect(rrect);
- return this->op(path, bounds, op, doAA);
+ return this->op(path, matrix, bounds, op, doAA);
}
-bool SkRasterClip::op(const SkPath& path, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& bounds,
+ SkRegion::Op op, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
if (fForceConservativeRects) {
@@ -207,9 +209,12 @@ bool SkRasterClip::op(const SkPath& path, const SkIRect& bounds, SkRegion::Op op
case kReplaceClippedAgainstGlobalBounds_MutateResult:
ir = bounds;
break;
- case kContinue_MutateResult:
- ir = path.getBounds().roundOut();
+ case kContinue_MutateResult: {
+ SkRect bounds = path.getBounds();
+ matrix.mapRect(&bounds);
+ ir = bounds.roundOut();
break;
+ }
}
return this->op(ir, op);
}
@@ -218,6 +223,13 @@ bool SkRasterClip::op(const SkPath& path, const SkIRect& bounds, SkRegion::Op op
// 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,
@@ -226,21 +238,21 @@ bool SkRasterClip::op(const SkPath& path, const SkIRect& bounds, SkRegion::Op op
// 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(path, this->bwRgn(), doAA);
+ return this->setPath(devPath, this->bwRgn(), doAA);
} else {
base.setRect(this->getBounds());
SkRasterClip clip(fForceConservativeRects);
- clip.setPath(path, base, doAA);
+ clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
} else {
base.setRect(bounds);
if (SkRegion::kReplace_Op == op) {
- return this->setPath(path, base, doAA);
+ return this->setPath(devPath, base, doAA);
} else {
SkRasterClip clip(fForceConservativeRects);
- clip.setPath(path, base, doAA);
+ clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
}
@@ -309,8 +321,10 @@ static bool nearly_integral(SkScalar x) {
return x - SkScalarFloorToScalar(x) < domain;
}
-bool SkRasterClip::op(const SkRect& r, const SkIRect& bounds, SkRegion::Op op, bool doAA) {
+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;
@@ -321,30 +335,40 @@ bool SkRasterClip::op(const SkRect& r, const SkIRect& bounds, SkRegion::Op op, b
ir = bounds;
break;
case kContinue_MutateResult:
- ir = r.roundOut();
+ 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(r.fLeft) && nearly_integral(r.fTop) &&
- nearly_integral(r.fRight) && nearly_integral(r.fBottom)) {
+ if (nearly_integral(devRect.fLeft) && nearly_integral(devRect.fTop) &&
+ nearly_integral(devRect.fRight) && nearly_integral(devRect.fBottom)) {
doAA = false;
}
}
if (fIsBW && !doAA) {
SkIRect ir;
- r.round(&ir);
+ devRect.round(&ir);
(void)fBW.op(ir, op);
} else {
if (fIsBW) {
this->convertToAA();
}
- (void)fAA.op(r, op, doAA);
+ (void)fAA.op(devRect, op, doAA);
}
return this->updateCacheAndReturnNonEmpty();
}