diff options
author | Robert Phillips <robertphillips@google.com> | 2018-04-20 10:27:27 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-20 15:13:55 +0000 |
commit | 3d0e8507face451a4b17698beb6ad0ea51b9ef1d (patch) | |
tree | 876f06c75dbcdd21fd61d37bc62b614170025ed1 | |
parent | 1eece783181701bf07431180eca13c689fd13aee (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.cpp | 7 | ||||
-rw-r--r-- | tests/CanvasTest.cpp | 26 |
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); +} + |