aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkCanvas.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-05-17 11:17:39 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-17 17:06:24 +0000
commit120784394c160d009bc3aa88dd217c13c105a6ca (patch)
treec2f3406ff37360a511af362138938e754c057619 /src/core/SkCanvas.cpp
parentffb3d688b0e76ad7d1517657b00e4525cc603f40 (diff)
Fix srcBounds computation in SkMatrixConvolutionImageFilter
Note that this does change the behavior of the cropRect for the repeated case. The cropRect now only acts as a hard clip on the output. BUG= skia:7766 Change-Id: I1d66678bc797cd4835701cd20c36e68b22ac880a Reviewed-on: https://skia-review.googlesource.com/127338 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/core/SkCanvas.cpp')
-rw-r--r--src/core/SkCanvas.cpp47
1 files changed, 33 insertions, 14 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index a467cac060..00bbdf418e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -879,24 +879,42 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix()
- if (imageFilter) {
- clipBounds = imageFilter->filterBounds(clipBounds, ctm,
- SkImageFilter::kReverse_MapDirection);
- if (bounds && !imageFilter->canComputeFastBounds()) {
- bounds = nullptr;
- }
+ if (imageFilter && bounds && !imageFilter->canComputeFastBounds()) {
+ // If the image filter DAG affects transparent black then we will need to render
+ // out to the clip bounds
+ bounds = nullptr;
}
- SkIRect ir;
+
+ SkIRect inputSaveLayerBounds;
if (bounds) {
SkRect r;
ctm.mapRect(&r, *bounds);
- r.roundOut(&ir);
+ r.roundOut(&inputSaveLayerBounds);
} else { // no user bounds, so just use the clip
- ir = clipBounds;
+ inputSaveLayerBounds = clipBounds;
+ }
+
+ if (imageFilter) {
+ // expand the clip bounds by the image filter DAG to include extra content that might
+ // be required by the image filters.
+ clipBounds = imageFilter->filterBounds(clipBounds, ctm,
+ SkImageFilter::kReverse_MapDirection,
+ &inputSaveLayerBounds);
+ }
+
+ SkIRect clippedSaveLayerBounds;
+ if (bounds) {
+ // For better or for worse, user bounds currently act as a hard clip on the layer's
+ // extent (i.e., they implement the CSS filter-effects 'filter region' feature).
+ clippedSaveLayerBounds = inputSaveLayerBounds;
+ } else {
+ // If there are no user bounds, we don't want to artificially restrict the resulting
+ // layer bounds, so allow the expanded clip bounds free reign.
+ clippedSaveLayerBounds = clipBounds;
}
// early exit if the layer's bounds are clipped out
- if (!ir.intersect(clipBounds)) {
+ if (!clippedSaveLayerBounds.intersect(clipBounds)) {
if (BoundsAffectsClip(saveLayerFlags)) {
fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty
fMCRec->fRasterClip.setEmpty();
@@ -904,17 +922,18 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
}
return false;
}
- SkASSERT(!ir.isEmpty());
+ SkASSERT(!clippedSaveLayerBounds.isEmpty());
if (BoundsAffectsClip(saveLayerFlags)) {
// Simplify the current clips since they will be applied properly during restore()
- fMCRec->fRasterClip.setRect(ir);
- fDeviceClipBounds = qr_clip_bounds(ir);
+ fMCRec->fRasterClip.setRect(clippedSaveLayerBounds);
+ fDeviceClipBounds = qr_clip_bounds(clippedSaveLayerBounds);
}
if (intersection) {
- *intersection = ir;
+ *intersection = clippedSaveLayerBounds;
}
+
return true;
}