Allow custom blitters to be passed to SkDraw::drawPath

R=reed@google.com

Author: krajcevski@google.com

Review URL: https://codereview.chromium.org/444003004
diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h
index 918f233..21d4210 100644
--- a/include/core/SkDraw.h
+++ b/include/core/SkDraw.h
@@ -17,6 +17,7 @@
 class SkBitmap;
 class SkClipStack;
 class SkBaseDevice;
+class SkBlitter;
 class SkMatrix;
 class SkPath;
 class SkRegion;
@@ -49,8 +50,9 @@
         this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
     }
 
-    void drawPath(const SkPath& path, const SkPaint& paint) const {
-        this->drawPath(path, paint, NULL, false, false);
+    void drawPath(const SkPath& path, const SkPaint& paint,
+                  SkBlitter* customBlitter = NULL) const {
+        this->drawPath(path, paint, NULL, false, false, customBlitter);
     }
 
     void    drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
@@ -74,8 +76,9 @@
      *
      *  Only device A8 is supported right now.
      */
-    void drawPathCoverage(const SkPath& src, const SkPaint& paint) const {
-        this->drawPath(src, paint, NULL, false, true);
+    void drawPathCoverage(const SkPath& src, const SkPaint& paint,
+                          SkBlitter* customBlitter = NULL) const {
+        this->drawPath(src, paint, NULL, false, true, customBlitter);
     }
 
     /** Helper function that creates a mask from a path and an optional maskfilter.
@@ -118,7 +121,8 @@
     void    drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
 
     void    drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
-                     bool pathIsMutable, bool drawCoverage) const;
+                     bool pathIsMutable, bool drawCoverage,
+                     SkBlitter* customBlitter = NULL) const;
 
     /**
      *  Return the current clip bounds, in local coordinates, with slop to account
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index b77eb43..9bc29b3 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -54,9 +54,10 @@
     SkBlitter*  get() const { return fBlitter; }
 
     void choose(const SkBitmap& device, const SkMatrix& matrix,
-                const SkPaint& paint) {
+                const SkPaint& paint, bool drawCoverage = false) {
         SkASSERT(!fBlitter);
-        fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator);
+        fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
+                                     drawCoverage);
     }
 
 private:
@@ -992,7 +993,7 @@
 
 void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
                       const SkMatrix* prePathMatrix, bool pathIsMutable,
-                      bool drawCoverage) const {
+                      bool drawCoverage, SkBlitter* customBlitter) const {
     SkDEBUGCODE(this->validate();)
 
     // nothing to draw
@@ -1078,12 +1079,19 @@
     // transform the path into device space
     pathPtr->transform(*matrix, devPathPtr);
 
-    SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, *paint, drawCoverage);
+    SkBlitter* blitter = NULL;
+    SkAutoBlitterChoose blitterStorage;
+    if (NULL == customBlitter) {
+        blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
+        blitter = blitterStorage.get();
+    } else {
+        blitter = customBlitter;
+    }
 
     if (paint->getMaskFilter()) {
         SkPaint::Style style = doFill ? SkPaint::kFill_Style :
             SkPaint::kStroke_Style;
-        if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter.get(), style)) {
+        if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter, style)) {
             return; // filterPath() called the blitter, so we're done
         }
     }
@@ -1102,7 +1110,7 @@
             proc = SkScan::HairPath;
         }
     }
-    proc(*devPathPtr, *fRC, blitter.get());
+    proc(*devPathPtr, *fRC, blitter);
 }
 
 /** For the purposes of drawing bitmaps, if a matrix is "almost" translate