Add geometric version of spot shadow

BUG=skia:6119

Change-Id: Ib9770bd88f4eebd68f2d893c5788f966d89f193c
Reviewed-on: https://skia-review.googlesource.com/7585
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/effects/GrShadowTessellator.h b/src/gpu/effects/GrShadowTessellator.h
index 6d42f49..c2acde7 100755
--- a/src/gpu/effects/GrShadowTessellator.h
+++ b/src/gpu/effects/GrShadowTessellator.h
@@ -16,6 +16,8 @@
 class SkMatrix;
 class SkPath;
 
+// TODO: derive these two classes from a base class containing common elements
+
 /**
  * This class generates an ambient shadow for a path by walking the path, outsetting by the
  * radius, and setting inner and outer colors to umbraColor and penumbraColor, respectively.
@@ -23,8 +25,8 @@
  */
 class GrAmbientShadowTessellator {
 public:
-    GrAmbientShadowTessellator(const SkMatrix& viewMatrix, const SkPath& path, SkScalar radius,
-                               GrColor umbraColor, GrColor penumbraColor, bool transparent);
+    GrAmbientShadowTessellator(const SkPath& path, SkScalar radius, GrColor umbraColor,
+                               GrColor penumbraColor, bool transparent);
 
     int      vertexCount() { return fPositions.count(); }
     SkPoint* positions() { return fPositions.begin(); }
@@ -34,14 +36,12 @@
 
 private:
     void handleLine(const SkPoint& p);
-    void handleLine(const SkMatrix& m, SkPoint p);
 
     void handleQuad(const SkPoint pts[3]);
-    void handleQuad(const SkMatrix& m, SkPoint pts[3]);
 
-    void handleCubic(const SkMatrix& m, SkPoint pts[4]);
+    void handleCubic(SkPoint pts[4]);
 
-    void handleConic(const SkMatrix& m, SkPoint pts[3], SkScalar w);
+    void handleConic(SkPoint pts[3], SkScalar w);
 
     void addArc(const SkVector& nextNormal);
     void finishArcAndAddEdge(const SkVector& nextPoint, const SkVector& nextNormal);
@@ -69,4 +69,65 @@
     SkTDArray<SkPoint>  fPointBuffer;
 };
 
+/**
+ * This class generates an spot shadow for a path by walking the transformed path, further 
+ * transforming by the scale and translation, and outsetting and insetting by a radius.
+ * The center will be clipped against the original path unless transparent is true.
+ */
+class GrSpotShadowTessellator {
+public:
+    GrSpotShadowTessellator(const SkPath& path, SkScalar scale, const SkVector& translate,
+                            SkScalar radius, GrColor umbraColor, GrColor penumbraColor,
+                            bool transparent);
+
+    int      vertexCount() { return fPositions.count(); }
+    SkPoint* positions() { return fPositions.begin(); }
+    GrColor* colors() { return fColors.begin(); }
+    int      indexCount() { return fIndices.count(); }
+    uint16_t* indices() { return fIndices.begin(); }
+
+private:
+    void computeClipBounds(const SkPath& path);
+
+    void handleLine(const SkPoint& p);
+    void handleLine(SkScalar scale, const SkVector& xlate, SkPoint p);
+
+    void handleQuad(const SkPoint pts[3]);
+    void handleQuad(SkScalar scale, const SkVector& xlate, SkPoint pts[3]);
+
+    void handleCubic(SkScalar scale, const SkVector& xlate, SkPoint pts[4]);
+
+    void handleConic(SkScalar scale, const SkVector& xlate, SkPoint pts[3], SkScalar w);
+
+    void mapPoints(SkScalar scale, const SkVector& xlate, SkPoint* pts, int count);
+    void addInnerPoint(const SkPoint& pathPoint, GrColor umbraColor, SkScalar radiusSqd);
+    void addArc(const SkVector& nextNormal);
+    void finishArcAndAddEdge(const SkVector& nextPoint, const SkVector& nextNormal);
+    void addEdge(const SkVector& nextPoint, const SkVector& nextNormal);
+
+    SkScalar            fRadius;
+    GrColor             fUmbraColor;
+    GrColor             fPenumbraColor;
+
+    SkTDArray<SkPoint>  fPositions;
+    SkTDArray<GrColor>  fColors;
+    SkTDArray<uint16_t> fIndices;
+
+    int                 fPrevInnerIndex;
+    SkPoint             fPrevPoint;
+    SkVector            fPrevNormal;
+    int                 fFirstVertex;
+    SkPoint             fFirstPoint;
+    SkVector            fFirstNormal;
+    SkScalar            fDirection;
+
+    SkPoint             fCentroid;
+    SkTDArray<SkPoint>  fClipPolygon;
+
+    // first three points
+    SkTDArray<SkPoint>  fInitPoints;
+    // temporary buffer
+    SkTDArray<SkPoint>  fPointBuffer;
+};
+
 #endif