Introduce text blob processing but don't wire it up

Have all the old code paths start using lists in preparation
for introducing text blobs.

Change-Id: I65cc02ee3da63bc3c9492db78a08b0eee3b1f931
Reviewed-on: https://skia-review.googlesource.com/141081
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 367105d..3c5ec34 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2431,8 +2431,8 @@
     while (iter.next()) {
         fScratchGlyphRunBuilder->drawText(
                 looper.paint(), text, byteLength, SkPoint::Make(x, y));
-        auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
-        iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
+        auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
+        iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
     }
 
     LOOPER_END
@@ -2445,8 +2445,8 @@
 
     while (iter.next()) {
         fScratchGlyphRunBuilder->drawPosText(looper.paint(), text, byteLength, pos);
-        auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
-        iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
+        auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
+        iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
     }
 
     LOOPER_END
@@ -2460,8 +2460,8 @@
     while (iter.next()) {
         fScratchGlyphRunBuilder->drawPosTextH(
                 looper.paint(), text, byteLength, xpos, constY);
-        const auto& glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
-        iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
+        auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
+        iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
     }
 
     LOOPER_END
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 5ca8f5e..a4482a1 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -157,8 +157,8 @@
             auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
             SkGlyphRunBuilder builder;
             builder.drawText(runPaint, (const char*) it.glyphs(), textLen, origin);
-            auto glyphRun = builder.useGlyphRun();
-            glyphRun->temporaryShuntToDrawPosText(this);
+            auto glyphRunList = builder.useGlyphRunList();
+            glyphRunList->temporaryShuntToDrawPosText(this);
         }
         break;
         case SkTextBlob::kHorizontal_Positioning:
@@ -239,11 +239,8 @@
     }
 }
 
-void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun) {
-    SkPaint glyphPaint(paint);
-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
-    glyphRun->temporaryShuntToDrawPosText(this);
+void SkBaseDevice::drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList) {
+    glyphRunList->temporaryShuntToDrawPosText(this);
 }
 
 void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index 2173d91..2a33822 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -16,7 +16,7 @@
 
 class SkBitmap;
 struct SkDrawShadowRec;
-class SkGlyphRun;
+class SkGlyphRunList;
 class SkGlyphRunBuilder;
 class SkImageFilterCache;
 struct SkIRect;
@@ -222,7 +222,7 @@
      *  Does not handle text decoration.
      *  Decorations (underline and stike-thru) will be handled by SkCanvas.
      */
-    virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun);
+    virtual void drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList);
     virtual void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
                               const SkPaint&) = 0;
     virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index 781263c..6cb4585 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -69,6 +69,36 @@
     callback(fTemporaryShuntGlyphIDs.size(), bytes, pos);
 }
 
+// -- SkGlyphRunList -------------------------------------------------------------------------------
+SkGlyphRunList::SkGlyphRunList(
+        const SkPaint& paint,
+        const SkTextBlob* blob,
+        SkPoint origin,
+        SkSpan<SkGlyphRun> glyphRunList)
+        : fOriginalPaint{&paint}
+        , fOriginalTextBlob{blob}
+        , fOrigin{origin}
+        , fGlyphRuns{glyphRunList} { }
+
+uint64_t SkGlyphRunList::uniqueID() const {
+    return fOriginalTextBlob != nullptr ? fOriginalTextBlob->uniqueID()
+                                        : SK_InvalidUniqueID;
+}
+
+bool SkGlyphRunList::anyRunsLCD() const {
+    for (const auto& r : fGlyphRuns) {
+        if (r.paint().isLCDRenderText()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void SkGlyphRunList::temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const {
+    SkASSERT(fOriginalTextBlob != nullptr);
+    fOriginalTextBlob->notifyAddedToCache(cacheID);
+}
+
 // -- SkGlyphIDSet ---------------------------------------------------------------------------------
 // A faster set implementation that does not need any initialization, and reading the set items
 // is order the number of items, and not the size of the universe.
@@ -140,6 +170,8 @@
         this->simplifyDrawText(
                 paint, glyphIDs, origin, fUniqueGlyphIDIndices, fUniqueGlyphIDs, fPositions);
     }
+
+    this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
 }
 
 void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes,
@@ -151,6 +183,8 @@
         this->simplifyDrawPosTextH(
                 paint, glyphIDs, xpos, constY, fUniqueGlyphIDIndices, fUniqueGlyphIDs, fPositions);
     }
+
+    this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
 }
 
 void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, const void* bytes,
@@ -158,17 +192,82 @@
     auto glyphIDs = textToGlyphIDs(paint, bytes, byteLength);
     if (!glyphIDs.empty()) {
         this->initialize(glyphIDs.size());
-        this->simplifyDrawPosText(
-                paint, glyphIDs, pos, fUniqueGlyphIDIndices, fUniqueGlyphIDs);
+        this->simplifyDrawPosText(paint, glyphIDs, pos, fUniqueGlyphIDIndices, fUniqueGlyphIDs);
     }
+
+    this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
 }
 
-SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
-    return &fScratchGlyphRun;
+void SkGlyphRunBuilder::drawTextBlob(const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) {
+    SkPaint runPaint = paint;
+
+    // Figure out all the storage needed to pre-size everything below.
+    size_t totalGlyphs = 0;
+    for (SkTextBlobRunIterator it(&blob); !it.done(); it.next()) {
+        totalGlyphs += it.glyphCount();
+    }
+
+    // Pre-size all the buffers so they don't move during processing.
+    this->initialize(totalGlyphs);
+
+    uint16_t* currentDenseIndices = fUniqueGlyphIDIndices;
+    SkPoint* currentPositions = fPositions;
+    SkGlyphID* currentUniqueGlyphIDs = fUniqueGlyphIDs;
+
+    for (SkTextBlobRunIterator it(&blob); !it.done(); it.next()) {
+        // applyFontToPaint() always overwrites the exact same attributes,
+        // so it is safe to not re-seed the paint for this reason.
+        it.applyFontToPaint(&runPaint);
+        size_t runSize = it.glyphCount();
+
+        // These better be glyphs
+        SkASSERT(runPaint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+
+        auto text = SkSpan<const char>(it.text(), it.textSize());
+        auto clusters = SkSpan<const uint32_t>(it.clusters(), runSize);
+        const SkPoint& offset = it.offset();
+        auto glyphIDs = SkSpan<const SkGlyphID>{it.glyphs(), runSize};
+
+        size_t uniqueGlyphIDsSize = 0;
+        switch (it.positioning()) {
+            case SkTextBlob::kDefault_Positioning: {
+                uniqueGlyphIDsSize = this->simplifyDrawText(
+                        runPaint, glyphIDs, offset,
+                        currentDenseIndices, currentUniqueGlyphIDs, currentPositions,
+                        text, clusters);
+            }
+                break;
+            case SkTextBlob::kHorizontal_Positioning: {
+                auto constY = offset.y();
+                uniqueGlyphIDsSize = this->simplifyDrawPosTextH(
+                        runPaint, glyphIDs, it.pos(), constY,
+                        currentDenseIndices, currentUniqueGlyphIDs, currentPositions,
+                        text, clusters);
+            }
+                break;
+            case SkTextBlob::kFull_Positioning:
+                uniqueGlyphIDsSize = this->simplifyDrawPosText(
+                        runPaint, glyphIDs, (const SkPoint*)it.pos(),
+                        currentDenseIndices, currentUniqueGlyphIDs,
+                        text, clusters);
+                break;
+            default:
+                SK_ABORT("unhandled positioning mode");
+        }
+
+        currentDenseIndices += runSize;
+        currentPositions += runSize;
+        currentUniqueGlyphIDs += uniqueGlyphIDsSize;
+    }
+
+    this->makeGlyphRunList(paint, &blob, origin);
+}
+
+SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() {
+    return &fGlyphRunList;
 }
 
 void SkGlyphRunBuilder::initialize(size_t totalRunSize) {
-    fUniqueID = 0;
 
     if (totalRunSize > fMaxTotalRunSize) {
         fMaxTotalRunSize = totalRunSize;
@@ -177,8 +276,7 @@
         fUniqueGlyphIDs.reset(fMaxTotalRunSize);
     }
 
-    // Be sure to clean up the last run before we reuse it.
-    fScratchGlyphRun.~SkGlyphRun();
+    fGlyphRunListStorage.clear();
 }
 
 SkSpan<const SkGlyphID> SkGlyphRunBuilder::textToGlyphIDs(
@@ -236,25 +334,31 @@
         glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         glyphRunPaint.setTextAlign(SkPaint::kLeft_Align);
 
-        new ((void*)&fScratchGlyphRun) SkGlyphRun{
+        fGlyphRunListStorage.emplace_back(
                 std::move(glyphRunPaint),
                 uniqueGlyphIDIndices,
                 positions,
                 glyphIDs,
                 uniqueGlyphIDs,
                 text,
-                clusters
-        };
+                clusters);
     }
 }
 
-void SkGlyphRunBuilder::simplifyDrawText(
+void SkGlyphRunBuilder::makeGlyphRunList(
+        const SkPaint& paint, const SkTextBlob* blob, SkPoint origin) {
+
+    fGlyphRunList.~SkGlyphRunList();
+    new (&fGlyphRunList) SkGlyphRunList{
+        paint, blob, origin, SkSpan<SkGlyphRun>{fGlyphRunListStorage}};
+}
+
+size_t SkGlyphRunBuilder::simplifyDrawText(
         const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, SkPoint origin,
         uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer, SkPoint* positions,
         SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
     SkASSERT(!glyphIDs.empty());
 
-
     auto runSize = glyphIDs.size();
 
     auto unqiueGlyphIDs = this->addDenseAndUnique(
@@ -271,7 +375,7 @@
 
         for (size_t i = 0; i < runSize; i++) {
             positions[i] = endOfLastGlyph;
-            endOfLastGlyph += fScratchAdvances[fUniqueGlyphIDIndices[i]];
+            endOfLastGlyph += fScratchAdvances[uniqueGlyphIDIndicesBuffer[i]];
         }
 
         if (paint.getTextAlign() != SkPaint::kLeft_Align) {
@@ -289,14 +393,16 @@
                 paint,
                 glyphIDs,
                 SkSpan<const SkPoint>{positions, runSize},
-                SkSpan<const uint16_t>{fUniqueGlyphIDIndices, runSize},
+                SkSpan<const uint16_t>{uniqueGlyphIDIndicesBuffer, runSize},
                 unqiueGlyphIDs,
                 text,
                 clusters);
     }
+
+    return unqiueGlyphIDs.size();
 }
 
-void SkGlyphRunBuilder::simplifyDrawPosTextH(
+size_t SkGlyphRunBuilder::simplifyDrawPosTextH(
         const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs,
         const SkScalar* xpos, SkScalar constY,
         uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer, SkPoint* positions,
@@ -307,13 +413,13 @@
         *posCursor++ = SkPoint::Make(x, constY);
     }
 
-    this->simplifyDrawPosText(
+    return this->simplifyDrawPosText(
             paint, glyphIDs, positions,
             uniqueGlyphIDIndicesBuffer, uniqueGlyphIDsBuffer,
             text, clusters);
 }
 
-void SkGlyphRunBuilder::simplifyDrawPosText(
+size_t SkGlyphRunBuilder::simplifyDrawPosText(
         const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, const SkPoint* pos,
         uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer,
         SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
@@ -336,6 +442,7 @@
             uniqueGlyphIDs,
             text,
             clusters);
+    return 0;
 }
 
 
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index a1124fd..4b392fd 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -61,10 +61,8 @@
     void temporaryShuntToCallback(TemporaryShuntCallback callback);
 
     size_t runSize() const { return fUniqueGlyphIDIndices.size(); }
-    uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); }
     SkSpan<const SkPoint> positions() const { return fPositions; }
-    SkSpan<const SkGlyphID> uniqueGlyphIDs() const { return fUniqueGlyphIDs; }
-    SkSpan<const SkGlyphID> shuntGlyphsIDs() const { return fTemporaryShuntGlyphIDs; }
+    const SkPaint& paint() const { return fRunPaint; }
 
 private:
     //
@@ -83,6 +81,53 @@
     const SkPaint fRunPaint;
 };
 
+class SkGlyphRunList {
+    const SkPaint* fOriginalPaint{nullptr};
+    // The text blob is needed to hookup the call back that the SkTextBlob destructor calls. It
+    // should be used for nothing else
+    const SkTextBlob*  fOriginalTextBlob{nullptr};
+    SkPoint fOrigin = {0, 0};
+    SkSpan<SkGlyphRun> fGlyphRuns;
+
+public:
+    SkGlyphRunList() = default;
+    // Blob maybe null.
+    SkGlyphRunList(
+            const SkPaint& paint,
+            const SkTextBlob* blob,
+            SkPoint origin,
+            SkSpan<SkGlyphRun> glyphRunList);
+
+    uint64_t uniqueID() const;
+    bool anyRunsLCD() const;
+    void temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const;
+
+    bool canCache() const { return fOriginalTextBlob != nullptr; }
+    size_t runCount() const { return fGlyphRuns.size(); }
+    size_t totalGlyphCount() const {
+        size_t glyphCount = 0;
+        for(const auto& run : fGlyphRuns) {
+            glyphCount += run.runSize();
+        }
+        return glyphCount;
+    }
+
+    SkPoint origin() const { return fOrigin; }
+    const SkPaint& paint() const { return *fOriginalPaint; }
+
+    auto begin() -> decltype(fGlyphRuns.begin())               { return fGlyphRuns.begin(); }
+    auto end()   -> decltype(fGlyphRuns.end())                 { return fGlyphRuns.end();   }
+    auto size()  -> decltype(fGlyphRuns.size())                { return fGlyphRuns.size();  }
+    auto empty() -> decltype(fGlyphRuns.empty())               { return fGlyphRuns.empty(); }
+    auto operator [] (size_t i) -> decltype(fGlyphRuns[i])     { return fGlyphRuns[i];      }
+    void temporaryShuntToDrawPosText(SkBaseDevice* device) {
+        for (auto& run : fGlyphRuns) {
+            run.temporaryShuntToDrawPosText(device);
+        }
+    }
+
+};
+
 class SkGlyphIDSet {
 public:
     SkSpan<const SkGlyphID> uniquifyGlyphIDs(
@@ -96,16 +141,16 @@
 class SkGlyphRunBuilder {
 public:
     void drawText(
-            const SkPaint& paint, const void* bytes, size_t byteLength,
-            SkPoint origin);
+            const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin);
     void drawPosTextH(
             const SkPaint& paint, const void* bytes, size_t byteLength,
             const SkScalar* xpos, SkScalar constY);
     void drawPosText(
-            const SkPaint& paint, const void* bytes, size_t byteLength,
-            const SkPoint* pos);
+            const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos);
+    void drawTextBlob(const SkPaint& paint, const SkTextBlob& blob, SkPoint origin);
 
     SkGlyphRun* useGlyphRun();
+    SkGlyphRunList* useGlyphRunList();
 
 private:
     void initialize(size_t totalRunSize);
@@ -128,30 +173,35 @@
             SkSpan<const char> text,
             SkSpan<const uint32_t> clusters);
 
-    void simplifyDrawText(
+    void makeGlyphRunList(const SkPaint& paint, const SkTextBlob* blob, SkPoint origin);
+
+    size_t simplifyDrawText(
             const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, SkPoint origin,
             uint16_t* uniqueGlyphIDIndices, SkGlyphID* uniqueGlyphIDs, SkPoint* positions,
             SkSpan<const char> text = SkSpan<const char>{},
             SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
-    void simplifyDrawPosTextH(
+    size_t simplifyDrawPosTextH(
             const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs,
             const SkScalar* xpos, SkScalar constY,
             uint16_t* uniqueGlyphIDIndices, SkGlyphID* uniqueGlyphIDs, SkPoint* positions,
             SkSpan<const char> text = SkSpan<const char>{},
             SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
-    void simplifyDrawPosText(
+    size_t simplifyDrawPosText(
             const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, const SkPoint* pos,
             uint16_t* uniqueGlyphIDIndices, SkGlyphID* uniqueGlyphIDs,
             SkSpan<const char> text = SkSpan<const char>{},
             SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
 
-    uint64_t fUniqueID{0};
 
     size_t fMaxTotalRunSize{0};
     SkAutoTMalloc<uint16_t> fUniqueGlyphIDIndices;
     SkAutoTMalloc<SkPoint> fPositions;
     SkAutoTMalloc<SkGlyphID> fUniqueGlyphIDs;
 
+    std::vector<SkGlyphRun> fGlyphRunListStorage;
+    SkGlyphRunList fGlyphRunList;
+
+
     // Used as a temporary for preparing using utfN text. This implies that only one run of
     // glyph ids will ever be needed because blobs are already glyph based.
     std::vector<SkGlyphID> fScratchGlyphIDs;
@@ -159,10 +209,6 @@
     // Used as temporary storage for calculating positions for drawText.
     std::vector<SkPoint> fScratchAdvances;
 
-
-    // Used as temporary glyph run for the rest of the Text stack.
-    SkGlyphRun fScratchGlyphRun;
-
     // Used for collecting the set of unique glyphs.
     SkGlyphIDSet fGlyphIDSet;
 };
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index 04d92ae..a2ef40f 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -214,15 +214,17 @@
                     builder.drawText(runPaint.skPaint(),
                                      (const char*) it.glyphs(), textLen, origin);
 
-                    auto glyphRun = builder.useGlyphRun();
-
-                    glyphRun->temporaryShuntToCallback(
+                    auto glyphRunList = builder.useGlyphRunList();
+                    if (!glyphRunList->empty()) {
+                        auto glyphRun = (*glyphRunList)[0];
+                        glyphRun.temporaryShuntToCallback(
                             [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
                                 this->drawDFPosText(
-                                    cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
-                                    viewMatrix, glyphIDs, 2 * runSize, pos, 2,
-                                    SkPoint::Make(0,0));
+                                    cacheBlob, run, glyphCache, props, runPaint,
+                                    scalerContextFlags, viewMatrix, glyphIDs, 2 * runSize,
+                                    pos, 2, SkPoint::Make(0, 0));
                             });
+                    }
                     break;
                 }
 
@@ -249,15 +251,18 @@
                     builder.drawText(runPaint.skPaint(),
                                      (const char*) it.glyphs(), textLen, origin);
 
-                    auto glyphRun = builder.useGlyphRun();
+                    auto glyphRunList = builder.useGlyphRunList();
+                    if (!glyphRunList->empty()) {
+                        auto glyphRun = (*glyphRunList)[0];
 
-                    glyphRun->temporaryShuntToCallback(
+                        glyphRun.temporaryShuntToCallback(
                             [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
                                 this->DrawBmpPosText(
-                                    cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
-                                    viewMatrix, glyphIDs, 2 * runSize,
+                                    cacheBlob, run, glyphCache, props, runPaint,
+                                    scalerContextFlags, viewMatrix, glyphIDs, 2 * runSize,
                                     pos, 2, SkPoint::Make(0, 0));
                             });
+                    }
                     break;
                 }
                 case SkTextBlob::kHorizontal_Positioning:
@@ -783,16 +788,20 @@
     builder.drawText(skPaint, text, textLen, origin);
     sk_sp<GrTextBlob> blob;
 
-    auto glyphRun = builder.useGlyphRun();
-    // Use the text and textLen below, because we don't want to mess with the paint.
-    glyphRun->temporaryShuntToCallback(
+    auto glyphRunList = builder.useGlyphRunList();
+    if (!glyphRunList->empty()) {
+        auto glyphRun = (*glyphRunList)[0];
+        // Use the text and textLen below, because we don't want to mess with the paint.
+        glyphRun.temporaryShuntToCallback(
             [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
                 blob = textContext->makeDrawPosTextBlob(
                     context->contextPriv().getTextBlobCache(), glyphCache,
                     *context->contextPriv().caps()->shaderCaps(), utilsPaint,
-                    GrTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps, text,
+                    GrTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps,
+                    text,
                     textLen, pos, 2, origin);
             });
+    }
 
     return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, surfaceProps,
                              textContext->dfAdjustTable(), rtc->textTarget());