aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-04-20 10:27:27 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-20 15:13:55 +0000
commit3d0e8507face451a4b17698beb6ad0ea51b9ef1d (patch)
tree876f06c75dbcdd21fd61d37bc62b614170025ed1
parent1eece783181701bf07431180eca13c689fd13aee (diff)
Prevent matrix stack from being corrupted if a rotated image filter is clipped out
Bug: skia:7765 Change-Id: Id76b63cebc25dcdff02d4ba3f6d6bba6f2b6b842 Reviewed-on: https://skia-review.googlesource.com/122782 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r--src/core/SkCanvas.cpp7
-rw-r--r--tests/CanvasTest.cpp26
2 files changed, 33 insertions, 0 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 635f453bf7..7398f2819d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -984,6 +984,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
SkLazyPaint lazyP;
SkImageFilter* imageFilter = paint ? paint->getImageFilter() : nullptr;
SkMatrix stashedMatrix = fMCRec->fMatrix;
+ MCRec* modifiedRec = nullptr;
SkMatrix remainder;
SkSize scale;
/*
@@ -1006,6 +1007,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
stashedMatrix.decomposeScale(&scale, &remainder))
{
// We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix
+ modifiedRec = fMCRec;
this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height()));
SkPaint* p = lazyP.set(*paint);
p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder,
@@ -1021,6 +1023,11 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
SkIRect ir;
if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
+ if (modifiedRec) {
+ // In this case there will be no layer in which to stash the matrix so we need to
+ // revert the prior MCRec to its earlier state.
+ modifiedRec->fMatrix = stashedMatrix;
+ }
return;
}
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index 95030a3e42..d61d195982 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -898,3 +898,29 @@ DEF_TEST(Canvas_degenerate_dimension, reporter) {
}
}
+#include "SkBlurImageFilter.h"
+
+DEF_TEST(Canvas_ClippedOutImageFilter, reporter) {
+ SkCanvas canvas(100, 100);
+
+ SkPaint p;
+ p.setColor(SK_ColorGREEN);
+ p.setImageFilter(SkBlurImageFilter::Make(3.0f, 3.0f, nullptr, nullptr));
+
+ SkRect blurredRect = SkRect::MakeXYWH(60, 10, 30, 30);
+
+ SkMatrix invM;
+ invM.setRotate(-45);
+ invM.mapRect(&blurredRect);
+
+ const SkRect clipRect = SkRect::MakeXYWH(0, 50, 50, 50);
+
+ canvas.clipRect(clipRect);
+
+ canvas.rotate(45);
+ const SkMatrix preCTM = canvas.getTotalMatrix();
+ canvas.drawRect(blurredRect, p);
+ const SkMatrix postCTM = canvas.getTotalMatrix();
+ REPORTER_ASSERT(reporter, preCTM == postCTM);
+}
+