don't use paint's gettextpath

Bug: skia:
Change-Id: I8ad0b924195f46a29b095e85a8c0573912f0045d
Reviewed-on: https://skia-review.googlesource.com/c/179986
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
diff --git a/gm/pictureimagegenerator.cpp b/gm/pictureimagegenerator.cpp
index 4e465d1..04b7064 100644
--- a/gm/pictureimagegenerator.cpp
+++ b/gm/pictureimagegenerator.cpp
@@ -9,6 +9,7 @@
 #include "sk_tool_utils.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkFontPriv.h"
 #include "SkGradientShader.h"
 #include "SkImageGenerator.h"
 #include "SkPaint.h"
@@ -16,6 +17,7 @@
 #include "SkPathOps.h"
 #include "SkPicture.h"
 #include "SkPictureRecorder.h"
+#include "SkTextUtils.h"
 
 static void draw_vector_logo(SkCanvas* canvas, const SkRect& viewBox) {
     constexpr char kSkiaStr[] = "SKIA";
@@ -25,20 +27,21 @@
 
     SkPaint paint;
     paint.setAntiAlias(true);
-    paint.setSubpixelText(true);
-    paint.setFakeBoldText(true);
-    sk_tool_utils::set_portable_typeface(&paint);
+
+    SkFont font(sk_tool_utils::create_portable_typeface());
+    font.setSubpixel(true);
+    font.setEmbolden(true);
 
     SkPath path;
     SkRect iBox, skiBox, skiaBox;
-    paint.getTextPath("SKI", 3, 0, 0, &path);
+    SkTextUtils::GetPath("SKI", 3, kUTF8_SkTextEncoding, 0, 0, font, &path);
     TightBounds(path, &skiBox);
-    paint.getTextPath("I", 1, 0, 0, &path);
+    SkTextUtils::GetPath("I", 1, kUTF8_SkTextEncoding, 0, 0, font, &path);
     TightBounds(path, &iBox);
     iBox.offsetTo(skiBox.fRight - iBox.width(), iBox.fTop);
 
     const size_t textLen = strlen(kSkiaStr);
-    paint.getTextPath(kSkiaStr, textLen, 0, 0, &path);
+    SkTextUtils::GetPath(kSkiaStr, textLen, kUTF8_SkTextEncoding, 0, 0, font, &path);
     TightBounds(path, &skiaBox);
     skiaBox.outset(0, 2 * iBox.width() * (kVerticalSpacing + 1));
 
@@ -90,7 +93,7 @@
     SkASSERT(SK_ARRAY_COUNT(pos2) == SK_ARRAY_COUNT(colors2));
     paint.setShader(SkGradientShader::MakeLinear(pts2, colors2, pos2, SK_ARRAY_COUNT(pos2),
                                                  SkShader::kClamp_TileMode));
-    canvas->drawText(kSkiaStr, textLen, 0, 0, paint);
+    canvas->drawSimpleText(kSkiaStr, textLen, kUTF8_SkTextEncoding, 0, 0, font, paint);
 }
 
 // This GM exercises SkPictureImageGenerator features
diff --git a/gm/scaledemoji.cpp b/gm/scaledemoji.cpp
index 07afe4b..7307a75 100644
--- a/gm/scaledemoji.cpp
+++ b/gm/scaledemoji.cpp
@@ -56,7 +56,9 @@
         canvas->drawColor(SK_ColorGRAY);
 
         SkPaint paint;
-        paint.setTypeface(fEmojiFont.fTypeface);
+        SkFont font(fEmojiFont.fTypeface);
+        font.setEdging(SkFont::Edging::kAlias);
+
         const char* text = fEmojiFont.fText;
 
         // draw text at different point sizes
@@ -65,10 +67,10 @@
         SkFontMetrics metrics;
         SkScalar y = 0;
         for (SkScalar textSize : { 70, 180, 270, 340 }) {
-            paint.setTextSize(textSize);
-            paint.getFontMetrics(&metrics);
+            font.setSize(textSize);
+            font.getMetrics(&metrics);
             y += -metrics.fAscent;
-            canvas->drawString(text, 10, y, paint);
+            canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 10, y, font, paint);
             y += metrics.fDescent + metrics.fLeading;
         }
 
diff --git a/gm/shadertext3.cpp b/gm/shadertext3.cpp
index c3345f2..b6e2613 100644
--- a/gm/shadertext3.cpp
+++ b/gm/shadertext3.cpp
@@ -103,15 +103,16 @@
 
                 SkPaint fillPaint;
                 fillPaint.setAntiAlias(true);
-                sk_tool_utils::set_portable_typeface(&fillPaint);
-                fillPaint.setTextSize(SkIntToScalar(kPointSize));
                 fillPaint.setFilterQuality(kLow_SkFilterQuality);
                 fillPaint.setShader(SkShader::MakeBitmapShader(fBmp, kTileModes[tm0],
                                                                kTileModes[tm1], &localM));
 
-                canvas->drawText(kText, kTextLen, 0, 0, fillPaint);
-                canvas->drawText(kText, kTextLen, 0, 0, outlinePaint);
-                SkScalar w = fillPaint.measureText(kText, kTextLen);
+                SkFont font(sk_tool_utils::create_portable_typeface(), kPointSize);
+
+                canvas->drawSimpleText(kText, kTextLen, kUTF8_SkTextEncoding, 0, 0, font, fillPaint);
+                canvas->drawSimpleText(kText, kTextLen, kUTF8_SkTextEncoding, 0, 0, font,
+                                       outlinePaint);
+                SkScalar w = font.measureText(kText, kTextLen, kUTF8_SkTextEncoding);
                 canvas->translate(w + 10.f, 0.f);
                 ++i;
                 if (!(i % 2)) {
diff --git a/gm/textblob.cpp b/gm/textblob.cpp
index 867e6cd..d22a35c 100644
--- a/gm/textblob.cpp
+++ b/gm/textblob.cpp
@@ -85,13 +85,12 @@
 protected:
     void onOnceBeforeDraw() override {
         fTypeface = sk_tool_utils::create_portable_typeface("serif", SkFontStyle());
-        SkPaint p;
-        p.setTypeface(fTypeface);
+        SkFont font(fTypeface);
         size_t txtLen = strlen(fText);
-        int glyphCount = p.textToGlyphs(fText, txtLen, nullptr);
+        int glyphCount = font.countText(fText, txtLen, kUTF8_SkTextEncoding);
 
         fGlyphs.append(glyphCount);
-        p.textToGlyphs(fText, txtLen, fGlyphs.begin());
+        font.textToGlyphs(fText, txtLen, kUTF8_SkTextEncoding, fGlyphs.begin(), glyphCount);
     }
 
     SkString onShortName() override {
diff --git a/gm/textblobshader.cpp b/gm/textblobshader.cpp
index 779b5b9..3d1b0a5 100644
--- a/gm/textblobshader.cpp
+++ b/gm/textblobshader.cpp
@@ -20,11 +20,10 @@
 class TextBlobShaderGM : public skiagm::GM {
 public:
     TextBlobShaderGM(const char* txt) {
-        SkPaint p;
-        sk_tool_utils::set_portable_typeface(&p);
+        SkFont font(sk_tool_utils::create_portable_typeface());
         size_t txtLen = strlen(txt);
-        fGlyphs.append(p.textToGlyphs(txt, txtLen, nullptr));
-        p.textToGlyphs(txt, txtLen, fGlyphs.begin());
+        fGlyphs.append(font.countText(txt, txtLen, kUTF8_SkTextEncoding));
+        font.textToGlyphs(txt, txtLen, kUTF8_SkTextEncoding, fGlyphs.begin(), fGlyphs.count());
     }
 
 protected:
diff --git a/include/utils/SkTextUtils.h b/include/utils/SkTextUtils.h
index e5919f4..63d8adf 100644
--- a/include/utils/SkTextUtils.h
+++ b/include/utils/SkTextUtils.h
@@ -13,6 +13,8 @@
 #include "SkPaint.h"
 #include "SkString.h"
 
+class SkPath;
+
 class SkTextUtils {
 public:
     enum Align {
@@ -49,6 +51,9 @@
         DrawText(canvas, str.c_str(), str.size(), x, y, paint, align);
     }
 #endif
+
+    static void GetPath(const void* text, size_t length, SkTextEncoding, SkScalar x, SkScalar y,
+                        const SkFont&, SkPath*);
 };
 
 #endif
diff --git a/samplecode/SampleQuadStroker.cpp b/samplecode/SampleQuadStroker.cpp
index 2eb6070..270fdc4 100644
--- a/samplecode/SampleQuadStroker.cpp
+++ b/samplecode/SampleQuadStroker.cpp
@@ -676,10 +676,10 @@
 
         if (fTextButton.fEnabled) {
             path.reset();
-            SkPaint paint;
-            paint.setAntiAlias(true);
-            paint.setTextSize(fTextSize);
-            paint.getTextPath(fText.c_str(), fText.size(), 0, fTextSize, &path);
+            SkFont font;
+            font.setSize(fTextSize);
+            SkTextUtils::GetPath(fText.c_str(), fText.size(), kUTF8_SkTextEncoding,
+                                 0, fTextSize, font, &path);
             setForText();
             draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true);
         }
diff --git a/samplecode/SampleTextEffects.cpp b/samplecode/SampleTextEffects.cpp
index 003d020..aa175eb 100644
--- a/samplecode/SampleTextEffects.cpp
+++ b/samplecode/SampleTextEffects.cpp
@@ -16,6 +16,7 @@
 #include "SkColorPriv.h"
 #include "SkColorFilter.h"
 #include "SkStrokeRec.h"
+#include "SkTextUtils.h"
 #include "SkTypeface.h"
 
 #include "SkGradientShader.h"
@@ -128,13 +129,13 @@
         canvas->drawColor(SK_ColorWHITE);
     }
 
-    void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkPaint& p) {
+    void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkFont& font) {
         SkTDArray<SkPoint> pts;
         auto pe = makepe(fInterp, &pts);
 
         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
         SkPath path, dstPath;
-        p.getTextPath(s.c_str(), s.size(), x, y, &path);
+        SkTextUtils::GetPath(s.c_str(), s.size(), kUTF8_SkTextEncoding, x, y, font, &path);
         pe->filterPath(&dstPath, path, &rec, nullptr);
 
         SkPaint paint;
@@ -150,16 +151,13 @@
         SkScalar x = SkIntToScalar(20);
         SkScalar y = SkIntToScalar(300);
 
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(SkIntToScalar(240));
-        paint.setTypeface(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()));
-        paint.setTypeface(fFace);
+        SkFont font(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()), 240);
 
         SkString str("9");
 
-        canvas->drawString(str, x, y, paint);
-        drawdots(canvas, str, x, y, paint);
+        canvas->drawSimpleText(str.c_str(), str.size(), kUTF8_SkTextEncoding,
+                               x, y, font, SkPaint());
+        drawdots(canvas, str, x, y, font);
 
         if (false) {
             fInterp += fDx;
diff --git a/src/core/SkFontPriv.h b/src/core/SkFontPriv.h
index b6b74d2..14ed3f5 100644
--- a/src/core/SkFontPriv.h
+++ b/src/core/SkFontPriv.h
@@ -12,6 +12,8 @@
 #include "SkMatrix.h"
 #include "SkTypeface.h"
 
+class SkGlyph;
+class SkGlyphCache;
 class SkReadBuffer;
 class SkWriteBuffer;
 
diff --git a/src/utils/SkTextUtils.cpp b/src/utils/SkTextUtils.cpp
index 3ae9b06..3973497 100644
--- a/src/utils/SkTextUtils.cpp
+++ b/src/utils/SkTextUtils.cpp
@@ -5,6 +5,8 @@
  * found in the LICENSE file.
  */
 
+#include "SkFontPriv.h"
+#include "SkPath.h"
 #include "SkTextUtils.h"
 #include "SkTextBlob.h"
 
@@ -22,3 +24,26 @@
     canvas->drawTextBlob(SkTextBlob::MakeFromText(text, size, font, encoding), x, y, paint);
 }
 
+void SkTextUtils::GetPath(const void* text, size_t length, SkTextEncoding encoding,
+                          SkScalar x, SkScalar y, const SkFont& font, SkPath* path) {
+    SkAutoToGlyphs ag(font, text, length, encoding);
+    SkAutoTArray<SkPoint> pos(ag.count());
+    font.getPos(ag.glyphs(), ag.count(), &pos[0], {x, y});
+
+    struct Rec {
+        SkPath* fDst;
+        const SkPoint* fPos;
+    } rec = { path, &pos[0] };
+
+    path->reset();
+    font.getPaths(ag.glyphs(), ag.count(), [](const SkPath* src, const SkMatrix& mx, void* ctx) {
+        Rec* rec = (Rec*)ctx;
+        if (src) {
+            SkMatrix m(mx);
+            m.postTranslate(rec->fPos->fX, rec->fPos->fY);
+            rec->fDst->addPath(*src, m);
+        }
+        rec->fPos += 1;
+    }, &rec);
+}
+