Duplicate drawDFPosText into drawDFGlyphRun

This CL has duplicate code, but this should be a small CL to
judge how glyphRuns will change the code.

Change-Id: Ib4700aa9d19ae3811090796a2c59bbe746361202
Reviewed-on: https://skia-review.googlesource.com/144022
Auto-Submit: Herb Derby <herb@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index d57055a..4631991 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -196,12 +196,10 @@
         }
         cacheBlob->setRunPaintFlags(run, runPaint.skPaint().getFlags());
 
-        SkASSERT(it.positioning() == SkTextBlobRunIterator::kFull_Positioning);
         if (CanDrawAsDistanceFields(runPaint, viewMatrix, props,
                                     shaderCaps.supportsDistanceFieldText(), fOptions)) {
-            this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
-                                scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
-                                textLen, it.pos(), 2, origin);
+            this->drawDFGlyphRun(cacheBlob, run, glyphCache, props, runPaint,
+                                scalerContextFlags, viewMatrix, it.glyphRun(), origin);
         } else {
             DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
                            viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2,
@@ -577,6 +575,50 @@
     fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags);
 }
 
+void GrTextContext::drawDFGlyphRun(GrTextBlob* blob, int runIndex,
+                                  GrGlyphCache* glyphCache, const SkSurfaceProps& props,
+                                  const GrTextUtils::Paint& paint,
+                                  SkScalerContextFlags scalerContextFlags,
+                                  const SkMatrix& viewMatrix, const SkGlyphRun& glyphRun,
+                                  const SkPoint& offset) const {
+    bool hasWCoord = viewMatrix.hasPerspective() || fOptions.fDistanceFieldVerticesAlwaysHaveW;
+
+    // Setup distance field paint and text ratio
+    SkScalar textRatio;
+    SkPaint dfPaint(paint);
+    SkScalerContextFlags flags;
+    InitDistanceFieldPaint(blob, &dfPaint, viewMatrix, fOptions, &textRatio, &flags);
+    blob->setHasDistanceField();
+    blob->setSubRunHasDistanceFields(runIndex, paint.skPaint().isLCDRenderText(),
+                                     paint.skPaint().isAntiAlias(), hasWCoord);
+
+    FallbackGlyphRunHelper fallbackTextHelper(viewMatrix, paint, glyphCache->getGlyphSizeLimit(),
+                                          textRatio);
+
+    sk_sp<GrTextStrike> currStrike;
+
+    {
+        auto cache = blob->setupCache(runIndex, props, flags, dfPaint, nullptr);
+
+        const SkPoint* positionCursor = glyphRun.positions().data();
+        for (auto glyphID : glyphRun.shuntGlyphsIDs()) {
+            const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID);
+            SkPoint glyphPos = offset + *positionCursor++;
+            if (glyph.fWidth > 0) {
+                if (glyph.fMaskFormat == SkMask::kSDF_Format) {
+                    DfAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph, glyphPos.fX,
+                                  glyphPos.fY, paint.filteredPremulColor(), cache.get(), textRatio);
+                } else {
+                    // can't append non-SDF glyph to SDF batch, send to fallback
+                    fallbackTextHelper.appendText(glyph, glyphID, glyphPos);
+                }
+            }
+        }
+    }
+
+    fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags);
+}
+
 // TODO: merge with BmpAppendGlyph
 void GrTextContext::DfAppendGlyph(GrTextBlob* blob, int runIndex,
                                   GrGlyphCache* grGlyphCache, sk_sp<GrTextStrike>* strike,
@@ -689,6 +731,77 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
+void GrTextContext::FallbackGlyphRunHelper::appendText(
+        const SkGlyph& glyph, SkGlyphID glyphID, SkPoint glyphPos) {
+    SkScalar maxDim = SkTMax(glyph.fWidth, glyph.fHeight)*fTextRatio;
+    if (SkScalarNearlyZero(maxDim)) return;
+
+    if (!fUseTransformedFallback) {
+        if (!fViewMatrix.isScaleTranslate() || maxDim*fMaxScale > fMaxTextSize) {
+            fUseTransformedFallback = true;
+            fMaxTextSize -= 2;    // Subtract 2 to account for the bilerp pad around the glyph
+        }
+    }
+
+    fFallbackTxt.push_back(glyphID);
+    if (fUseTransformedFallback) {
+        // If there's a glyph in the font that's particularly large, it's possible
+        // that fScaledFallbackTextSize may end up minimizing too much. We'd rather skip
+        // that glyph than make the others blurry, so we set a minimum size of half the
+        // maximum text size to avoid this case.
+        SkScalar glyphTextSize =
+                SkTMax(SkScalarFloorToScalar(fTextSize * fMaxTextSize/maxDim), 0.5f*fMaxTextSize);
+        fTransformedFallbackTextSize = SkTMin(glyphTextSize, fTransformedFallbackTextSize);
+    }
+    fFallbackPos.push_back(glyphPos);
+}
+
+void GrTextContext::FallbackGlyphRunHelper::drawText(
+        GrTextBlob* blob, int runIndex, GrGlyphCache* glyphCache, const SkSurfaceProps& props,
+        const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags) {
+    if (!fFallbackTxt.empty()) {
+        blob->initOverride(runIndex);
+        blob->setHasBitmap();
+        blob->setSubRunHasW(runIndex, fViewMatrix.hasPerspective());
+        const SkPaint& skPaint = paint.skPaint();
+        SkColor textColor = paint.filteredPremulColor();
+
+        SkScalar textRatio = SK_Scalar1;
+        SkPaint fallbackPaint(skPaint);
+        SkMatrix matrix = fViewMatrix;
+        this->initializeForDraw(&fallbackPaint, &textRatio, &matrix);
+        SkExclusiveStrikePtr cache =
+                blob->setupCache(runIndex, props, scalerContextFlags, fallbackPaint, &matrix);
+
+        sk_sp<GrTextStrike> currStrike;
+        auto glyphPos = fFallbackPos.begin();
+        for (auto glyphID : fFallbackTxt) {
+            const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID);
+            if (!fUseTransformedFallback) {
+                fViewMatrix.mapPoints(&*glyphPos, 1);
+                glyphPos->fX = SkScalarFloorToScalar(glyphPos->fX);
+                glyphPos->fY = SkScalarFloorToScalar(glyphPos->fY);
+            }
+            GrTextContext::BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph,
+                                          glyphPos->fX, glyphPos->fY, textColor,
+                                          cache.get(), textRatio, fUseTransformedFallback);
+            glyphPos++;
+        }
+    }
+}
+
+void GrTextContext::FallbackGlyphRunHelper::initializeForDraw(
+        SkPaint* paint, SkScalar* textRatio, SkMatrix* matrix) const {
+    if (!fUseTransformedFallback) return;
+
+    paint->setTextSize(fTransformedFallbackTextSize);
+    *textRatio = fTextSize / fTransformedFallbackTextSize;
+    *matrix = SkMatrix::I();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
 #if GR_TEST_UTILS
 
 #include "GrRenderTargetContext.h"