Bounds fixes for SkXfermodeImageFilter:

1) Change the default bounds to the union of the foreground and background bounds.
2) Use a canvas translate instead of manually offsetting the foreground and background bounds by the union.
3) Apply the transfer mode to all pixels, including those outside the foreground rect by using a difference clip.

Covered by the offset test cases in the xfermodeimagefilter GM (will need rebaselines).

R=reed@google.com

Review URL: https://codereview.chromium.org/112683004

git-svn-id: http://skia.googlecode.com/svn/trunk@12652 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
senorblanco@chromium.org 2013-12-12 21:00:58 +00:00
parent 30289512f9
commit 0682019f21
2 changed files with 11 additions and 5 deletions

View File

@ -75,3 +75,5 @@ clipped-bitmap-shaders-clamp-hq_angle
clipped-bitmap-shaders-mirror-hq_angle
clipped-bitmap-shaders-tile-hq_angle
# Added by senorblanco to accomodate bounds fixes for SkXfermodeImageFilter in https://codereview.chromium.org/112683004.
xfermodeimagefilter

View File

@ -61,21 +61,22 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
return false;
}
SkIRect bounds;
SkIRect bounds, foregroundBounds;
background.getBounds(&bounds);
bounds.offset(backgroundOffset);
foreground.getBounds(&foregroundBounds);
foregroundBounds.offset(foregroundOffset);
bounds.join(foregroundBounds);
if (!applyCropRect(&bounds, ctm)) {
return false;
}
backgroundOffset.fX -= bounds.left();
backgroundOffset.fY -= bounds.top();
foregroundOffset.fX -= bounds.left();
foregroundOffset.fY -= bounds.top();
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (NULL == device.get()) {
return false;
}
SkCanvas canvas(device);
canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX),
@ -83,6 +84,9 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
paint.setXfermode(fMode);
canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX),
SkIntToScalar(foregroundOffset.fY), &paint);
canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op);
paint.setColor(SK_ColorTRANSPARENT);
canvas.drawPaint(paint);
*dst = device->accessBitmap(false);
offset->fX += bounds.left();
offset->fY += bounds.top();