From 0682019f2161af00168bb1984918753f2a1c1e54 Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Thu, 12 Dec 2013 21:00:58 +0000 Subject: [PATCH] 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 --- expectations/gm/ignored-tests.txt | 2 ++ src/effects/SkXfermodeImageFilter.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt index f3edab2ecb..ac67f631e4 100644 --- a/expectations/gm/ignored-tests.txt +++ b/expectations/gm/ignored-tests.txt @@ -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 diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index 3ab52950be..4674ff44ab 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -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 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();