Create GrTextUtils

BUG=skia:

Review URL: https://codereview.chromium.org/1514933002
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 52a9c3a..8baa40f 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -190,6 +190,8 @@
       '<(skia_src_path)/gpu/GrTextureProvider.cpp',
       '<(skia_src_path)/gpu/GrTexturePriv.h',
       '<(skia_src_path)/gpu/GrTextureAccess.cpp',
+      '<(skia_src_path)/gpu/GrTextUtils.cpp',
+      '<(skia_src_path)/gpu/GrTextUtils.h',
       '<(skia_src_path)/gpu/GrTransferBuffer.h',
       '<(skia_src_path)/gpu/GrTRecorder.h',
       '<(skia_src_path)/gpu/GrVertexBuffer.h',
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 2090ed2..087f85e 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -1094,7 +1094,7 @@
     friend class GrDistanceFieldTextContext;
     friend class GrStencilAndCoverTextContext;
     friend class GrPathRendering;
-    friend class GrTextContext;
+    friend class GrTextUtils;
     friend class GrGLPathRendering;
     friend class SkScalerContext;
     friend class SkTextToPathIter;
diff --git a/src/gpu/GrAtlasTextBlob.cpp b/src/gpu/GrAtlasTextBlob.cpp
index 50ce0f8..dee6d13 100644
--- a/src/gpu/GrAtlasTextBlob.cpp
+++ b/src/gpu/GrAtlasTextBlob.cpp
@@ -10,6 +10,7 @@
 #include "GrBlurUtils.h"
 #include "GrContext.h"
 #include "GrDrawContext.h"
+#include "GrTextUtils.h"
 #include "SkColorFilter.h"
 #include "SkDrawFilter.h"
 #include "SkTextBlobRunIterator.h"
@@ -300,8 +301,7 @@
     }
 }
 
-void GrAtlasTextBlob::flushRunAsPaths(GrDrawContext* dc,
-                                      GrTextContext* textContext,
+void GrAtlasTextBlob::flushRunAsPaths(GrContext* context, GrDrawContext* dc,
                                       const SkSurfaceProps& props,
                                       const SkTextBlobRunIterator& it,
                                       const GrClip& clip, const SkPaint& skPaint,
@@ -322,28 +322,27 @@
 
     switch (it.positioning()) {
         case SkTextBlob::kDefault_Positioning:
-            textContext->drawTextAsPath(dc, clip, runPaint, viewMatrix,
+            GrTextUtils::DrawTextAsPath(context, dc, clip, runPaint, viewMatrix,
                                         (const char *)it.glyphs(),
                                         textLen, x + offset.x(), y + offset.y(), clipBounds);
             break;
         case SkTextBlob::kHorizontal_Positioning:
-            textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix,
+            GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix,
                                            (const char*)it.glyphs(),
                                            textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()),
                                            clipBounds);
             break;
         case SkTextBlob::kFull_Positioning:
-            textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix,
+            GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix,
                                            (const char*)it.glyphs(),
                                            textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds);
             break;
     }
 }
 
-void GrAtlasTextBlob::flushCached(const SkTextBlob* blob,
-                                  GrContext* context,
+void GrAtlasTextBlob::flushCached(GrContext* context,
                                   GrDrawContext* dc,
-                                  GrTextContext* textContext,
+                                  const SkTextBlob* blob,
                                   const SkSurfaceProps& props,
                                   const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                   const SkPaint& skPaint,
@@ -363,7 +362,7 @@
     SkTextBlobRunIterator it(blob);
     for (int run = 0; !it.done(); it.next(), run++) {
         if (fRuns[run].fDrawAsPaths) {
-            this->flushRunAsPaths(dc, textContext, props, it, clip, skPaint,
+            this->flushRunAsPaths(context, dc, props, it, clip, skPaint,
                                   drawFilter, viewMatrix, clipBounds, x, y);
             continue;
         }
diff --git a/src/gpu/GrAtlasTextBlob.h b/src/gpu/GrAtlasTextBlob.h
index 0f99576..d99ae70 100644
--- a/src/gpu/GrAtlasTextBlob.h
+++ b/src/gpu/GrAtlasTextBlob.h
@@ -316,10 +316,9 @@
                         const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
 
     // flush a GrAtlasTextBlob associated with a SkTextBlob
-    void flushCached(const SkTextBlob* blob,
-                     GrContext* context,
+    void flushCached(GrContext* context,
                      GrDrawContext* dc,
-                     GrTextContext* textContext,
+                     const SkTextBlob* blob,
                      const SkSurfaceProps& props,
                      const GrDistanceFieldAdjustTable* distanceAdjustTable,
                      const SkPaint& skPaint,
@@ -377,8 +376,8 @@
                         SkScalar transX, SkScalar transY,
                         const SkIRect& clipBounds);
 
-    void flushRunAsPaths(GrDrawContext* dc,
-                         GrTextContext* textContext,
+    void flushRunAsPaths(GrContext* context,
+                         GrDrawContext* dc,
                          const SkSurfaceProps& props,
                          const SkTextBlobRunIterator& it,
                          const GrClip& clip, const SkPaint& skPaint,
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 5e11eb5..735693b 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -203,7 +203,7 @@
                                  blob, x, y, drawFilter, clip);
     }
 
-    cacheBlob->flushCached(blob, fContext, dc, this, fSurfaceProps, fDistanceAdjustTable, skPaint,
+    cacheBlob->flushCached(fContext, dc, blob, fSurfaceProps, fDistanceAdjustTable, skPaint,
                            grPaint, drawFilter, clip, viewMatrix, clipBounds, x, y, transX, transY);
 }
 
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 7ce7a31..8ff2523 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -6,20 +6,14 @@
  */
 
 #include "GrTextContext.h"
-#include "GrBlurUtils.h"
 #include "GrContext.h"
-#include "GrDrawContext.h"
 #include "GrFontScaler.h"
+#include "GrTextUtils.h"
 
-#include "SkAutoKern.h"
 #include "SkDrawFilter.h"
-#include "SkDrawProcs.h"
 #include "SkGlyphCache.h"
-#include "SkGpuDevice.h"
 #include "SkGrPriv.h"
 #include "SkTextBlobRunIterator.h"
-#include "SkTextMapStateProc.h"
-#include "SkTextToPathIter.h"
 
 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfaceProps)
     : fFallbackTextContext(nullptr)
@@ -51,7 +45,8 @@
     } while (textContext);
 
     // fall back to drawing as a path
-    this->drawTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, x, y, clipBounds);
+    GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, byteLength, x, y,
+                                clipBounds);
 }
 
 void GrTextContext::drawPosText(GrDrawContext* dc,
@@ -76,8 +71,8 @@
     } while (textContext);
 
     // fall back to drawing as a path
-    this->drawPosTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, pos,
-                            scalarsPerPosition, offset, clipBounds);
+    GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, viewMatrix, text,
+                                   byteLength, pos, scalarsPerPosition, offset, clipBounds);
 }
 
 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) {
@@ -160,105 +155,6 @@
     }
 }
 
-void GrTextContext::drawTextAsPath(GrDrawContext* dc,
-                                   const GrClip& clip,
-                                   const SkPaint& skPaint, const SkMatrix& viewMatrix,
-                                   const char text[], size_t byteLength, SkScalar x, SkScalar y,
-                                   const SkIRect& clipBounds) {
-    SkTextToPathIter iter(text, byteLength, skPaint, true);
-
-    SkMatrix    matrix;
-    matrix.setScale(iter.getPathScale(), iter.getPathScale());
-    matrix.postTranslate(x, y);
-
-    const SkPath* iterPath;
-    SkScalar xpos, prevXPos = 0;
-
-    while (iter.next(&iterPath, &xpos)) {
-        matrix.postTranslate(xpos - prevXPos, 0);
-        if (iterPath) {
-            const SkPaint& pnt = iter.getPaint();
-            GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *iterPath,
-                                                pnt, viewMatrix, &matrix, clipBounds, false);
-        }
-        prevXPos = xpos;
-    }
-}
-
-void GrTextContext::drawPosTextAsPath(GrDrawContext* dc,
-                                      const GrClip& clip,
-                                      const SkPaint& origPaint, const SkMatrix& viewMatrix,
-                                      const char text[], size_t byteLength,
-                                      const SkScalar pos[], int scalarsPerPosition,
-                                      const SkPoint& offset, const SkIRect& clipBounds) {
-    // setup our std paint, in hopes of getting hits in the cache
-    SkPaint paint(origPaint);
-    SkScalar matrixScale = paint.setupForAsPaths();
-
-    SkMatrix matrix;
-    matrix.setScale(matrixScale, matrixScale);
-
-    // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
-    paint.setStyle(SkPaint::kFill_Style);
-    paint.setPathEffect(nullptr);
-
-    SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
-    SkAutoGlyphCache    autoCache(paint, &fSurfaceProps, nullptr);
-    SkGlyphCache*       cache = autoCache.getCache();
-
-    const char*        stop = text + byteLength;
-    SkTextAlignProc    alignProc(paint.getTextAlign());
-    SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
-
-    // Now restore the original settings, so we "draw" with whatever style/stroking.
-    paint.setStyle(origPaint.getStyle());
-    paint.setPathEffect(origPaint.getPathEffect());
-
-    while (text < stop) {
-        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
-        if (glyph.fWidth) {
-            const SkPath* path = cache->findPath(glyph);
-            if (path) {
-                SkPoint tmsLoc;
-                tmsProc(pos, &tmsLoc);
-                SkPoint loc;
-                alignProc(tmsLoc, glyph, &loc);
-
-                matrix[SkMatrix::kMTransX] = loc.fX;
-                matrix[SkMatrix::kMTransY] = loc.fY;
-                GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *path, paint,
-                                                    viewMatrix, &matrix, clipBounds, false);
-            }
-        }
-        pos += scalarsPerPosition;
-    }
-}
-
-// *** change to output positions?
-int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
-                                const char text[], size_t byteLength, SkVector* stopVector) {
-    SkFixed     x = 0, y = 0;
-    const char* stop = text + byteLength;
-
-    SkAutoKern  autokern;
-
-    int numGlyphs = 0;
-    while (text < stop) {
-        // don't need x, y here, since all subpixel variants will have the
-        // same advance
-        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
-
-        x += autokern.adjust(glyph) + glyph.fAdvanceX;
-        y += glyph.fAdvanceY;
-        ++numGlyphs;
-    }
-    stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
-
-    SkASSERT(text == stop);
-    
-    return numGlyphs;
-}
-
 static void GlyphCacheAuxProc(void* data) {
     GrFontScaler* scaler = (GrFontScaler*)data;
     SkSafeUnref(scaler);
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index 387717c..1e27caa 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -65,20 +65,7 @@
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset, const SkIRect& clipBounds) = 0;
 
-    void drawTextAsPath(GrDrawContext*, const GrClip& clip,
-                        const SkPaint& origPaint, const SkMatrix& viewMatrix,
-                        const char text[], size_t byteLength, SkScalar x, SkScalar y,
-                        const SkIRect& clipBounds);
-    void drawPosTextAsPath(GrDrawContext*, const GrClip& clip,
-                           const SkPaint& origPaint, const SkMatrix& viewMatrix,
-                           const char text[], size_t byteLength,
-                           const SkScalar pos[], int scalarsPerPosition,
-                           const SkPoint& offset, const SkIRect& clipBounds);
-
     static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
-    // sets extent in stopVector and returns glyph count
-    static int MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
-                           const char text[], size_t byteLength, SkVector* stopVector);
     static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
 
     friend class GrAtlasTextBatch;
diff --git a/src/gpu/GrTextUtils.cpp b/src/gpu/GrTextUtils.cpp
new file mode 100644
index 0000000..e56b5cb
--- /dev/null
+++ b/src/gpu/GrTextUtils.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextUtils.h"
+
+#include "GrBlurUtils.h"
+#include "GrContext.h"
+#include "GrDrawContext.h"
+#include "SkDrawProcs.h"
+#include "SkGlyphCache.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkTextMapStateProc.h"
+#include "SkTextToPathIter.h"
+
+void GrTextUtils::DrawTextAsPath(GrContext* context, GrDrawContext* dc,
+                                 const GrClip& clip,
+                                 const SkPaint& skPaint, const SkMatrix& viewMatrix,
+                                 const char text[], size_t byteLength, SkScalar x, SkScalar y,
+                                 const SkIRect& clipBounds) {
+    SkTextToPathIter iter(text, byteLength, skPaint, true);
+
+    SkMatrix    matrix;
+    matrix.setScale(iter.getPathScale(), iter.getPathScale());
+    matrix.postTranslate(x, y);
+
+    const SkPath* iterPath;
+    SkScalar xpos, prevXPos = 0;
+
+    while (iter.next(&iterPath, &xpos)) {
+        matrix.postTranslate(xpos - prevXPos, 0);
+        if (iterPath) {
+            const SkPaint& pnt = iter.getPaint();
+            GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *iterPath,
+                                                pnt, viewMatrix, &matrix, clipBounds, false);
+        }
+        prevXPos = xpos;
+    }
+}
+
+void GrTextUtils::DrawPosTextAsPath(GrContext* context,
+                                    GrDrawContext* dc,
+                                    const SkSurfaceProps& props,
+                                    const GrClip& clip,
+                                    const SkPaint& origPaint, const SkMatrix& viewMatrix,
+                                    const char text[], size_t byteLength,
+                                    const SkScalar pos[], int scalarsPerPosition,
+                                    const SkPoint& offset, const SkIRect& clipBounds) {
+    // setup our std paint, in hopes of getting hits in the cache
+    SkPaint paint(origPaint);
+    SkScalar matrixScale = paint.setupForAsPaths();
+
+    SkMatrix matrix;
+    matrix.setScale(matrixScale, matrixScale);
+
+    // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
+    paint.setStyle(SkPaint::kFill_Style);
+    paint.setPathEffect(nullptr);
+
+    SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
+    SkAutoGlyphCache    autoCache(paint, &props, nullptr);
+    SkGlyphCache*       cache = autoCache.getCache();
+
+    const char*        stop = text + byteLength;
+    SkTextAlignProc    alignProc(paint.getTextAlign());
+    SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
+
+    // Now restore the original settings, so we "draw" with whatever style/stroking.
+    paint.setStyle(origPaint.getStyle());
+    paint.setPathEffect(origPaint.getPathEffect());
+
+    while (text < stop) {
+        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+        if (glyph.fWidth) {
+            const SkPath* path = cache->findPath(glyph);
+            if (path) {
+                SkPoint tmsLoc;
+                tmsProc(pos, &tmsLoc);
+                SkPoint loc;
+                alignProc(tmsLoc, glyph, &loc);
+
+                matrix[SkMatrix::kMTransX] = loc.fX;
+                matrix[SkMatrix::kMTransY] = loc.fY;
+                GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *path, paint,
+                                                    viewMatrix, &matrix, clipBounds, false);
+            }
+        }
+        pos += scalarsPerPosition;
+    }
+}
diff --git a/src/gpu/GrTextUtils.h b/src/gpu/GrTextUtils.h
new file mode 100644
index 0000000..cd2067f
--- /dev/null
+++ b/src/gpu/GrTextUtils.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextUtils_DEFINED
+#define GrTextUtils_DEFINED
+
+#include "SkScalar.h"
+
+class GrClip;
+class GrContext;
+class GrDrawContext;
+class SkMatrix;
+struct SkIRect;
+class SkPaint;
+struct SkPoint;
+class SkSurfaceProps;
+
+/*
+ * A class to house a bunch of common text utilities.  This class should *ONLY* have static
+ * functions.  It is not a namespace only because we wish to friend SkPaint
+ *
+ */
+class GrTextUtils {
+public:
+
+static void DrawTextAsPath(GrContext*, GrDrawContext*, const GrClip& clip,
+                           const SkPaint& origPaint, const SkMatrix& viewMatrix,
+                           const char text[], size_t byteLength, SkScalar x, SkScalar y,
+                           const SkIRect& clipBounds);
+
+static void DrawPosTextAsPath(GrContext* context,
+                              GrDrawContext* dc,
+                              const SkSurfaceProps& props,
+                              const GrClip& clip,
+                              const SkPaint& origPaint, const SkMatrix& viewMatrix,
+                              const char text[], size_t byteLength,
+                              const SkScalar pos[], int scalarsPerPosition,
+                              const SkPoint& offset, const SkIRect& clipBounds);
+};
+
+#endif