drawText Cleanup, part 2

Change-Id: I6765d623924d12c6eea2c402dd27eade61b73b66
Reviewed-on: https://skia-review.googlesource.com/c/182151
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Auto-Submit: Hal Canary <halcanary@google.com>
diff --git a/gm/hsl.cpp b/gm/hsl.cpp
index a4c9657..03bc3f7 100644
--- a/gm/hsl.cpp
+++ b/gm/hsl.cpp
@@ -145,12 +145,11 @@
 }
 
 DEF_SIMPLE_GM(hsl, canvas, 600, 100) {
-    SkPaint label;
-    sk_tool_utils::set_portable_typeface(&label);
-    label.setAntiAlias(true);
+    SkPaint paint;
+    SkFont font(sk_tool_utils::create_portable_typeface());
 
     const char* comment = "HSL blend modes are correct when you see no circles in the squares.";
-    canvas->drawText(comment, strlen(comment), 10,10, label);
+    canvas->drawString(comment, 10,10, font, paint);
 
     // Just to keep things reaaaal simple, we'll only use opaque colors.
     SkPaint bg, fg;
@@ -180,8 +179,7 @@
             canvas->drawCircle(50,50, 20, ref);
         }
 
-        const char* name = SkBlendMode_Name(test.mode);
-        canvas->drawText(name, strlen(name), 20,90, label);
+        canvas->drawString(SkBlendMode_Name(test.mode), 20, 90, font, paint);
 
         canvas->translate(100,0);
     }
diff --git a/gm/linepaths.cpp b/gm/linepaths.cpp
index 94a2979..e3f386d 100644
--- a/gm/linepaths.cpp
+++ b/gm/linepaths.cpp
@@ -76,17 +76,15 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&titlePaint);
-        titlePaint.setTextSize(15 * SK_Scalar1);
+
+        SkFont font(sk_tool_utils::create_portable_typeface(), 15.0f);
+
         const char titleNoClose[] = "Line Drawn Into Rectangle Clips With "
             "Indicated Style, Fill and Linecaps, with stroke width 10";
         const char titleClose[] = "Line Closed Drawn Into Rectangle Clips With "
             "Indicated Style, Fill and Linecaps, with stroke width 10";
         const char* title = doClose ? titleClose : titleNoClose;
-        canvas->drawString(title,
-                           20 * SK_Scalar1,
-                           20 * SK_Scalar1,
-                           titlePaint);
+        canvas->drawString(title, 20.0f, 20.0f, font, titlePaint);
 
         SkRandom rand;
         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
@@ -122,18 +120,13 @@
 
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
-                    labelPaint.setAntiAlias(true);
-                    sk_tool_utils::set_portable_typeface(&labelPaint);
-                    labelPaint.setTextSize(10 * SK_Scalar1);
-                    canvas->drawString(gStyles[style].fName,
-                                       0, rect.height() + 12 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gFills[fill].fName,
-                                       0, rect.height() + 24 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gCaps[cap].fName,
-                                       0, rect.height() + 36 * SK_Scalar1,
-                                       labelPaint);
+                    font.setSize(10);
+                    canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f,
+                                       font, labelPaint);
+                    canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f,
+                                       font, labelPaint);
+                    canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f,
+                                       font, labelPaint);
                 }
                 canvas->restore();
             }
diff --git a/gm/matrixconvolution.cpp b/gm/matrixconvolution.cpp
index 80ffc6b..24fa578 100644
--- a/gm/matrixconvolution.cpp
+++ b/gm/matrixconvolution.cpp
@@ -34,17 +34,14 @@
         SkCanvas canvas(fBitmap);
         canvas.clear(0x00000000);
         SkPaint paint;
-        paint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
-        paint.setTextSize(SkIntToScalar(180));
-        SkPoint pts[2] = { SkPoint::Make(0, 0),
-                           SkPoint::Make(0, SkIntToScalar(80)) };
-        SkScalar pos[2] = { 0, SkIntToScalar(80) };
+        SkPoint pts[2] = { {0, 0},
+                           {0, 80.0f} };
+        SkScalar pos[2] = { 0, 80.0f };
         paint.setShader(SkGradientShader::MakeLinear(
             pts, fColors, pos, 2, SkShader::kClamp_TileMode));
-        const char* str = "e";
-        canvas.drawString(str, SkIntToScalar(-10), SkIntToScalar(80), paint);
+        SkFont font(sk_tool_utils::create_portable_typeface(), 180.0f);
+        canvas.drawString("e", -10.0f, 80.0f, font, paint);
     }
 
     SkISize onISize() override {
diff --git a/gm/mipmap.cpp b/gm/mipmap.cpp
index 98b766c..7188cd3 100644
--- a/gm/mipmap.cpp
+++ b/gm/mipmap.cpp
@@ -34,10 +34,9 @@
     SkPaint paint;
     const SkRect dst = SkRect::MakeWH(177, 15);
 
-    paint.setTextSize(30);
     SkString str;
     str.printf("scale %g %g", dst.width() / img->width(), dst.height() / img->height());
-//    canvas->drawString(str, 300, 100, paint);
+//    canvas->drawString(str, 300, 100, SkFont(nullptr, 30), paint);
 
     canvas->translate(20, 20);
     for (int i = 0; i < 4; ++i) {
diff --git a/gm/mixedtextblobs.cpp b/gm/mixedtextblobs.cpp
index afdd736..9e83b90 100644
--- a/gm/mixedtextblobs.cpp
+++ b/gm/mixedtextblobs.cpp
@@ -114,8 +114,6 @@
         paint.setColor(SK_ColorBLACK);
         canvas->translate(10, 40);
 
-        paint.setTextSize(40);
-
         // compute the bounds of the text and setup some clips
         SkRect bounds = fBlob->bounds();
 
diff --git a/gm/morphology.cpp b/gm/morphology.cpp
index 99603c1..d21053a 100644
--- a/gm/morphology.cpp
+++ b/gm/morphology.cpp
@@ -29,15 +29,12 @@
         fBitmap.allocN32Pixels(135, 135);
         SkCanvas canvas(fBitmap);
         canvas.clear(0x0);
+
+        SkFont font(sk_tool_utils::create_portable_typeface(), 64.0f);
         SkPaint paint;
-        paint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&paint);
-        const char* str1 = "ABC";
-        const char* str2 = "XYZ";
         paint.setColor(0xFFFFFFFF);
-        paint.setTextSize(64);
-        canvas.drawString(str1, 10, 55, paint);
-        canvas.drawString(str2, 10, 110, paint);
+        canvas.drawString("ABC", 10, 55,  font, paint);
+        canvas.drawString("XYZ", 10, 110, font, paint);
     }
 
     SkISize onISize() override {
diff --git a/gm/p3.cpp b/gm/p3.cpp
index a67ab72..044af53 100644
--- a/gm/p3.cpp
+++ b/gm/p3.cpp
@@ -6,9 +6,11 @@
  */
 
 #include "gm.h"
+
 #include "SkColorSpace.h"
 #include "SkColorSpaceXformSteps.h"
 #include "SkDashPathEffect.h"
+#include "SkFont.h"
 #include "SkGradientShader.h"
 #include "SkString.h"
 
@@ -33,8 +35,8 @@
 static void compare_pixel(const char* label,
                           SkCanvas* canvas, int x, int y,
                           SkColor4f color, SkColorSpace* cs) {
-    SkPaint text;
-    text.setAntiAlias(true);
+    SkPaint paint;
+    SkFont font;
     auto canvas_cs = canvas->imageInfo().refColorSpace();
 
     // I'm not really sure if this makes things easier or harder to follow,
@@ -50,7 +52,7 @@
     bm.allocPixels(SkImageInfo::Make(1,1, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, canvas_cs));
     if (!canvas->readPixels(bm, x,y)) {
         MarkGMGood(canvas, 140,40);
-        canvas->drawString("can't readPixels() on this canvas :(", 100,20, text);
+        canvas->drawString("can't readPixels() on this canvas :(", 100,20, font, paint);
         return;
     }
 
@@ -85,11 +87,11 @@
     };
 
     SkAutoCanvasRestore saveRestore(canvas, true);
-    canvas->drawString(label, 80,20, text);
+    canvas->drawString(label, 80,20, font, paint);
     for (auto l : lines) {
         canvas->translate(0,20);
-        canvas->drawString(l.label,               80,20, text);
-        canvas->drawString(fmt(l.color).c_str(), 140,20, text);
+        canvas->drawString(l.label,               80,20, font, paint);
+        canvas->drawString(fmt(l.color).c_str(), 140,20, font, paint);
     }
 }
 
diff --git a/gm/pictureimagefilter.cpp b/gm/pictureimagefilter.cpp
index 899bbb9..cf8b579 100644
--- a/gm/pictureimagefilter.cpp
+++ b/gm/pictureimagefilter.cpp
@@ -31,12 +31,9 @@
     SkPictureRecorder recorder;
     SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
     SkPaint paint;
-    paint.setAntiAlias(true);
-    sk_tool_utils::set_portable_typeface(&paint);
     paint.setColor(0xFFFFFFFF);
-    paint.setTextSize(SkIntToScalar(96));
-    const char* str = "e";
-    canvas->drawString(str, SkIntToScalar(20), SkIntToScalar(70), paint);
+    SkFont font(sk_tool_utils::create_portable_typeface(), 96.0f);
+    canvas->drawString("e", 20.0f, 70.0f, font, paint);
     return recorder.finishRecordingAsPicture();
 }
 
@@ -46,14 +43,11 @@
     SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
     canvas->clear(SK_ColorTRANSPARENT);
     SkPaint paint;
-    paint.setLCDRenderText(true);   // want LCD
-    paint.setAntiAlias(true);       // need AA for LCD
-    sk_tool_utils::set_portable_typeface(&paint);
     paint.setColor(0xFFFFFFFF);
     // this has to be small enough that it doesn't become a path
-    paint.setTextSize(SkIntToScalar(36));
-    const char* str = "e";
-    canvas->drawString(str, SkIntToScalar(20), SkIntToScalar(70), paint);
+    SkFont font(sk_tool_utils::create_portable_typeface(), 36.0f);
+    font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
+    canvas->drawString("e", 20.0f, 70.0f, font, paint);
     return recorder.finishRecordingAsPicture();
 }
 
diff --git a/gm/pixelsnap.cpp b/gm/pixelsnap.cpp
index 88fa58a..b1373b6 100644
--- a/gm/pixelsnap.cpp
+++ b/gm/pixelsnap.cpp
@@ -41,10 +41,8 @@
 
         SkString offset;
         SkPaint labelPaint;
-        labelPaint.setAntiAlias(true);
         labelPaint.setColor(SK_ColorWHITE);
-        labelPaint.setTextSize(SkIntToScalar(kLabelTextSize));
-        sk_tool_utils::set_portable_typeface(&labelPaint);
+        SkFont font(sk_tool_utils::create_portable_typeface(), SkIntToScalar(kLabelTextSize));
         SkPaint linePaint;
         linePaint.setColor(SK_ColorWHITE);
 
@@ -53,9 +51,8 @@
             canvas->translate(0, SkIntToScalar(kLabelOffsetY));
             for (int i = 0; i <= kSubPixelSteps; ++i) {
                 offset.printf("%d", i);
-                canvas->drawString(offset,
-                                    0, i * kTrans + labelPaint.getTextSize(),
-                                    labelPaint);
+                canvas->drawString(offset, 0, i * kTrans + SkIntToScalar(kLabelTextSize),
+                                   font, labelPaint);
             }
         canvas->restore();
 
@@ -64,9 +61,8 @@
             canvas->translate(SkIntToScalar(kLabelOffsetX), 0);
             for (int i = 0; i <= kSubPixelSteps; ++i) {
                 offset.printf("%d", i);
-                canvas->drawString(offset,
-                                    i * SkIntToScalar(kTrans), labelPaint.getTextSize(),
-                                    labelPaint);
+                canvas->drawString(offset, i * SkIntToScalar(kTrans), SkIntToScalar(kLabelTextSize),
+                                   font, labelPaint);
             }
         canvas->restore();
 
diff --git a/gm/poly2poly.cpp b/gm/poly2poly.cpp
index 7b72aa4..7e79839 100644
--- a/gm/poly2poly.cpp
+++ b/gm/poly2poly.cpp
@@ -38,11 +38,13 @@
     SkPaint     fFillPaint;
     SkPaint     fStrokePaint;
     SkPath      fPath;
+    SkFont      fFont;
 };
 
-SkJSCanvas::SkJSCanvas(SkCanvas* target) : fTarget(target) {
+SkJSCanvas::SkJSCanvas(SkCanvas* target)
+        : fTarget(target)
+        , fFont(sk_tool_utils::create_portable_typeface(), 12) {
     fFillPaint.setAntiAlias(true);
-    sk_tool_utils::set_portable_typeface(&fFillPaint);
     fStrokePaint.setAntiAlias(true);
     fStrokePaint.setStyle(SkPaint::kStroke_Style);
     fStrokePaint.setStrokeWidth(SK_Scalar1);
@@ -74,7 +76,7 @@
 }
 
 void SkJSCanvas::fillText(const char text[], double x, double y) {
-    fTarget->drawString(text, SkDoubleToScalar(x), SkDoubleToScalar(y), fFillPaint);
+    fTarget->drawString(text, SkDoubleToScalar(x), SkDoubleToScalar(y), fFont, fFillPaint);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/gm/quadpaths.cpp b/gm/quadpaths.cpp
index fb10685..82fcd33 100644
--- a/gm/quadpaths.cpp
+++ b/gm/quadpaths.cpp
@@ -84,16 +84,12 @@
         path.fName = "moveTo-quad";
 
         SkPaint titlePaint;
-        titlePaint.setColor(SK_ColorBLACK);
-        titlePaint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&titlePaint);
-        titlePaint.setTextSize(15 * SK_Scalar1);
+        SkFont font(sk_tool_utils::create_portable_typeface(), 15);
+        SkFont labelFont(sk_tool_utils::create_portable_typeface(), 10);
+
         const char title[] = "Quad Drawn Into Rectangle Clips With "
                              "Indicated Style, Fill and Linecaps, with stroke width 10";
-        canvas->drawString(title,
-                           20 * SK_Scalar1,
-                           20 * SK_Scalar1,
-                           titlePaint);
+        canvas->drawString(title, 20.0f, 20.0f, font, titlePaint);
 
         SkRandom rand;
         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
@@ -129,18 +125,12 @@
 
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
-                    labelPaint.setAntiAlias(true);
-                    sk_tool_utils::set_portable_typeface(&labelPaint);
-                    labelPaint.setTextSize(10 * SK_Scalar1);
-                    canvas->drawString(gStyles[style].fName,
-                                       0, rect.height() + 12 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gFills[fill].fName,
-                                       0, rect.height() + 24 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gCaps[cap].fName,
-                                       0, rect.height() + 36 * SK_Scalar1,
-                                       labelPaint);
+                    canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f,
+                                       labelFont, labelPaint);
+                    canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f,
+                                       labelFont, labelPaint);
+                    canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f,
+                                       labelFont, labelPaint);
                 }
                 canvas->restore();
             }
@@ -225,16 +215,11 @@
         path.fName = "moveTo-quad-close";
 
         SkPaint titlePaint;
-        titlePaint.setColor(SK_ColorBLACK);
-        titlePaint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&titlePaint);
-        titlePaint.setTextSize(15 * SK_Scalar1);
+        SkFont font(sk_tool_utils::create_portable_typeface(), 15);
+        SkFont labelFont(sk_tool_utils::create_portable_typeface(), 10);
         const char title[] = "Quad Closed Drawn Into Rectangle Clips With "
                              "Indicated Style, Fill and Linecaps, with stroke width 10";
-        canvas->drawString(title,
-                           20 * SK_Scalar1,
-                           20 * SK_Scalar1,
-                           titlePaint);
+        canvas->drawString(title, 20.0f, 20.0f, font, titlePaint);
 
         SkRandom rand;
         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
@@ -270,18 +255,12 @@
 
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
-                    labelPaint.setAntiAlias(true);
-                    sk_tool_utils::set_portable_typeface(&labelPaint);
-                    labelPaint.setTextSize(10 * SK_Scalar1);
-                    canvas->drawString(gStyles[style].fName,
-                                       0, rect.height() + 12 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gFills[fill].fName,
-                                       0, rect.height() + 24 * SK_Scalar1,
-                                       labelPaint);
-                    canvas->drawString(gCaps[cap].fName,
-                                       0, rect.height() + 36 * SK_Scalar1,
-                                       labelPaint);
+                    canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f,
+                                       labelFont, labelPaint);
+                    canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f,
+                                       labelFont, labelPaint);
+                    canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f,
+                                       labelFont, labelPaint);
                 }
                 canvas->restore();
             }
diff --git a/gm/rectangletexture.cpp b/gm/rectangletexture.cpp
index 4d4e1df..857fecb 100644
--- a/gm/rectangletexture.cpp
+++ b/gm/rectangletexture.cpp
@@ -146,9 +146,8 @@
         SkASSERT(SkToBool(rectImgs[0]) == SkToBool(rectImgs[1]));
         if (!rectImgs[0]) {
             SkPaint paint;
-            paint.setAntiAlias(true);
-            const char* kMsg = "Could not create rectangle texture image.";
-            canvas->drawString(kMsg, 10, 100, paint);
+            SkFont font;
+            canvas->drawString("Could not create rectangle texture image.", 10, 100, font, paint);
             return;
         }
 
diff --git a/gm/samplerstress.cpp b/gm/samplerstress.cpp
index 5f41f3d..2e435a3 100644
--- a/gm/samplerstress.cpp
+++ b/gm/samplerstress.cpp
@@ -95,10 +95,9 @@
         // stipple mask with a round rect soft clip
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextSize(72);
         paint.setShader(fShader);
         paint.setMaskFilter(fMaskFilter);
-        sk_tool_utils::set_portable_typeface(&paint);
+        SkFont font(sk_tool_utils::create_portable_typeface(), 72);
 
         SkRect temp;
         temp.set(SkIntToScalar(115),
@@ -111,9 +110,7 @@
 
         canvas->clipPath(path, true); // AA is on
 
-        canvas->drawString("M",
-                         SkIntToScalar(100), SkIntToScalar(100),
-                         paint);
+        canvas->drawString("M", 100.0f, 100.0f, font, paint);
 
         canvas->restore();
 
@@ -122,13 +119,9 @@
         SkPaint paint2;
         paint2.setColor(SK_ColorBLACK);
         paint2.setAntiAlias(true);
-        paint2.setTextSize(72);
         paint2.setStyle(SkPaint::kStroke_Style);
         paint2.setStrokeWidth(1);
-        sk_tool_utils::set_portable_typeface(&paint2);
-        canvas->drawString("M",
-                         SkIntToScalar(100), SkIntToScalar(100),
-                         paint2);
+        canvas->drawString("M", 100.0f, 100.0f, font, paint2);
 
         paint2.setColor(SK_ColorGRAY);
 
diff --git a/gm/shadertext3.cpp b/gm/shadertext3.cpp
index b6e2613..f28b93a 100644
--- a/gm/shadertext3.cpp
+++ b/gm/shadertext3.cpp
@@ -42,8 +42,6 @@
     const char* fLabel;
 };
 
-constexpr char kText[] = "B";
-constexpr int kTextLen = SK_ARRAY_COUNT(kText) - 1;
 constexpr int kPointSize = 300;
 
 class ShaderText3GM : public GM {
@@ -72,10 +70,8 @@
         bmpPaint.setAlpha(0x80);
         canvas->drawBitmap(fBmp, 5.f, 5.f, &bmpPaint);
 
+        SkFont font(sk_tool_utils::create_portable_typeface(), SkIntToScalar(kPointSize));
         SkPaint outlinePaint;
-        outlinePaint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&outlinePaint);
-        outlinePaint.setTextSize(SkIntToScalar(kPointSize));
         outlinePaint.setStyle(SkPaint::kStroke_Style);
         outlinePaint.setStrokeWidth(0.f);
 
@@ -107,12 +103,10 @@
                 fillPaint.setShader(SkShader::MakeBitmapShader(fBmp, kTileModes[tm0],
                                                                kTileModes[tm1], &localM));
 
-                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);
+                constexpr char kText[] = "B";
+                canvas->drawString(kText, 0, 0, font, fillPaint);
+                canvas->drawString(kText, 0, 0, font, outlinePaint);
+                SkScalar w = font.measureText(kText, strlen(kText), kUTF8_SkTextEncoding);
                 canvas->translate(w + 10.f, 0.f);
                 ++i;
                 if (!(i % 2)) {
diff --git a/gm/simpleaaclip.cpp b/gm/simpleaaclip.cpp
index 36eb5af..c2d64df 100644
--- a/gm/simpleaaclip.cpp
+++ b/gm/simpleaaclip.cpp
@@ -156,15 +156,11 @@
         };
 
         SkPaint textPaint;
-        textPaint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&textPaint);
-        textPaint.setTextSize(SK_Scalar1*24);
+        SkFont font(sk_tool_utils::create_portable_typeface(), 24);
         int xOff = 0;
 
         for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
-            canvas->drawString(gOps[op].fName,
-                             SkIntToScalar(75), SkIntToScalar(50),
-                             textPaint);
+            canvas->drawString(gOps[op].fName, 75.0f, 50.0f, font, textPaint);
 
             if (kAAClip_GeomType == fGeomType) {
                 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
diff --git a/gm/srcmode.cpp b/gm/srcmode.cpp
index 21cf979..f64b1d1 100644
--- a/gm/srcmode.cpp
+++ b/gm/srcmode.cpp
@@ -28,32 +28,30 @@
                                                   SkShader::kClamp_TileMode));
 }
 
-typedef void (*Proc)(SkCanvas*, const SkPaint&);
+typedef void (*Proc)(SkCanvas*, const SkPaint&, const SkFont&);
 
-static void draw_hair(SkCanvas* canvas, const SkPaint& paint) {
+static void draw_hair(SkCanvas* canvas, const SkPaint& paint, const SkFont&) {
     SkPaint p(paint);
     p.setStrokeWidth(0);
     canvas->drawLine(0, 0, W, H, p);
 }
 
-static void draw_thick(SkCanvas* canvas, const SkPaint& paint) {
+static void draw_thick(SkCanvas* canvas, const SkPaint& paint, const SkFont&) {
     SkPaint p(paint);
     p.setStrokeWidth(H/5);
     canvas->drawLine(0, 0, W, H, p);
 }
 
-static void draw_rect(SkCanvas* canvas, const SkPaint& paint) {
+static void draw_rect(SkCanvas* canvas, const SkPaint& paint, const SkFont&) {
     canvas->drawRect(SkRect::MakeWH(W, H), paint);
 }
 
-static void draw_oval(SkCanvas* canvas, const SkPaint& paint) {
+static void draw_oval(SkCanvas* canvas, const SkPaint& paint, const SkFont&) {
     canvas->drawOval(SkRect::MakeWH(W, H), paint);
 }
 
-static void draw_text(SkCanvas* canvas, const SkPaint& paint) {
-    SkPaint p(paint);
-    p.setTextSize(H/4);
-    canvas->drawString("Hamburge", 0, H*2/3, p);
+static void draw_text(SkCanvas* canvas, const SkPaint& paint, const SkFont& font) {
+    canvas->drawString("Hamburge", 0, H*2/3, font, paint);
 }
 
 class SrcModeGM : public skiagm::GM {
@@ -76,7 +74,7 @@
         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
 
         SkPaint paint;
-        sk_tool_utils::set_portable_typeface(&paint);
+        SkFont font(sk_tool_utils::create_portable_typeface(), H/4);
         paint.setColor(0x80F60000);
 
         const Proc procs[] = {
@@ -93,6 +91,7 @@
 
         for (int aa = 0; aa <= 1; ++aa) {
             paint.setAntiAlias(SkToBool(aa));
+            font.setEdging(SkToBool(aa) ? SkFont::Edging::kAntiAlias : SkFont::Edging::kAlias);
             canvas->save();
             for (size_t i = 0; i < SK_ARRAY_COUNT(paintProcs); ++i) {
                 paintProcs[i](&paint);
@@ -100,7 +99,7 @@
                     paint.setBlendMode(modes[x]);
                     canvas->save();
                     for (size_t y = 0; y < SK_ARRAY_COUNT(procs); ++y) {
-                        procs[y](canvas, paint);
+                        procs[y](canvas, paint, font);
                         canvas->translate(0, H * 5 / 4);
                     }
                     canvas->restore();
diff --git a/gm/strokefill.cpp b/gm/strokefill.cpp
index b28b415..a557ab2 100644
--- a/gm/strokefill.cpp
+++ b/gm/strokefill.cpp
@@ -227,22 +227,23 @@
     return path;
 }
 
-static void show_bold(SkCanvas* canvas, const void* text, int len,
-                      SkScalar x, SkScalar y, const SkPaint& paint) {
-        SkPaint p(paint);
-        canvas->drawText(text, len, x, y, p);
-        p.setFakeBoldText(true);
-        canvas->drawText(text, len, x, y + SkIntToScalar(120), p);
+static void show_bold(SkCanvas* canvas, const char* text,
+                      SkScalar x, SkScalar y, const SkPaint& paint, const SkFont& font) {
+        canvas->drawString(text, x, y, font, paint);
+        SkFont f(font);
+        f.setEmbolden(true);
+        canvas->drawString(text, x, y + 120, f, paint);
 }
 
-static void path_bold(SkCanvas* canvas, const SkPath& path, const SkPaint& paint) {
+static void path_bold(SkCanvas* canvas, const SkPath& path,
+                      const SkPaint& paint, float textSize) {
         SkPaint p(paint);
         canvas->drawPath(path, p);
         p.setStyle(SkPaint::kStrokeAndFill_Style);
-        SkScalar fakeBoldScale = SkScalarInterpFunc(p.getTextSize(),
+        SkScalar fakeBoldScale = SkScalarInterpFunc(textSize,
                 kStdFakeBoldInterpKeys, kStdFakeBoldInterpValues,
                 kStdFakeBoldInterpLength);
-        SkScalar extra = p.getTextSize() * fakeBoldScale;
+        SkScalar extra = textSize * fakeBoldScale;
         p.setStrokeWidth(extra);
         canvas->save();
         canvas->translate(0, 120);
@@ -255,21 +256,19 @@
         SkScalar x = SkIntToScalar(100);
         SkScalar y = SkIntToScalar(88);
 
+        // use the portable typeface to generically test the fake bold code everywhere
+        // (as long as the freetype option to do the bolding itself isn't enabled)
+        SkFont font(sk_tool_utils::create_portable_typeface("serif", SkFontStyle()), 100);
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextSize(SkIntToScalar(100));
         paint.setStrokeWidth(SkIntToScalar(5));
 
         // use paths instead of text to test the path data on all platforms, since the
         // Mac-specific font may change or is not available everywhere
-        path_bold(canvas, papyrus_hello(), paint);
-        path_bold(canvas, hiragino_maru_gothic_pro_dash(), paint);
+        path_bold(canvas, papyrus_hello(), paint, font.getSize());
+        path_bold(canvas, hiragino_maru_gothic_pro_dash(), paint, font.getSize());
 
-        // use the portable typeface to generically test the fake bold code everywhere
-        // (as long as the freetype option to do the bolding itself isn't enabled)
-        sk_tool_utils::set_portable_typeface(&paint, "serif");
-        const unsigned char hiThere[] = "Hi There";
-        show_bold(canvas, hiThere, SK_ARRAY_COUNT(hiThere), x + SkIntToScalar(430), y, paint);
+        show_bold(canvas, "Hi There", x + SkIntToScalar(430), y, paint, font);
 
         paint.setStyle(SkPaint::kStrokeAndFill_Style);
 
diff --git a/gm/textbloblooper.cpp b/gm/textbloblooper.cpp
index 49ee649..51e8155 100644
--- a/gm/textbloblooper.cpp
+++ b/gm/textbloblooper.cpp
@@ -226,8 +226,6 @@
         SkPaint paint;
         canvas->translate(10, 40);
 
-        paint.setTextSize(40);
-
         SkRect bounds = fBlob->bounds();
 
         int y = 0;
diff --git a/gm/texteffects.cpp b/gm/texteffects.cpp
index 53b0f7f..8fdaf8e 100644
--- a/gm/texteffects.cpp
+++ b/gm/texteffects.cpp
@@ -40,9 +40,7 @@
 
 namespace {
 
-sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const char* text) {
-    const SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
-
+sk_sp<SkTextBlob> MakeFancyBlob(const SkPaint& paint, const SkFont& font, const char* text) {
     const size_t textLen = strlen(text);
     const int glyphCount = font.countText(text, textLen, kUTF8_SkTextEncoding);
     SkAutoTArray<SkGlyphID> glyphs(glyphCount);
@@ -107,14 +105,14 @@
     const SkPoint blobOffset = { 10, 80 };
 
     for (size_t font = 0; font < SK_ARRAY_COUNT(fam); ++font) {
-        sk_tool_utils::set_portable_typeface(&paint, fam[font]);
         for (SkScalar textSize = 100; textSize > 10; textSize -= 20) {
-            paint.setTextSize(textSize);
+            SkFont skFont(
+                    sk_tool_utils::create_portable_typeface(fam[font], SkFontStyle()), textSize);
             const SkScalar uWidth = textSize / 15;
             paint.setStrokeWidth(uWidth);
             paint.setStyle(SkPaint::kFill_Style);
 
-            sk_sp<SkTextBlob> blob = MakeFancyBlob(paint, test);
+            sk_sp<SkTextBlob> blob = MakeFancyBlob(paint, skFont, test);
             canvas->drawTextBlob(blob, blobOffset.x(), blobOffset.y(), paint);
 
             const SkScalar uPos = uWidth;
diff --git a/gm/tilemodes.cpp b/gm/tilemodes.cpp
index be98f8c..fa94deb 100644
--- a/gm/tilemodes.cpp
+++ b/gm/tilemodes.cpp
@@ -79,6 +79,8 @@
     }
 
     void onDraw(SkCanvas* canvas) override {
+        SkPaint textPaint;
+        SkFont font(sk_tool_utils::create_portable_typeface(), 12);
 
         int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
 
@@ -136,14 +138,8 @@
                         x += r.width() * 4 / 3;
                     }
                 }
-                {
-                    SkPaint p;
-                    SkString str;
-                    p.setAntiAlias(true);
-                    sk_tool_utils::set_portable_typeface(&p);
-                    str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
-                    canvas->drawString(str, x, y + r.height() * 2 / 3, p);
-                }
+                canvas->drawString(SkStringPrintf("%s, %s", gConfigNames[i], gFilterNames[j]),
+                                   x, y + r.height() * 2 / 3, font, textPaint);
 
                 y += r.height() * 4 / 3;
             }
diff --git a/gm/tilemodes_scaled.cpp b/gm/tilemodes_scaled.cpp
index 78c7641..9366927 100644
--- a/gm/tilemodes_scaled.cpp
+++ b/gm/tilemodes_scaled.cpp
@@ -77,6 +77,9 @@
     }
 
     void onDraw(SkCanvas* canvas) override {
+        SkPaint textPaint;
+        SkFont font(sk_tool_utils::create_portable_typeface(), 12);
+
         float scale = 32.f/kPOTSize;
 
         int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
@@ -99,7 +102,6 @@
         SkScalar y = SkIntToScalar(24);
         SkScalar x = SkIntToScalar(10)/scale;
 
-        SkFont font(sk_tool_utils::create_portable_typeface());
         for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
             for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                 SkString str;
@@ -138,14 +140,8 @@
                         x += r.width() * 4 / 3;
                     }
                 }
-                {
-                    SkPaint p;
-                    SkString str;
-                    p.setAntiAlias(true);
-                    sk_tool_utils::set_portable_typeface(&p);
-                    str.printf("%s, %s", gColorTypeNames[i], gFilterNames[j]);
-                    canvas->drawString(str, scale*x, scale*(y + r.height() * 2 / 3), p);
-                }
+                canvas->drawString(SkStringPrintf("%s, %s", gColorTypeNames[i], gFilterNames[j]),
+                                   scale * x, scale * (y + r.height() * 2 / 3), font, textPaint);
 
                 y += r.height() * 4 / 3;
             }
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index 9d53c2f..b11d82a 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -43,9 +43,8 @@
     void onDraw(SkCanvas* canvas) override {
         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
+        SkFont font(sk_tool_utils::create_portable_typeface());
         SkPaint labelP;
-        labelP.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&labelP);
 
         constexpr SkColor kSolidColors[] = {
             SK_ColorTRANSPARENT,
@@ -70,9 +69,9 @@
             for (size_t m = 0; m <= (size_t)SkBlendMode::kLastMode; ++m) {
                 SkBlendMode mode = static_cast<SkBlendMode>(m);
                 canvas->drawString(SkBlendMode_Name(mode),
-                                 SkIntToScalar(x),
-                                 SkIntToScalar(y + kSize + 3) + labelP.getTextSize(),
-                                 labelP);
+                                   SkIntToScalar(x),
+                                   SkIntToScalar(y + kSize + 3) + font.getSize(),
+                                   font, labelP);
                 for (size_t c = 0; c < SK_ARRAY_COUNT(kSolidColors); ++c) {
                     SkPaint modePaint;
                     modePaint.setBlendMode(mode);