Image filters: fix crop rect application in SkXfermodeImageFilter.

The crop rect was being incorrectly applied in SkXfermodeImageFilter:
the background and foreground bounds were having the crop rect applied
individually to them, and then unioned. The correct approach is to take
the union of their bounds, and apply the crop rect to that. (A similar
bug in SkMergeImageFilter was fixed a while back.)

This is important when applying a compositing mode
which affects pixels outside the foreground bounds
(e.g., SrcIn, SrcOut).

NOTE: this will change the results of the xfermodeimagefilter GM (new
test case).
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1842033005

Review URL: https://codereview.chromium.org/1842033005
This commit is contained in:
senorblanco 2016-03-31 08:24:29 -07:00 committed by Commit bot
parent 2ae4b2e95d
commit 9db0427423
2 changed files with 19 additions and 15 deletions

View File

@ -183,6 +183,18 @@ protected:
x = 0;
y += fBitmap.height() + MARGIN;
}
// Test small fg, large bg with SrcIn with a crop that forces it to full size.
// This tests that SkXfermodeImageFilter correctly applies the compositing mode to
// the region outside the foreground.
mode = SkXfermode::Make(SkXfermode::kSrcIn_Mode);
SkImageFilter::CropRect cropRectFull(SkRect::MakeXYWH(0, 0, 80, 80));
paint.setImageFilter(SkXfermodeImageFilter::Make(mode, background, cropped, &cropRectFull));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
x = 0;
y += fBitmap.height() + MARGIN;
}
}
private:

View File

@ -64,21 +64,13 @@ bool SkXfermodeImageFilter::onFilterImageDeprecated(Proxy* proxy,
foreground.reset();
}
SkIRect bounds, foregroundBounds;
SkIRect foregroundSrcBounds = foreground.bounds();
foregroundSrcBounds.offset(foregroundOffset);
if (!applyCropRect(ctx, foregroundSrcBounds, &foregroundBounds)) {
foregroundBounds.setEmpty();
foreground.reset();
}
SkIRect backgroundSrcBounds = background.bounds();
backgroundSrcBounds.offset(backgroundOffset);
if (!applyCropRect(ctx, backgroundSrcBounds, &bounds)) {
bounds.setEmpty();
background.reset();
}
bounds.join(foregroundBounds);
if (bounds.isEmpty()) {
SkIRect foregroundBounds = foreground.bounds();
foregroundBounds.offset(foregroundOffset);
SkIRect srcBounds = background.bounds();
srcBounds.offset(backgroundOffset);
srcBounds.join(foregroundBounds);
SkIRect bounds;
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return false;
}