Reland "Fix SkImageSource::filterBounds()" again

This relands commit cb4d58766668b003fea67798027fc25d84acd059
which was reverted by commit b6d2be1330f16fe05f1eed5abda927c0fbb50055
because the original CL broke some blink layout tests, and the first
reland was reverted by commit because it broke filterfastbounds gm.

This reland let SkImageSource::onFilterNodeBounds() return the dst rect
with ctm applied when mapping forward or otherwise the default value.

Original description:

> Previously SkImageSource::filterBounds() uses the default
> SkImageFilter::onFilterNodeBounds() which returns the input rect.
>
> Now override onFilterNodeBounds() in SkImageSource to return src
> or dst rect (with transform applied).

Change-Id: I4548981142b9a96beda8339d394cf9943c9f4c0f
Reviewed-on: https://skia-review.googlesource.com/50420
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 05c0bff..db269f0 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -1941,7 +1941,7 @@
     REPORTER_ASSERT(reporter, filter->cloneCount() == 1u);
 }
 
-// Test XfermodeimageFilter::onFilterBounds with different blending modes.
+// Test SkXfermodeImageFilter::filterBounds with different blending modes.
 DEF_TEST(XfermodeImageFilterBounds, reporter) {
     SkIRect background_rect = SkIRect::MakeXYWH(0, 0, 100, 100);
     SkIRect foreground_rect = SkIRect::MakeXYWH(50, 50, 100, 100);
@@ -2049,8 +2049,50 @@
     test_arithmetic_bounds(reporter, v, v, v, v, background, foreground, &crop, crop_rect);
 }
 
-// Test ArithmeticImageFilter::onFilterBounds with different blending modes.
+// Test SkArithmeticImageFilter::filterBounds with different blending modes.
 DEF_TEST(ArithmeticImageFilterBounds, reporter) {
     test_arithmetic_combinations(reporter, 1);
     test_arithmetic_combinations(reporter, 0.5);
 }
+
+// Test SkImageSource::filterBounds.
+DEF_TEST(ImageSourceBounds, reporter) {
+    sk_sp<SkImage> image(SkImage::MakeFromBitmap(make_gradient_circle(64, 64)));
+    // Default src and dst rects.
+    sk_sp<SkImageFilter> source1(SkImageSource::Make(image));
+    SkIRect imageBounds = SkIRect::MakeWH(64, 64);
+    SkIRect input(SkIRect::MakeXYWH(10, 20, 30, 40));
+    REPORTER_ASSERT(reporter,
+                    imageBounds == source1->filterBounds(input, SkMatrix::I(),
+                                                         SkImageFilter::kForward_MapDirection));
+    REPORTER_ASSERT(reporter,
+                    input == source1->filterBounds(input, SkMatrix::I(),
+                                                   SkImageFilter::kReverse_MapDirection));
+    SkMatrix scale(SkMatrix::MakeScale(2));
+    SkIRect scaledBounds = SkIRect::MakeWH(128, 128);
+    REPORTER_ASSERT(reporter,
+                    scaledBounds == source1->filterBounds(input, scale,
+                                                          SkImageFilter::kForward_MapDirection));
+    REPORTER_ASSERT(
+            reporter,
+            input == source1->filterBounds(input, scale, SkImageFilter::kReverse_MapDirection));
+
+    // Specified src and dst rects.
+    SkRect src(SkRect::MakeXYWH(0.5, 0.5, 100.5, 100.5));
+    SkRect dst(SkRect::MakeXYWH(-10.5, -10.5, 120.5, 120.5));
+    sk_sp<SkImageFilter> source2(SkImageSource::Make(image, src, dst, kMedium_SkFilterQuality));
+    REPORTER_ASSERT(reporter,
+                    dst.roundOut() == source2->filterBounds(input, SkMatrix::I(),
+                                                            SkImageFilter::kForward_MapDirection));
+    REPORTER_ASSERT(reporter,
+                    input == source2->filterBounds(input, SkMatrix::I(),
+                                                   SkImageFilter::kReverse_MapDirection));
+    scale.mapRect(&dst);
+    scale.mapRect(&src);
+    REPORTER_ASSERT(reporter,
+                    dst.roundOut() == source2->filterBounds(input, scale,
+                                                            SkImageFilter::kForward_MapDirection));
+    REPORTER_ASSERT(
+            reporter,
+            input == source2->filterBounds(input, scale, SkImageFilter::kReverse_MapDirection));
+}