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
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 3ab5295..4674ff4 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -61,21 +61,22 @@
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 @@
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();