From 203a993c77ea146e0a4e7f1e0c079cc79fd09167 Mon Sep 17 00:00:00 2001 From: jbroman Date: Mon, 11 Jul 2016 14:07:59 -0700 Subject: Handle negative scale in SkDropShadowImageFilter::onFilterNodeBounds. Add unit tests for positive and negative scale factors for the two effects that apply a Gaussian blur like this: blur and drop-shadow. The last two assertions fail without the fix in SkDropShadowImageFilter. BUG=chromium:600821 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2114313002 Review-Url: https://codereview.chromium.org/2114313002 --- src/effects/SkDropShadowImageFilter.cpp | 5 +-- tests/ImageFilterTest.cpp | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp index 31c45082b2..5befe71194 100644 --- a/src/effects/SkDropShadowImageFilter.cpp +++ b/src/effects/SkDropShadowImageFilter.cpp @@ -139,8 +139,9 @@ SkIRect SkDropShadowImageFilter::onFilterNodeBounds(const SkIRect& src, const Sk SkScalarCeilToInt(offsetVec.y())); SkVector sigma = SkVector::Make(fSigmaX, fSigmaY); ctm.mapVectors(&sigma, 1); - dst.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))), - SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3)))); + dst.outset( + SkScalarCeilToInt(SkScalarAbs(SkScalarMul(sigma.x(), SkIntToScalar(3)))), + SkScalarCeilToInt(SkScalarAbs(SkScalarMul(sigma.y(), SkIntToScalar(3))))); if (fShadowMode == kDrawShadowAndForeground_ShadowMode) { dst.join(src); } diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp index dd0824551b..f46519d94e 100644 --- a/tests/ImageFilterTest.cpp +++ b/tests/ImageFilterTest.cpp @@ -856,6 +856,64 @@ DEF_TEST(ImageFilterDilateThenBlurBounds, reporter) { REPORTER_ASSERT(reporter, bounds == expectedBounds); } +DEF_TEST(ImageFilterScaledBlurRadius, reporter) { + // Each blur should spread 3*sigma, so 3 for the blur and 30 for the shadow + // (before the CTM). Bounds should be computed correctly in the presence of + // a (possibly negative) scale. + sk_sp blur(make_blur(nullptr)); + sk_sp dropShadow(make_drop_shadow(nullptr)); + { + // Uniform scale by 2. + SkMatrix scaleMatrix; + scaleMatrix.setScale(2, 2); + SkIRect bounds = SkIRect::MakeLTRB(0, 0, 200, 200); + + SkIRect expectedBlurBounds = SkIRect::MakeLTRB(-6, -6, 206, 206); + SkIRect blurBounds = blur->filterBounds( + bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); + REPORTER_ASSERT(reporter, blurBounds == expectedBlurBounds); + SkIRect reverseBlurBounds = blur->filterBounds( + bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); + REPORTER_ASSERT(reporter, reverseBlurBounds == expectedBlurBounds); + + SkIRect expectedShadowBounds = SkIRect::MakeLTRB(0, 0, 460, 460); + SkIRect shadowBounds = dropShadow->filterBounds( + bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); + REPORTER_ASSERT(reporter, shadowBounds == expectedShadowBounds); + SkIRect expectedReverseShadowBounds = + SkIRect::MakeLTRB(-260, -260, 200, 200); + SkIRect reverseShadowBounds = dropShadow->filterBounds( + bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); + REPORTER_ASSERT(reporter, + reverseShadowBounds == expectedReverseShadowBounds); + } + { + // Vertical flip. + SkMatrix scaleMatrix; + scaleMatrix.setScale(1, -1); + SkIRect bounds = SkIRect::MakeLTRB(0, -100, 100, 0); + + SkIRect expectedBlurBounds = SkIRect::MakeLTRB(-3, -103, 103, 3); + SkIRect blurBounds = blur->filterBounds( + bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); + REPORTER_ASSERT(reporter, blurBounds == expectedBlurBounds); + SkIRect reverseBlurBounds = blur->filterBounds( + bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); + REPORTER_ASSERT(reporter, reverseBlurBounds == expectedBlurBounds); + + SkIRect expectedShadowBounds = SkIRect::MakeLTRB(0, -230, 230, 0); + SkIRect shadowBounds = dropShadow->filterBounds( + bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); + REPORTER_ASSERT(reporter, shadowBounds == expectedShadowBounds); + SkIRect expectedReverseShadowBounds = + SkIRect::MakeLTRB(-130, -100, 100, 130); + SkIRect reverseShadowBounds = dropShadow->filterBounds( + bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); + REPORTER_ASSERT(reporter, + reverseShadowBounds == expectedReverseShadowBounds); + } +} + DEF_TEST(ImageFilterComposedBlurFastBounds, reporter) { sk_sp filter1(make_blur(nullptr)); sk_sp filter2(make_blur(nullptr)); -- cgit v1.2.3