Reland "Fix SkImageSource::filterBounds()" again

This relands commit cb4d587666
which was reverted by commit b6d2be1330
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>
This commit is contained in:
Xianzhu Wang 2017-09-25 10:26:40 -07:00 committed by Skia Commit-Bot
parent 477e9d432a
commit b449666fa2
3 changed files with 57 additions and 2 deletions

View File

@ -31,6 +31,8 @@ protected:
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
private:
explicit SkImageSource(sk_sp<SkImage>);
SkImageSource(sk_sp<SkImage>,

View File

@ -146,6 +146,17 @@ SkRect SkImageSource::computeFastBounds(const SkRect& src) const {
return fDstRect;
}
SkIRect SkImageSource::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
if (kReverse_MapDirection == direction) {
return SkImageFilter::onFilterNodeBounds(src, ctm, direction);
}
SkRect dstRect = fDstRect;
ctm.mapRect(&dstRect);
return dstRect.roundOut();
}
#ifndef SK_IGNORE_TO_STRING
void SkImageSource::toString(SkString* str) const {
str->appendf("SkImageSource: (");

View File

@ -1941,7 +1941,7 @@ DEF_TEST(ImageFilterColorSpaceDAG, reporter) {
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 @@ static void test_arithmetic_combinations(skiatest::Reporter* reporter, float v)
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));
}