Enhance SkDropShadowImageFilter to support separate X & Y sigmas, and crop rect. This required a new flavour of the constructor.

This is driven by the feDropShadow filter effect in SVG, which unlike the shorthand version accepts separate X & Y sigmas.

Covered by new GM dropshadowimagefilter.

R=reed@google.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk/src@12401 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/effects/SkDropShadowImageFilter.cpp b/effects/SkDropShadowImageFilter.cpp
index b4d8689..5be633e 100644
--- a/effects/SkDropShadowImageFilter.cpp
+++ b/effects/SkDropShadowImageFilter.cpp
@@ -15,10 +15,21 @@
 #include "SkFlattenableBuffers.h"
 
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor color, SkImageFilter* input)
-    : SkImageFilter(input)
+    : INHERITED(input)
     , fDx(dx)
     , fDy(dy)
-    , fSigma(sigma)
+    , fSigmaX(sigma)
+    , fSigmaY(sigma)
+    , fColor(color)
+{
+}
+
+SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, SkImageFilter* input, const CropRect* cropRect)
+    : INHERITED(input, cropRect)
+    , fDx(dx)
+    , fDy(dy)
+    , fSigmaX(sigmaX)
+    , fSigmaY(sigmaY)
     , fColor(color)
 {
 }
@@ -27,11 +38,13 @@
  : INHERITED(1, buffer) {
     fDx = buffer.readScalar();
     fDy = buffer.readScalar();
-    fSigma = buffer.readScalar();
+    fSigmaX = buffer.readScalar();
+    fSigmaY = buffer.readScalar();
     fColor = buffer.readColor();
     buffer.validate(SkScalarIsFinite(fDx) &&
                     SkScalarIsFinite(fDy) &&
-                    SkScalarIsFinite(fSigma));
+                    SkScalarIsFinite(fSigmaX) &&
+                    SkScalarIsFinite(fSigmaY));
 }
 
 void SkDropShadowImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const
@@ -39,7 +52,8 @@
     this->INHERITED::flatten(buffer);
     buffer.writeScalar(fDx);
     buffer.writeScalar(fDy);
-    buffer.writeScalar(fSigma);
+    buffer.writeScalar(fSigmaX);
+    buffer.writeScalar(fSigmaY);
     buffer.writeColor(fColor);
 }
 
@@ -49,17 +63,26 @@
     if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, loc))
         return false;
 
-    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.height()));
+    SkIRect bounds;
+    src.getBounds(&bounds);
+    if (!this->applyCropRect(&bounds, matrix)) {
+        return false;
+    }
+
+    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
     SkCanvas canvas(device.get());
 
-    SkAutoTUnref<SkImageFilter> blurFilter(new SkBlurImageFilter(fSigma, fSigma));
+    SkAutoTUnref<SkImageFilter> blurFilter(new SkBlurImageFilter(fSigmaX, fSigmaY));
     SkAutoTUnref<SkColorFilter> colorFilter(SkColorFilter::CreateModeFilter(fColor, SkXfermode::kSrcIn_Mode));
     SkPaint paint;
     paint.setImageFilter(blurFilter.get());
     paint.setColorFilter(colorFilter.get());
     paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+    canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
     canvas.drawBitmap(src, fDx, fDy, &paint);
     canvas.drawBitmap(src, 0, 0);
     *result = device->accessBitmap(false);
+    loc->fX += bounds.fLeft;
+    loc->fY += bounds.fTop;
     return true;
 }