Add factory class for generating various flavors of GrTextContext.

This is the first pass of making Gr*TextContext more generic and easily
subclassed. The next stage will be making GrBitmapTextContext and
GrDistanceFieldTextContext more similar by moving the SkDraw loop into
each subclass.

BUG=skia:2018

Committed: http://code.google.com/p/skia/source/detail?r=13142

R=bsalomon@google.com, reed@google.com

Author: jvanverth@google.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk@13165 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index a43c4a2..6e33d90 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -24,12 +24,10 @@
                 "Dump the contents of the font cache before every purge.");
 
 GrBitmapTextContext::GrBitmapTextContext(GrContext* context, const GrPaint& paint,
-                                         SkColor color) :
-                                         GrTextContext(context, paint) {
+                                         const SkPaint& skPaint) :
+                                         GrTextContext(context, paint, skPaint) {
     fAutoMatrix.setIdentity(fContext, &fPaint);
 
-    fSkPaintColor = color;
-
     fStrike = NULL;
 
     fCurrTexture = NULL;
@@ -83,11 +81,11 @@
             // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
             // the mask texture color. The end result is that we get
             //            mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
-            int a = SkColorGetA(fSkPaintColor);
+            int a = SkColorGetA(fSkPaint.getColor());
             // paintAlpha
             drawState->setColor(SkColorSetARGB(a, a, a, a));
             // paintColor
-            drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaintColor));
+            drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
             drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
         } else {
             // set back to normal in case we took LCD path previously.
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 95e773e..4c9631e 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -28,8 +28,7 @@
 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
                                                        const GrPaint& grPaint,
                                                        const SkPaint& skPaint)
-                                                     : GrTextContext(context, grPaint),
-                                                       fSkPaint(skPaint) {
+                                                     : GrTextContext(context, grPaint, skPaint) {
     fStrike = NULL;
 
     fCurrTexture = NULL;
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 9e91628..77e98d2 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -8,7 +8,8 @@
 
 #include "GrTextContext.h"
 
-GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(paint) {
+GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint,
+                             const SkPaint& skPaint) : fPaint(paint), fSkPaint(skPaint) {
     fContext = context;
 
     const GrClipData* clipData = context->getClip();
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 5ba174c..0e91182 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -200,6 +200,12 @@
     fContext = context;
     fContext->ref();
 
+#if SK_DISTANCEFIELD_FONTS
+    fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+#else
+    fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+#endif
+
     fRenderTarget = NULL;
     fNeedClear = false;
 
@@ -235,6 +241,12 @@
     fContext = context;
     fContext->ref();
 
+#if SK_DISTANCEFIELD_FONTS
+    fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+#else
+    fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+#endif
+
     fRenderTarget = NULL;
     fNeedClear = false;
 
@@ -279,6 +291,8 @@
     if (fDrawProcs) {
         delete fDrawProcs;
     }
+    
+    delete fTextContextManager;
 
     // The GrContext takes a ref on the target. We don't want to cause the render
     // target to be unnecessarily kept alive.
@@ -1820,13 +1834,15 @@
 
         SkDEBUGCODE(this->validate();)
 
-        GrDistanceFieldTextContext context(fContext, grPaint, paint);
+        SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+        GrDistanceFieldTextContext* dfContext =
+                                            static_cast<GrDistanceFieldTextContext*>(context.get());
 
-        SkAutoGlyphCache    autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL);
+        SkAutoGlyphCache    autoCache(dfContext->getSkPaint(), &this->fLeakyProperties, NULL);
         SkGlyphCache*       cache = autoCache.getCache();
         GrFontScaler*       fontScaler = get_gr_font_scaler(cache);
 
-        context.drawText((const char *)text, byteLength, x, y, cache, fontScaler);
+        dfContext->drawText((const char *)text, byteLength, x, y, cache, fontScaler);
 #endif
     } else {
         SkDraw myDraw(draw);
@@ -1836,8 +1852,8 @@
             return;
         }
 
-        GrBitmapTextContext context(fContext, grPaint, paint.getColor());
-        myDraw.fProcs = this->initDrawForText(&context);
+        SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+        myDraw.fProcs = this->initDrawForText(context.get());
         this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
     }
 }
@@ -1861,13 +1877,15 @@
 
         SkDEBUGCODE(this->validate();)
 
-        GrDistanceFieldTextContext context(fContext, grPaint, paint);
-
-        SkAutoGlyphCache    autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL);
+        SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+        GrDistanceFieldTextContext* dfContext =
+                                            static_cast<GrDistanceFieldTextContext*>(context.get());
+        
+        SkAutoGlyphCache    autoCache(dfContext->getSkPaint(), &this->fLeakyProperties, NULL);
         SkGlyphCache*       cache = autoCache.getCache();
         GrFontScaler*       fontScaler = get_gr_font_scaler(cache);
-
-        context.drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos,
+        
+        dfContext->drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos,
                             cache, fontScaler);
 #endif
     } else {
@@ -1877,8 +1895,9 @@
         if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
             return;
         }
-        GrBitmapTextContext context(fContext, grPaint, paint.getColor());
-        myDraw.fProcs = this->initDrawForText(&context);
+
+        SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+        myDraw.fProcs = this->initDrawForText(context.get());
         this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
                                         scalarsPerPos, paint);
     }