Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / effects / SkXfermodeImageFilter.cpp
index e8fa0d2..d43699d 100644 (file)
@@ -9,7 +9,8 @@
 #include "SkCanvas.h"
 #include "SkDevice.h"
 #include "SkColorPriv.h"
-#include "SkFlattenableBuffers.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
 #include "SkXfermode.h"
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
@@ -32,12 +33,12 @@ SkXfermodeImageFilter::~SkXfermodeImageFilter() {
     SkSafeUnref(fMode);
 }
 
-SkXfermodeImageFilter::SkXfermodeImageFilter(SkFlattenableReadBuffer& buffer)
-  : INHERITED(buffer) {
+SkXfermodeImageFilter::SkXfermodeImageFilter(SkReadBuffer& buffer)
+  : INHERITED(2, buffer) {
     fMode = buffer.readXfermode();
 }
 
-void SkXfermodeImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
+void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fMode);
 }
@@ -46,7 +47,7 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
                                             const SkBitmap& src,
                                             const SkMatrix& ctm,
                                             SkBitmap* dst,
-                                            SkIPoint* offset) {
+                                            SkIPoint* offset) const {
     SkBitmap background = src, foreground = src;
     SkImageFilter* backgroundInput = getInput(0);
     SkImageFilter* foregroundInput = getInput(1);
@@ -61,18 +62,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),
@@ -80,9 +85,12 @@ 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();
+    offset->fX = bounds.left();
+    offset->fY = bounds.top();
     return true;
 }
 
@@ -92,7 +100,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
                                            const SkBitmap& src,
                                            const SkMatrix& ctm,
                                            SkBitmap* result,
-                                           SkIPoint* offset) {
+                                           SkIPoint* offset) const {
     SkBitmap background;
     SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
     if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &background,
@@ -150,8 +158,8 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
         foregroundPaint.addColorTextureEffect(foregroundTex, foregroundMatrix);
         context->drawRect(foregroundPaint, srcRect);
     }
-    offset->fX += backgroundOffset.fX;
-    offset->fY += backgroundOffset.fY;
+    offset->fX = backgroundOffset.fX;
+    offset->fY = backgroundOffset.fY;
     return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result);
 }