Adding an option to render only the shadow in SkDropShadowImageFilter

This is basically how blink uses the filter. Currently, I can't use it for "ShadowOnly" mode with the filter at all, but instead of copying the code and risking to have the codepaths diverge, I'm simply going to add the option here.

BUG=skia:

Review URL: https://codereview.chromium.org/646213004
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index bad7fc3..2255af9 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -46,6 +46,10 @@
 bleed
 drawbitmapmatrix
 
+# sugoi https://codereview.chromium.org/646213004/
+# New shadow only option in SkDropShadowImageFilter
+dropshadowimagefilter
+
 #bsalomon slight(?) changes after reseting GrContext between GMs
 dftext
 megalooper_0x0
diff --git a/gm/dropshadowimagefilter.cpp b/gm/dropshadowimagefilter.cpp
index a22ec43..5a8c7a2 100644
--- a/gm/dropshadowimagefilter.cpp
+++ b/gm/dropshadowimagefilter.cpp
@@ -102,7 +102,7 @@
         return SkString("dropshadowimagefilter");
     }
 
-    virtual SkISize onISize() { return SkISize::Make(400, 700); }
+    virtual SkISize onISize() { return SkISize::Make(400, 656); }
 
     void draw_frame(SkCanvas* canvas, const SkRect& r) {
         SkPaint paint;
@@ -134,12 +134,20 @@
 
         SkImageFilter* filters[] = {
             NULL,
-            SkDropShadowImageFilter::Create(7.0f, 0.0f, 0.0f, 3.0f, SK_ColorBLUE),
-            SkDropShadowImageFilter::Create(0.0f, 7.0f, 3.0f, 0.0f, SK_ColorBLUE),
-            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE),
-            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, cfif),
-            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, NULL, &cropRect),
-            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, NULL, &bogusRect),
+            SkDropShadowImageFilter::Create(7.0f, 0.0f, 0.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
+            SkDropShadowImageFilter::Create(0.0f, 7.0f, 3.0f, 0.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
+            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
+            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, cfif, NULL, 0),
+            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, NULL, &cropRect, 0),
+            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, NULL, &bogusRect, 0),
+            SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode),
         };
 
         SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
diff --git a/gm/imagefiltersbase.cpp b/gm/imagefiltersbase.cpp
index d1bd5a7..4546b8a 100644
--- a/gm/imagefiltersbase.cpp
+++ b/gm/imagefiltersbase.cpp
@@ -231,7 +231,8 @@
             FailImageFilter::Create(),
             SkColorFilterImageFilter::Create(cf),
             SkBlurImageFilter::Create(12.0f, 0.0f),
-            SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
+            SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
         };
         cf->unref();
 
diff --git a/gm/imagefiltersclipped.cpp b/gm/imagefiltersclipped.cpp
index e836e40..ae53a2e 100644
--- a/gm/imagefiltersclipped.cpp
+++ b/gm/imagefiltersclipped.cpp
@@ -101,8 +101,8 @@
         SkImageFilter* filters[] = {
             SkBlurImageFilter::Create(SkIntToScalar(12), SkIntToScalar(12)),
             SkDropShadowImageFilter::Create(SkIntToScalar(10), SkIntToScalar(10),
-                                            SkIntToScalar(3), SkIntToScalar(3),
-                                            SK_ColorGREEN),
+                SkIntToScalar(3), SkIntToScalar(3), SK_ColorGREEN,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
             SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkIntToScalar(12),
diff --git a/gm/imagefilterscropexpand.cpp b/gm/imagefilterscropexpand.cpp
index c9601b0..7db41e0 100644
--- a/gm/imagefilterscropexpand.cpp
+++ b/gm/imagefilterscropexpand.cpp
@@ -142,7 +142,8 @@
 
             draw(canvas, checkerboard, rect, SkDropShadowImageFilter::Create(
                 SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3), SkIntToScalar(3),
-                SK_ColorBLUE, noop_cropped.get(), &big_rect));
+                SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
+                noop_cropped.get(), &big_rect, 0));
 
             draw(canvas, checkerboard, rect, SkDisplacementMapEffect::Create(
                 SkDisplacementMapEffect::kR_ChannelSelectorType,
diff --git a/gm/imagefiltersscaled.cpp b/gm/imagefiltersscaled.cpp
index cf4dc4e..8b44bd0 100644
--- a/gm/imagefiltersscaled.cpp
+++ b/gm/imagefiltersscaled.cpp
@@ -110,8 +110,8 @@
         SkImageFilter* filters[] = {
             SkBlurImageFilter::Create(SkIntToScalar(4), SkIntToScalar(4)),
             SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10),
-                                            SkIntToScalar(3), SkIntToScalar(3),
-                                            SK_ColorYELLOW),
+                SkIntToScalar(3), SkIntToScalar(3), SK_ColorYELLOW,
+                SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
             SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkIntToScalar(12),
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index ddf4551..a83490d 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -243,13 +243,14 @@
     // V34: Add SkTextBlob serialization.
     // V35: Store SkRect (rather then width & height) in header
     // V36: Remove (obsolete) alphatype from SkColorTable
+    // V37: Added shadow only option to SkDropShadowImageFilter
 
     // Note: If the picture version needs to be increased then please follow the
     // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t MIN_PICTURE_VERSION = 19;
-    static const uint32_t CURRENT_PICTURE_VERSION = 36;
+    static const uint32_t CURRENT_PICTURE_VERSION = 37;
 
     mutable uint32_t      fUniqueID;
 
diff --git a/include/effects/SkDropShadowImageFilter.h b/include/effects/SkDropShadowImageFilter.h
index 0d6c24e..c6b936a 100644
--- a/include/effects/SkDropShadowImageFilter.h
+++ b/include/effects/SkDropShadowImageFilter.h
@@ -11,20 +11,46 @@
 
 class SK_API SkDropShadowImageFilter : public SkImageFilter {
 public:
+    enum ShadowMode {
+        kDrawShadowAndForeground_ShadowMode,
+        kDrawShadowOnly_ShadowMode
+    };
+
+    /** @deprecated use another Create function below instead */
     static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
                                            SkScalar sigmaX, SkScalar sigmaY, SkColor color,
                                            SkImageFilter* input = NULL,
                                            const CropRect* cropRect = NULL,
                                            uint32_t uniqueID = 0) {
-        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
-                                                    color, input, cropRect, uniqueID));
+        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
+                                                    kDrawShadowAndForeground_ShadowMode,
+                                                    input, cropRect, uniqueID));
     }
+
+    static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
+                                           SkScalar sigmaX, SkScalar sigmaY, SkColor color,
+                                           ShadowMode shadowMode,
+                                           SkImageFilter* input,
+                                           const CropRect* cropRect,
+                                           uint32_t uniqueID) {
+        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
+                                                    shadowMode, input, cropRect, uniqueID));
+    }
+
+    static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
+                                           SkScalar sigmaX, SkScalar sigmaY, SkColor color,
+                                           ShadowMode shadowMode) {
+        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
+                                                    shadowMode, NULL, NULL, 0));
+    }
+
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
 
 protected:
     SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
-                            SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
+                            ShadowMode shadowMode, SkImageFilter* input, const CropRect* cropRect,
+                            uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDropShadowImageFilter(SkReadBuffer&);
 #endif
@@ -36,5 +62,6 @@
 private:
     SkScalar fDx, fDy, fSigmaX, fSigmaY;
     SkColor fColor;
+    ShadowMode fShadowMode;
     typedef SkImageFilter INHERITED;
 };
diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp
index a996a4b..e073f80 100644
--- a/samplecode/SampleFilterFuzz.cpp
+++ b/samplecode/SampleFilterFuzz.cpp
@@ -122,6 +122,11 @@
     return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090;
 }
 
+static SkDropShadowImageFilter::ShadowMode make_shadow_mode() {
+    return (R(2) == 1) ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode :
+                         SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
+}
+
 static SkPoint3 make_point() {
     return SkPoint3(make_scalar(), make_scalar(), make_scalar(true));
 }
@@ -340,8 +345,9 @@
     }
         break;
     case DROP_SHADOW:
-        filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(),
-                     make_scalar(true), make_scalar(true), make_color(), make_image_filter());
+        filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(), make_scalar(true),
+                    make_scalar(true), make_color(), make_shadow_mode(), make_image_filter(),
+                    NULL, 0);
         break;
     case MORPHOLOGY:
         if (R(2) == 1) {
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index b073847..f87fb75 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -50,6 +50,7 @@
         kRemoveAndroidPaintOpts_Version    = 32,
         kFlattenCreateProc_Version         = 33,
         kRemoveColorTableAlpha_Version     = 36,
+        kDropShadowMode_Version            = 37,
     };
 
     /**
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 339e955..0ba8b23 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -17,14 +17,15 @@
 
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy,
                                                  SkScalar sigmaX, SkScalar sigmaY, SkColor color,
-                                                 SkImageFilter* input, const CropRect* cropRect,
-                                                 uint32_t uniqueID)
+                                                 ShadowMode shadowMode, SkImageFilter* input,
+                                                 const CropRect* cropRect, uint32_t uniqueID)
     : INHERITED(1, &input, cropRect, uniqueID)
     , fDx(dx)
     , fDy(dy)
     , fSigmaX(sigmaX)
     , fSigmaY(sigmaY)
     , fColor(color)
+    , fShadowMode(shadowMode)
 {
 }
 
@@ -36,6 +37,9 @@
     fSigmaX = buffer.readScalar();
     fSigmaY = buffer.readScalar();
     fColor = buffer.readColor();
+    fShadowMode = buffer.isVersionLT(SkReadBuffer::kDropShadowMode_Version) ?
+                  kDrawShadowAndForeground_ShadowMode :
+                  static_cast<ShadowMode>(buffer.readInt());
     buffer.validate(SkScalarIsFinite(fDx) &&
                     SkScalarIsFinite(fDy) &&
                     SkScalarIsFinite(fSigmaX) &&
@@ -50,7 +54,11 @@
     SkScalar sigmaX = buffer.readScalar();
     SkScalar sigmaY = buffer.readScalar();
     SkColor color = buffer.readColor();
-    return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect(), common.uniqueID());
+    ShadowMode shadowMode = buffer.isVersionLT(SkReadBuffer::kDropShadowMode_Version) ?
+                            kDrawShadowAndForeground_ShadowMode :
+                            static_cast<ShadowMode>(buffer.readInt());
+    return Create(dx, dy, sigmaX, sigmaY, color, shadowMode, common.getInput(0),
+                  &common.cropRect(), common.uniqueID());
 }
 
 void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
@@ -60,6 +68,7 @@
     buffer.writeScalar(fSigmaX);
     buffer.writeScalar(fSigmaY);
     buffer.writeColor(fColor);
+    buffer.writeInt(static_cast<int>(fShadowMode));
 }
 
 bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
@@ -98,7 +107,9 @@
     canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
                      SkIntToScalar(srcOffset.fY - bounds.fTop));
     canvas.drawBitmap(src, offsetVec.fX, offsetVec.fY, &paint);
-    canvas.drawBitmap(src, 0, 0);
+    if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
+        canvas.drawBitmap(src, 0, 0);
+    }
     *result = device->accessBitmap(false);
     offset->fX = bounds.fLeft;
     offset->fY = bounds.fTop;
@@ -116,7 +127,11 @@
     shadowBounds.offset(fDx, fDy);
     shadowBounds.outset(SkScalarMul(fSigmaX, SkIntToScalar(3)),
                         SkScalarMul(fSigmaY, SkIntToScalar(3)));
-    dst->join(shadowBounds);
+    if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
+        dst->join(shadowBounds);
+    } else {
+        *dst = shadowBounds;
+    }
 }
 
 bool SkDropShadowImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
@@ -130,7 +145,9 @@
     ctm.mapVectors(&sigma, 1);
     bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
                   SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
-    bounds.join(src);
+    if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
+        bounds.join(src);
+    }
     if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
         return false;
     }
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index d0fa93f..778230b 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -256,7 +256,9 @@
                                         SkDisplacementMapEffect::kB_ChannelSelectorType,
                                         40.0f, input.get(), input.get(), &cropRect),
         SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
-        SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, input.get(), &cropRect),
+        SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1,
+            SK_ColorGREEN, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
+            input.get(), &cropRect, 0),
         SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect),
         SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect),
         SkMatrixConvolutionImageFilter::Create(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect),
@@ -409,7 +411,8 @@
               20.0f, gradient_source.get()) },
         { "blur", SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1) },
         { "drop shadow", SkDropShadowImageFilter::Create(
-              SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN) },
+              SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN,
+              SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode) },
         { "diffuse lighting", SkLightingImageFilter::CreatePointLitDiffuse(
               location, SK_ColorGREEN, 0, 0) },
         { "specular lighting",
@@ -537,7 +540,8 @@
     return SkDropShadowImageFilter::Create(
         SkIntToScalar(100), SkIntToScalar(100),
         SkIntToScalar(10), SkIntToScalar(10),
-        SK_ColorBLUE, input);
+        SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
+        input, NULL, 0);
 }
 
 DEF_TEST(ImageFilterBlurThenShadowBounds, reporter) {
diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp
index 0dfd86a..43d4f60 100644
--- a/tests/RecordDrawTest.cpp
+++ b/tests/RecordDrawTest.cpp
@@ -234,7 +234,8 @@
     // We draw a rectangle with a long drop shadow.  We used to not update the clip
     // bounds based on SaveLayer paints, so the drop shadow could be cut off.
     SkPaint paint;
-    paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK))->unref();
+    paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK,
+                         SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode))->unref();
 
     recorder.saveLayer(NULL, &paint);
         recorder.clipRect(SkRect::MakeWH(20, 40));