Fix for SkDisplacementMap::onFilterBounds().
Two problems: we were not applying the CTM to the scale parameter when
modifying clip bounds, and the recursion for onFilterBounds() must be done
in the reverse order.
BUG=370914
R=junov@chromium.org
Review URL: https://codereview.chromium.org/272643003
git-svn-id: http://skia.googlecode.com/svn/trunk@14627 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 3922244..d0f134b 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -257,11 +257,13 @@
bool SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) const {
SkIRect bounds = src;
- if (getColorInput() && !getColorInput()->filterBounds(src, ctm, &bounds)) {
- return false;
+ SkVector scale = SkVector::Make(fScale, fScale);
+ ctm.mapVectors(&scale, 1);
+ bounds.outset(SkScalarCeilToInt(scale.fX * SK_ScalarHalf),
+ SkScalarCeilToInt(scale.fY * SK_ScalarHalf));
+ if (getColorInput()) {
+ return getColorInput()->filterBounds(bounds, ctm, dst);
}
- bounds.outset(SkScalarCeilToInt(fScale * SK_ScalarHalf),
- SkScalarCeilToInt(fScale * SK_ScalarHalf));
*dst = bounds;
return true;
}
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index f8492a7..91b2c09 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -309,7 +309,7 @@
{ "displacement map", SkDisplacementMapEffect::Create(
SkDisplacementMapEffect::kR_ChannelSelectorType,
SkDisplacementMapEffect::kB_ChannelSelectorType,
- 40.0f, gradient_source.get()) },
+ 20.0f, gradient_source.get()) },
{ "blur", SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1) },
{ "drop shadow", SkDropShadowImageFilter::Create(
SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN) },
@@ -335,34 +335,40 @@
tiledResult.allocN32Pixels(width, height);
SkCanvas tiledCanvas(tiledResult);
SkCanvas untiledCanvas(untiledResult);
- tiledCanvas.clear(0);
- untiledCanvas.clear(0);
- int tileSize = 16;
+ int tileSize = 8;
- for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
- SkPaint paint;
- paint.setImageFilter(filters[i].fFilter);
- paint.setTextSize(SkIntToScalar(height));
- paint.setColor(SK_ColorWHITE);
- SkString str;
- const char* text = "ABC";
- SkScalar ypos = SkIntToScalar(height);
- untiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
- for (int y = 0; y < height; y += tileSize) {
- for (int x = 0; x < width; x += tileSize) {
- tiledCanvas.save();
- tiledCanvas.clipRect(SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize)));
- tiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
- tiledCanvas.restore();
+ for (int scale = 1; scale <= 2; ++scale) {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
+ tiledCanvas.clear(0);
+ untiledCanvas.clear(0);
+ SkPaint paint;
+ paint.setImageFilter(filters[i].fFilter);
+ paint.setTextSize(SkIntToScalar(height));
+ paint.setColor(SK_ColorWHITE);
+ SkString str;
+ const char* text = "ABC";
+ SkScalar ypos = SkIntToScalar(height);
+ untiledCanvas.save();
+ untiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale));
+ untiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
+ untiledCanvas.restore();
+ for (int y = 0; y < height; y += tileSize) {
+ for (int x = 0; x < width; x += tileSize) {
+ tiledCanvas.save();
+ tiledCanvas.clipRect(SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize)));
+ tiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale));
+ tiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
+ tiledCanvas.restore();
+ }
}
- }
- untiledCanvas.flush();
- tiledCanvas.flush();
- for (int y = 0; y < height; y++) {
- int diffs = memcmp(untiledResult.getAddr32(0, y), tiledResult.getAddr32(0, y), untiledResult.rowBytes());
- REPORTER_ASSERT_MESSAGE(reporter, !diffs, filters[i].fName);
- if (diffs) {
- break;
+ untiledCanvas.flush();
+ tiledCanvas.flush();
+ for (int y = 0; y < height; y++) {
+ int diffs = memcmp(untiledResult.getAddr32(0, y), tiledResult.getAddr32(0, y), untiledResult.rowBytes());
+ REPORTER_ASSERT_MESSAGE(reporter, !diffs, filters[i].fName);
+ if (diffs) {
+ break;
+ }
}
}
}