update docs for new/changed textblob apis

Docs-Preview: https://skia.org/?cl=165944
Bug: skia:2664
Change-Id: Ifcd112cae535501d709bc124848e2425d2ec6e5c
Reviewed-on: https://skia-review.googlesource.com/c/165944
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index acc32f0..7a22330 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -5297,7 +5297,6 @@
         alphabet[i] = 'A' + i;
     }
     SkPaint paint;
-    paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->translate(110, 138);
     canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
 }
@@ -5825,7 +5824,6 @@
             {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
             {0.5f,3.2f} };
     paint.setTextSize(18.f / 30);
-    paint.setTextAlign(SkPaint::kCenter_Align);
     for (int i = 0; i< 10; ++i) {
        char digit = '0' + i;
        canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
diff --git a/docs/SkImageInfo_Reference.bmh b/docs/SkImageInfo_Reference.bmh
index 76749b0..98f15f5 100644
--- a/docs/SkImageInfo_Reference.bmh
+++ b/docs/SkImageInfo_Reference.bmh
@@ -1447,9 +1447,8 @@
    SkImageInfo imageInfo = source.info();
    canvas->translate(0, imageInfo.height());
    SkPaint paint;
-   paint.setTextAlign(SkPaint::kCenter_Align);
    canvas->drawLine(0, 10, imageInfo.width(), 10, paint);
-   canvas->drawString("width", imageInfo.width() / 2, 25, paint);
+   canvas->drawString("width", imageInfo.width() / 2 - 15, 25, paint);
 ##
 
 #SeeAlso height SkBitmap::width SkPixelRef::width SkImage::width SkSurface::width
@@ -1472,9 +1471,8 @@
    canvas->drawBitmap(source, 0, 0);
    SkImageInfo imageInfo = source.info();
    SkPaint paint;
-   paint.setTextAlign(SkPaint::kCenter_Align);
    canvas->drawLine(imageInfo.width() + 10, 0, imageInfo.width() + 10, imageInfo.height(), paint);
-   canvas->drawString("height", imageInfo.width() + 34, imageInfo.height() / 2, paint);
+   canvas->drawString("height", imageInfo.width() + 15, imageInfo.height() / 2, paint);
 ##
 
 #SeeAlso width SkBitmap::height SkPixelRef::height SkImage::height SkSurface::height
@@ -1737,8 +1735,7 @@
         string.printf("%s gamma is %s" "close to sRGB", what, closeToSRGB ? "" : "not ");
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
-        canvas->drawString(string, width / 2, 56, paint);
+        canvas->drawString(string, 20, 56, paint);
     };
     SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };
     SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };
@@ -1900,8 +1897,7 @@
         string.printf("%s gamma is %s" "close to sRGB", what, closeToSRGB ? "" : "not ");
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
-        canvas->drawString(string, width / 2, 56, paint);
+        canvas->drawString(string, 20, 56, paint);
     };
     SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };
     SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };
diff --git a/docs/SkImage_Reference.bmh b/docs/SkImage_Reference.bmh
index 99e4cc3..9285fd4 100644
--- a/docs/SkImage_Reference.bmh
+++ b/docs/SkImage_Reference.bmh
@@ -975,9 +975,8 @@
    canvas->drawImage(image, 0, 0);
    canvas->translate(0, image->height());
    SkPaint paint;
-   paint.setTextAlign(SkPaint::kCenter_Align);
    canvas->drawLine(0, 10, image->width(), 10, paint);
-   canvas->drawString("width", image->width() / 2, 25, paint);
+   canvas->drawString("width", image->width() / 2 - 15, 25, paint);
 ##
 
 #SeeAlso dimensions() height()
@@ -1000,7 +999,6 @@
    canvas->drawImage(image, 0, 0);
    canvas->translate(image->width(), 0);
    SkPaint paint;
-   paint.setTextAlign(SkPaint::kCenter_Align);
    canvas->drawLine(10, 0, 10, image->height(), paint);
    canvas->drawString("height", 34, image->height() / 2, paint);
 ##
@@ -1411,11 +1409,10 @@
     }
     SkPaint paint;
     paint.setAntiAlias(true);
-    paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawImage(image, 0, 0);
-    canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
+    canvas->drawString(label, 30, image->height() / 4, paint);
     canvas->drawString(image->isTextureBacked() ? "is GPU texture" : "not GPU texture",
-                       image->width() / 2, image->height() * 3 / 4, paint);
+                       20, image->height() * 3 / 4, paint);
 };
 sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
 sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
@@ -1458,15 +1455,14 @@
     }
     SkPaint paint;
     paint.setAntiAlias(true);
-    paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawImage(image, 0, 0);
     canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
     if (canvas->getGrContext()) {
         canvas->drawString(image->isValid(canvas->getGrContext()) ? "is valid on GPU" :
-                "not valid on GPU", image->width() / 2, image->height() * 5 / 8, paint);
+                "not valid on GPU", 20, image->height() * 5 / 8, paint);
     }
     canvas->drawString(image->isValid(nullptr) ? "is valid on CPU" :
-            "not valid on CPU", image->width() / 2, image->height() * 7 / 8, paint);
+            "not valid on CPU", 20, image->height() * 7 / 8, paint);
 };
 sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
 sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
@@ -1931,10 +1927,9 @@
         }
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
         sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));
         canvas->drawImage(texture, 0, 0);
-        canvas->drawString(label, texture->width() / 2, texture->height() / 4, paint);
+        canvas->drawString(label, 20, texture->height() / 4, paint);
     };
     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
     GrContext* context = canvas->getGrContext();
@@ -1974,10 +1969,9 @@
         }
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
         sk_sp<SkImage> nonTexture(image->makeNonTextureImage());
         canvas->drawImage(nonTexture, 0, 0);
-        canvas->drawString(label, nonTexture->width() / 2, nonTexture->height() / 4, paint);
+        canvas->drawString(label, 20, nonTexture->height() / 4, paint);
     };
     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
@@ -2017,10 +2011,9 @@
         }
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
         sk_sp<SkImage> raster(image->makeRasterImage());
         canvas->drawImage(raster, 0, 0);
-        canvas->drawString(label, raster->width() / 2, raster->height() / 4, paint);
+        canvas->drawString(label, 20, raster->height() / 4, paint);
     };
     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
@@ -2290,12 +2283,11 @@
         }
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setTextAlign(SkPaint::kCenter_Align);
         canvas->drawImage(image, 0, 0);
-        canvas->drawString(label, image->width() / 2, image->height() / 4, paint);
+        canvas->drawString(label, 30, image->height() / 4, paint);
         canvas->drawString(
                 image->isLazyGenerated() ? "is lazily generated" : "not lazily generated",
-                image->width() / 2, image->height() * 3 / 4, paint);
+                20, image->height() * 3 / 4, paint);
     };
     sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));
     sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,
diff --git a/docs/SkPaint_Reference.bmh b/docs/SkPaint_Reference.bmh
index 878251d..0a0caab 100644
--- a/docs/SkPaint_Reference.bmh
+++ b/docs/SkPaint_Reference.bmh
@@ -3361,65 +3361,31 @@
     #Description
     Each position separately moves the glyph in drawPosText.
     ##
+
+    #Function
+    ###$
+    #include "SkTextUtils.h"
+    $$$#
+    ##
+
     void draw(SkCanvas* canvas) {
         SkPaint paint;
         paint.setTextSize(40);
-        SkPoint position[] = {{100, 50}, {150, 40}};
         for (SkPaint::Align a : { SkPaint::kLeft_Align,
                                   SkPaint::kCenter_Align,
                                   SkPaint::kRight_Align}) {
-            paint.setTextAlign(a);
-            canvas->drawPosText("Aa", 2, position, paint);
+            SkTextUtils::DrawString(canvas, "Aa", 100, 50, paint, a);
             canvas->translate(0, 50);
         }
     }
 ##
 
 #Method Align getTextAlign() const
-
-#In Text_Align
-#Line # returns Align: left, center, or right ##
-    Returns Text_Align.
-    Returns kLeft_Align if Text_Align has not been set.
-
-    #Return  text placement relative to position ##
-
-    #Example
-    SkPaint paint;
-    SkDebugf("kLeft_Align %c= default\n", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');
-
-        #StdOut
-        kLeft_Align == default
-        ##
-    ##
+#Deprecated
 ##
 
 #Method void    setTextAlign(Align align)
-
-#In Text_Align
-#Line # sets Align: left, center, or right ##
-    Sets Text_Align to align.
-    Has no effect if align is an invalid value.
-
-    #Param align  text placement relative to position ##
-
-    #Example
-    #Height 160
-    #Description
-    Text is left-aligned by default, and then set to center. Setting the
-    alignment out of range has no effect.
-    ##
-        void draw(SkCanvas* canvas) {
-            SkPaint paint;
-            paint.setTextSize(40);
-            canvas->drawString("Aa", 100, 50, paint);
-            paint.setTextAlign(SkPaint::kCenter_Align);
-            canvas->drawString("Aa", 100, 100, paint);
-            paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);
-            canvas->drawString("Aa", 100, 150, paint);
-        }
-    ##
-
+#Deprecated
 ##
 
 #Subtopic Text_Align ##
diff --git a/docs/SkPath_Reference.bmh b/docs/SkPath_Reference.bmh
index 1f4cf55..7011ead 100644
--- a/docs/SkPath_Reference.bmh
+++ b/docs/SkPath_Reference.bmh
@@ -178,7 +178,6 @@
     SkPaint rectPaint;
     rectPaint.setAntiAlias(true);
     SkPaint textPaint(rectPaint);
-    textPaint.setTextAlign(SkPaint::kCenter_Align);
     rectPaint.setStyle(SkPaint::kStroke_Style);
     SkPaint arrowPaint(rectPaint);
     SkPath arrowPath;
@@ -600,7 +599,6 @@
    canvas->drawLine({0, 50}, {120, 50}, strokePaint);
    SkPaint textPaint;
    textPaint.setAntiAlias(true);
-   textPaint.setTextAlign(SkPaint::kCenter_Align);
    SkScalar textHPos[] = { 10, 30, 60, 90, 110 };
    canvas->drawPosTextH("01210", 5, textHPos, 48, textPaint);
    textPaint.setTextSize(18);
@@ -3002,13 +3000,9 @@
     SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };
     canvas->drawLine(center, arcStart, tangentPaint);
     canvas->drawPath(path, arcPaint);
-    textPaint.setTextAlign(SkPaint::kRight_Align);
     canvas->drawString("(x0, y0)", pts[0].fX - 5, pts[0].fY, textPaint);
-    textPaint.setTextAlign(SkPaint::kLeft_Align);
     canvas->drawString("(x1, y1)", pts[1].fX + 5, pts[1].fY, textPaint);
-    textPaint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawString("(x2, y2)", pts[2].fX, pts[2].fY + 15, textPaint);
-    textPaint.setTextAlign(SkPaint::kRight_Align);
     canvas->drawString("radius", center.fX + 15, center.fY + 25, textPaint);
     canvas->drawString("radius", center.fX - 3, center.fY - 16, textPaint);
 }
@@ -3046,13 +3040,9 @@
     SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };
     canvas->drawLine(center, arcStart, tangentPaint);
     canvas->drawPath(path, arcPaint);
-    textPaint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawString("(x0, y0)", pts[0].fX, pts[0].fY - 7, textPaint);
-    textPaint.setTextAlign(SkPaint::kLeft_Align);
     canvas->drawString("(x1, y1)", pts[1].fX + 5, pts[1].fY, textPaint);
-    textPaint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawString("(x2, y2)", pts[2].fX, pts[2].fY + 15, textPaint);
-    textPaint.setTextAlign(SkPaint::kRight_Align);
     canvas->drawString("radius", center.fX + 15, center.fY + 25, textPaint);
     canvas->drawString("radius", center.fX - 5, center.fY - 20, textPaint);
 }
@@ -3929,7 +3919,6 @@
     SkPaint ovalPaint;
     ovalPaint.setAntiAlias(true);
     SkPaint textPaint(ovalPaint);
-    textPaint.setTextAlign(SkPaint::kCenter_Align);
     ovalPaint.setStyle(SkPaint::kStroke_Style);
     SkPaint arrowPaint(ovalPaint);
     SkPath arrowPath;
diff --git a/docs/SkRRect_Reference.bmh b/docs/SkRRect_Reference.bmh
index 674b394..c5f3839 100644
--- a/docs/SkRRect_Reference.bmh
+++ b/docs/SkRRect_Reference.bmh
@@ -249,7 +249,6 @@
         SkPaint paint;

         paint.setAntiAlias(true);

         const char* typeStr[] = { "empty", "rect", "oval", "simple", "nine patch", "complex" };

-        paint.setTextAlign(SkPaint::kCenter_Align);

         canvas->drawString(typeStr[(int) rrect.type()], rect.centerX(), rect.bottom() + 20, paint);

         paint.setStyle(SkPaint::kStroke_Style);       

         canvas->drawRRect(rrect, paint);

@@ -346,7 +345,6 @@
 #Height 100
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 10, 5);

     canvas->drawRRect(rrect, paint);

@@ -375,7 +373,6 @@
 #Height 100
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});

     canvas->drawRRect(rrect, paint);

@@ -412,7 +409,6 @@
 ##
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30);

     canvas->drawRRect(rrect, paint);

@@ -443,7 +439,6 @@
 #Height 100
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkVector radii[] = {{40, 30}, {40, 30}, {40, 30}, {40, 30}};

     SkRRect rrect;

@@ -477,7 +472,6 @@
 #Height 100
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkVector radii[] = {{20, 30}, {40, 30}, {40, 30}, {20, 30}};

     SkRRect rrect;

@@ -513,7 +507,6 @@
 #Height 100
     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     paint.setTextSize(16);

     SkVector radii[] = {{25, 30}, {40, 30}, {40, 30}, {20, 30}};

     SkRRect rrect;

@@ -605,7 +598,6 @@
     auto drawDetails = [=](const SkRRect& rrect) {

         SkPaint paint;

         paint.setAntiAlias(true);

-        paint.setTextAlign(SkPaint::kCenter_Align);

         paint.setTextSize(12);

         canvas->drawRRect(rrect, paint);

         SkVector corner = rrect.getSimpleRadii();

@@ -1380,7 +1372,6 @@
     test.inset(10, 10);

     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     canvas->drawString(rrect.contains(test) ? "contains" : "does not contain", 55, 100, paint);

     canvas->drawString(oval.contains(test) ? "contains" : "does not contain", 185, 100, paint);    

     paint.setStyle(SkPaint::kStroke_Style);

@@ -1414,7 +1405,6 @@
     *((float*) &corrupt) = 120;

     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     canvas->drawString(rrect.isValid() ? "is valid" : "is corrupted", 55, 100, paint);

     canvas->drawString(corrupt.isValid() ? "is valid" : "is corrupted", 185, 100, paint);    

     paint.setStyle(SkPaint::kStroke_Style);

@@ -1458,7 +1448,6 @@
     copy.readFromMemory(storage, sizeof(storage));

     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     canvas->drawString("rrect", 55, 100, paint);

     canvas->drawString("copy", 185, 100, paint);    

     paint.setStyle(SkPaint::kStroke_Style);

@@ -1498,7 +1487,6 @@
     copy.readFromMemory(storage, sizeof(storage));

     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     canvas->drawString("rrect", 55, 100, paint);

     canvas->drawString("copy", 185, 100, paint);    

     paint.setStyle(SkPaint::kStroke_Style);

@@ -1540,7 +1528,6 @@
     bool success = rrect.transform(matrix, &transformed);

     SkPaint paint;

     paint.setAntiAlias(true);

-    paint.setTextAlign(SkPaint::kCenter_Align);

     canvas->drawString("rrect", 55, 100, paint);

     canvas->drawString(success ? "transformed" : "transform failed", 185, 100, paint);    

     paint.setStyle(SkPaint::kStroke_Style);

diff --git a/docs/SkRegion_Reference.bmh b/docs/SkRegion_Reference.bmh
index 562dfa2..6158cfa 100644
--- a/docs/SkRegion_Reference.bmh
+++ b/docs/SkRegion_Reference.bmh
@@ -1618,7 +1618,6 @@
     const char* labels[] = {"difference", "intersect", "union", "xor", "reverse diff", "replace"};

     int index = 0;

     SkPaint paint;

-    paint.setTextAlign(SkPaint::kCenter_Align);

     for (auto op : { SkRegion::kDifference_Op, SkRegion::kIntersect_Op, SkRegion::kUnion_Op,

                      SkRegion::kXOR_Op, SkRegion::kReverseDifference_Op, SkRegion::kReplace_Op } ) {

         SkRegion target({10, 10, 60, 60});

diff --git a/docs/SkTextBlobBuilder_Reference.bmh b/docs/SkTextBlobBuilder_Reference.bmh
index e3ee47a..386d720 100644
--- a/docs/SkTextBlobBuilder_Reference.bmh
+++ b/docs/SkTextBlobBuilder_Reference.bmh
@@ -70,8 +70,8 @@
 #Return empty Text_Blob_Builder ##
 
 #Example
-    SkTextBlobBuilder builder;

-    sk_sp<SkTextBlob> blob = builder.make();

+    SkTextBlobBuilder builder;
+    sk_sp<SkTextBlob> blob = builder.make();
     SkDebugf("blob " "%s" " nullptr", blob == nullptr ? "equals" : "does not equal");
 #StdOut
 blob equals nullptr
@@ -112,21 +112,21 @@
 #Return Text_Blob or nullptr ##
 
 #Example
-    SkTextBlobBuilder builder;

-    sk_sp<SkTextBlob> blob = builder.make();

-    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");

-    SkPaint paint;

-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    paint.textToGlyphs("x", 1, builder.allocRun(paint, 1, 20, 20).glyphs);

-    blob = builder.make();

-    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");

-    blob = builder.make();

-    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");

-#StdOut

-blob equals nullptr

-blob does not equal nullptr

-blob equals nullptr

-##

+    SkTextBlobBuilder builder;
+    sk_sp<SkTextBlob> blob = builder.make();
+    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");
+    SkPaint paint;
+    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    paint.textToGlyphs("x", 1, builder.allocRun(paint, 1, 20, 20).glyphs);
+    blob = builder.make();
+    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");
+    blob = builder.make();
+    SkDebugf("blob " "%s" " nullptr\n", blob == nullptr ? "equals" : "does not equal");
+#StdOut
+blob equals nullptr
+blob does not equal nullptr
+blob equals nullptr
+##
 ##
 
 #SeeAlso SkTextBlob::MakeFromText
@@ -164,12 +164,12 @@
 
 #Example
 #Height 60
-    SkTextBlobBuilder builder;

-    SkPaint paint, glyphPaint;

-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    const SkTextBlobBuilder::RunBuffer& run = builder.allocRun(glyphPaint, 5, 20, 20);

-    paint.textToGlyphs("hello", 5, run.glyphs);

-    canvas->drawRect({20, 20, 30, 30}, paint);

+    SkTextBlobBuilder builder;
+    SkPaint paint, glyphPaint;
+    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRun(glyphPaint, 5, 20, 20);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    canvas->drawRect({20, 20, 30, 30}, paint);
     canvas->drawTextBlob(builder.make(), 20, 20, paint);    
 ##
 
@@ -179,6 +179,50 @@
 
 # ------------------------------------------------------------------------------
 
+#Method const RunBuffer& allocRun(const SkFont& font, int count, SkScalar x, SkScalar y,
+const SkRect* bounds = nullptr)
+#In Allocator
+#Line # returns writable glyph buffer at Point ##
+
+Returns run with storage for Glyphs. Caller must write count Glyphs to
+RunBuffer.glyphs before next call to FontBlobBuilder.
+
+RunBuffer.utf8text, and RunBuffer.clusters should be ignored.
+
+Glyphs share Paint_Font_Metrics in font, including: #paint_font_metrics#.
+
+Glyphs are positioned on a baseline at (x, y), using font Paint_Font_Metrics to
+determine their relative placement.
+
+bounds defines an optional bounding box, used to suppress drawing when Text_Blob
+bounds does not intersect Surface bounds. If bounds is nullptr, Text_Blob bounds
+is computed from (x, y) and RunBuffer.glyphs Paint_Font_Metrics.
+
+#Param font  Font used for this run ##
+#Param count  number of glyphs ##
+#Param x  horizontal offset within the blob ##
+#Param y  vertical offset within the blob ##
+#Param bounds  optional run bounding box ##
+
+#Return writable glyph buffer ##
+
+#Example
+#Height 60
+    SkTextBlobBuilder builder;
+    SkFont font;
+    SkPaint paint;
+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRun(font, 5, 20, 20);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    canvas->drawRect({20, 20, 30, 30}, paint);
+    canvas->drawTextBlob(builder.make(), 20, 20, paint);
+##
+
+#SeeAlso allocRunPosH allocRunPos
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
 #Method const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
                                   const SkRect* bounds = nullptr)
 #In Allocator
@@ -208,14 +252,59 @@
 
 #Example
 #Height 60
-    SkTextBlobBuilder builder;

-    SkPaint paint, glyphPaint;

-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPosH(glyphPaint, 5, 20);

-    paint.textToGlyphs("hello", 5, run.glyphs);

-    SkScalar positions[] = {0, 10, 20, 40, 80};

-    memcpy(run.pos, positions, sizeof(positions));

-    canvas->drawTextBlob(builder.make(), 20, 20, paint);    

+    SkTextBlobBuilder builder;
+    SkPaint paint, glyphPaint;
+    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPosH(glyphPaint, 5, 20);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    SkScalar positions[] = {0, 10, 20, 40, 80};
+    memcpy(run.pos, positions, sizeof(positions));
+    canvas->drawTextBlob(builder.make(), 20, 20, paint);    
+##
+
+#SeeAlso allocRunPos allocRun
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method const RunBuffer& allocRunPosH(const SkFont& font, int count, SkScalar y,
+                                      const SkRect* bounds = nullptr)
+#In Allocator
+#Line # returns writable glyph and x-axis position buffers ##
+
+Returns run with storage for Glyphs and positions along baseline. Caller must
+write count Glyphs to RunBuffer.glyphs, and count Scalars to RunBuffer.pos;
+before next call to FontBlobBuilder.
+
+RunBuffer.utf8text, and RunBuffer.clusters should be ignored.
+
+Glyphs share Paint_Font_Metrics in font, including: #paint_font_metrics#.
+
+Glyphs are positioned on a baseline at y, using x-axis positions written by
+caller to RunBuffer.pos.
+
+bounds defines an optional bounding box, used to suppress drawing when Text_Blob
+bounds does not intersect Surface bounds. If bounds is nullptr, Text_Blob bounds
+is computed from y, RunBuffer.pos, and RunBuffer.glyphs Paint_Font_Metrics.
+
+#Param font  Font used for this run ##
+#Param count  number of Glyphs ##
+#Param y  vertical offset within the blob ##
+#Param bounds  optional run bounding box ##
+
+#Return writable glyph buffer and x-axis position buffer ##
+
+#Example
+#Height 60
+    SkTextBlobBuilder builder;
+    SkPaint paint;
+    SkFont font;
+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPosH(font, 5, 20);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    SkScalar positions[] = {0, 10, 20, 40, 80};
+    memcpy(run.pos, positions, sizeof(positions));
+    canvas->drawTextBlob(builder.make(), 20, 20, paint);
 ##
 
 #SeeAlso allocRunPos allocRun
@@ -252,14 +341,58 @@
 
 #Example
 #Height 90
-    SkTextBlobBuilder builder;

-    SkPaint paint, glyphPaint;

-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(glyphPaint, 5);

-    paint.textToGlyphs("hello", 5, run.glyphs);

-    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};

-    memcpy(run.pos, positions, sizeof(positions));

-    canvas->drawTextBlob(builder.make(), 20, 20, paint);    

+    SkTextBlobBuilder builder;
+    SkPaint paint, font;
+    font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(font, 5);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};
+    memcpy(run.pos, positions, sizeof(positions));
+    canvas->drawTextBlob(builder.make(), 20, 20, paint);    
+##
+
+#SeeAlso allocRunPosH allocRun
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
+#Method const RunBuffer& allocRunPos(const SkFont& font, int count,
+                                     const SkRect* bounds = nullptr)
+#In Allocator
+#Line # returns writable glyph and Point buffers ##
+
+Returns run with storage for Glyphs and Point positions. Caller must
+write count Glyphs to RunBuffer.glyphs, and count Points to RunBuffer.pos;
+before next call to FontBlobBuilder.
+
+RunBuffer.utf8text, and RunBuffer.clusters should be ignored.
+
+Glyphs share Paint_Font_Metrics in font, including: #paint_font_metrics#.
+
+Glyphs are positioned using Points written by caller to RunBuffer.pos, using
+two Scalar values for each Point.
+
+bounds defines an optional bounding box, used to suppress drawing when Text_Blob
+bounds does not intersect Surface bounds. If bounds is nullptr, Text_Blob bounds
+is computed from RunBuffer.pos, and RunBuffer.glyphs Paint_Font_Metrics.
+
+#Param font  Font used for this run ##
+#Param count  number of Glyphs ##
+#Param bounds  optional run bounding box ##
+
+#Return writable glyph buffer and Point buffer ##
+
+#Example
+#Height 90
+    SkTextBlobBuilder builder;
+    SkPaint paint;
+    SkFont font;
+    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(font, 5);
+    paint.textToGlyphs("hello", 5, run.glyphs);
+    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};
+    memcpy(run.pos, positions, sizeof(positions));
+    canvas->drawTextBlob(builder.make(), 20, 20, paint);
 ##
 
 #SeeAlso allocRunPosH allocRun
diff --git a/docs/SkTextBlob_Reference.bmh b/docs/SkTextBlob_Reference.bmh
index 1abe822..a3f1dd5 100644
--- a/docs/SkTextBlob_Reference.bmh
+++ b/docs/SkTextBlob_Reference.bmh
@@ -25,28 +25,28 @@
 
 #Example
 #Height 70
-    SkTextBlobBuilder textBlobBuilder;

-    const char bunny[] = "/(^x^)\\";

-    const int len = sizeof(bunny) - 1;

-    uint16_t glyphs[len];

-    SkPaint paint;

-    paint.textToGlyphs(bunny, len, glyphs);

-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    int runs[] = { 3, 1, 3 };

-    SkPoint textPos = { 20, 50 };

-    int glyphIndex = 0;

-    for (auto runLen : runs) {

-        paint.setTextSize(1 == runLen ? 20 : 50);

-        const SkTextBlobBuilder::RunBuffer& run =

-                textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);

-        memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);

-        textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);

-        glyphIndex += runLen;

-    }

-    sk_sp<const SkTextBlob> blob = textBlobBuilder.make();

-    paint.reset();

-    canvas->drawTextBlob(blob.get(), 0, 0, paint);

-    paint.setStyle(SkPaint::kStroke_Style);

+    SkTextBlobBuilder textBlobBuilder;
+    const char bunny[] = "/(^x^)\\";
+    const int len = sizeof(bunny) - 1;
+    uint16_t glyphs[len];
+    SkPaint paint;
+    paint.textToGlyphs(bunny, len, glyphs);
+    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    int runs[] = { 3, 1, 3 };
+    SkPoint textPos = { 20, 50 };
+    int glyphIndex = 0;
+    for (auto runLen : runs) {
+        paint.setTextSize(1 == runLen ? 20 : 50);
+        const SkTextBlobBuilder::RunBuffer& run =
+                textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
+        memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
+        textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
+        glyphIndex += runLen;
+    }
+    sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
+    paint.reset();
+    canvas->drawTextBlob(blob.get(), 0, 0, paint);
+    paint.setStyle(SkPaint::kStroke_Style);
     canvas->drawRect(blob->bounds(), paint);
 ##
 
@@ -65,32 +65,32 @@
 #Return identifier for Text_Blob ##
 
 #Example
-for (int index = 0; index < 2; ++index) {

-    SkTextBlobBuilder textBlobBuilder;

-    const char bunny[] = "/(^x^)\\";

-    const int len = sizeof(bunny) - 1;

-    uint16_t glyphs[len];

-    SkPaint paint;

-    paint.textToGlyphs(bunny, len, glyphs);

-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

-    paint.setTextScaleX(0.5);

-    int runs[] = { 3, 1, 3 };

-    SkPoint textPos = { 20, 50 };

-    int glyphIndex = 0;

-    for (auto runLen : runs) {

-        paint.setTextSize(1 == runLen ? 20 : 50);

-        const SkTextBlobBuilder::RunBuffer& run =

-                textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);

-        memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);

-        textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);

-        glyphIndex += runLen;

-    }

-    sk_sp<const SkTextBlob> blob = textBlobBuilder.make();

-    paint.reset();

-    canvas->drawTextBlob(blob.get(), 0, 0, paint);

-    std::string id = "unique ID:" + std::to_string(blob->uniqueID());

-    canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint);

-    canvas->translate(blob->bounds().fRight + 10, 0);

+for (int index = 0; index < 2; ++index) {
+    SkTextBlobBuilder textBlobBuilder;
+    const char bunny[] = "/(^x^)\\";
+    const int len = sizeof(bunny) - 1;
+    uint16_t glyphs[len];
+    SkPaint paint;
+    paint.textToGlyphs(bunny, len, glyphs);
+    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    paint.setTextScaleX(0.5);
+    int runs[] = { 3, 1, 3 };
+    SkPoint textPos = { 20, 50 };
+    int glyphIndex = 0;
+    for (auto runLen : runs) {
+        paint.setTextSize(1 == runLen ? 20 : 50);
+        const SkTextBlobBuilder::RunBuffer& run =
+                textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
+        memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
+        textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
+        glyphIndex += runLen;
+    }
+    sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
+    paint.reset();
+    canvas->drawTextBlob(blob.get(), 0, 0, paint);
+    std::string id = "unique ID:" + std::to_string(blob->uniqueID());
+    canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint);
+    canvas->translate(blob->bounds().fRight + 10, 0);
 }
 ##
 
@@ -100,32 +100,33 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static sk_sp<SkTextBlob> MakeFromText(
-            const void* text, size_t byteLength, const SkPaint& paint)
+#Method static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
+                                          SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding)
 #In Constructors
 #Line # constructs Text_Blob with one run ##
 
 Creates Text_Blob with a single run. text meaning depends on Paint_Text_Encoding;
 by default, text is encoded as UTF-8.
 
-paint contains attributes used to define the run text: #paint_font_metrics#.
+font contains attributes used to define the run text: #paint_font_metrics#.
 
 #Param text character code points or Glyphs drawn ##
 #Param  byteLength   byte length of text array ##
-#Param  paint    text size, typeface, text scale, and so on, used to draw ##
+#Param  font    text size, typeface, text scale, and so on, used to draw ##
+#Param  encoding  one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
+                          kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
+##
 
 #Return Text_Blob constructed from one run ##
 
 #Example
 #Height 24
-    SkPaint blobPaint;
-    blobPaint.setColor(SK_ColorRED); // ignored
-    blobPaint.setTextSize(24);  // respected
-    blobPaint.setAntiAlias(true); // ignored
-    SkPaint canvasPaint = blobPaint;
+    SkFont font;
+    font.setSize(24);
+    SkPaint canvasPaint;
     canvasPaint.setColor(SK_ColorBLUE); // respected
     canvasPaint.setTextSize(2); // ignored
-    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint);
+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, font);
     canvas->drawTextBlob(blob, 20, 20, canvasPaint);
 ##
 
@@ -135,30 +136,32 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkPaint& paint)
+#Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
+             SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding)
 #In Constructors
 #Line # constructs Text_Blob with one run ##
 
 Creates Text_Blob with a single run. string meaning depends on Paint_Text_Encoding;
 by default, string is encoded as UTF-8.
 
-paint contains Paint_Font_Metrics used to define the run text: #paint_font_metrics#.
+font contains Paint_Font_Metrics used to define the run text: #paint_font_metrics#.
 
 #Param string character code points or Glyphs drawn ##
-#Param  paint    text size, typeface, text scale, and so on, used to draw ##
+#Param  font    text size, typeface, text scale, and so on, used to draw ##
+#Param  encoding  one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
+                          kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
+##
 
 #Return Text_Blob constructed from one run ##
 
 #Example
 #Height 24
-    SkPaint blobPaint;
-    blobPaint.setColor(SK_ColorRED); // ignored
-    blobPaint.setTextSize(24);  // respected
-    blobPaint.setAntiAlias(true); // ignored
-    SkPaint canvasPaint = blobPaint;
+    SkFont font;
+    font.setSize(24);
+    SkPaint canvasPaint;
     canvasPaint.setColor(SK_ColorBLUE); // respected
     canvasPaint.setTextSize(2); // ignored
-    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", blobPaint);
+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", font);
     canvas->drawTextBlob(blob, 20, 20, canvasPaint);
 ##
 
@@ -195,14 +198,14 @@
 #include "SkSerialProcs.h"
 $$
 $$$#
-    SkPaint blobPaint;

-    blobPaint.setTextSize(24);

-    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint);

-    char storage[2048];

-    size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage));

-    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs());

-    canvas->drawTextBlob(copy, 20, 20, SkPaint());

-    std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used);

+    SkFont blobFont;

+    blobFont.setSize(24);

+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);

+    char storage[2048];
+    size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage));
+    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs());
+    canvas->drawTextBlob(copy, 20, 20, SkPaint());
+    std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used);
     canvas->drawString(usage.c_str(), 20, 40, SkPaint());
 ##
 
@@ -234,11 +237,11 @@
 #include "SkSerialProcs.h"
 $$
 $$$#
-    SkPaint blobPaint;

-    blobPaint.setTextSize(24);

-    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobPaint);

-    sk_sp<SkData> data = blob->serialize(SkSerialProcs());

-    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());

+    SkFont blobFont;

+    blobFont.setSize(24);

+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);
+    sk_sp<SkData> data = blob->serialize(SkSerialProcs());
+    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
     canvas->drawTextBlob(copy, 20, 20, SkPaint());
 ##
 
@@ -278,14 +281,15 @@
 #include "SkSerialProcs.h"
 $$
 $$$#
-    SkPaint blobPaint;

-    blobPaint.setTextSize(24);

-    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobPaint);

+    SkFont blobFont;

+    blobFont.setSize(24);

+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobFont);

     sk_sp<SkData> data = blob->serialize(SkSerialProcs());

     uint16_t glyphs[6];

-    blobPaint.textToGlyphs("Hacker", 6, glyphs);

-    memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));

-    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());

+    SkPaint blobPaint;

+    blobPaint.textToGlyphs("Hacker", 6, glyphs);
+    memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));
+    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
     canvas->drawTextBlob(copy, 20, 20, SkPaint());
 ##
 
diff --git a/docs/illustrations.bmh b/docs/illustrations.bmh
index bda34b3..67eb6c97 100644
--- a/docs/illustrations.bmh
+++ b/docs/illustrations.bmh
@@ -4,16 +4,21 @@
 #Example
 #Width 415
 #Height 250
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("16-bit word", 5 + 20 * 8, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 1.5f, 137, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 6.5f, 187, paint);
+    SkTextUtils::DrawString(canvas, "16-bit word", 5 + 20 * 8, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 1.5f, 137, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 6.5f, 187, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -25,7 +30,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -33,7 +38,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -58,14 +63,19 @@
 #Example
 #Width 415
 #Height 250
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("16-bit word", 5 + 20 * 8, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
+    SkTextUtils::DrawString(canvas, "16-bit word", 5 + 20 * 8, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -77,7 +87,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -85,7 +95,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -108,14 +118,19 @@
 #Example
 #Width 812
 #Height 365
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
+    SkTextUtils::DrawString(canvas, "32-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -127,7 +142,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -135,7 +150,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -160,14 +175,19 @@
 #Example
 #Width 812
 #Height 365
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
+    SkTextUtils::DrawString(canvas, "32-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -179,7 +199,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -187,7 +207,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -212,14 +232,19 @@
 #Example
 #Width 812
 #Height 365
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
+    SkTextUtils::DrawString(canvas, "32-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -231,7 +256,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -239,7 +264,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -264,20 +289,25 @@
 #Example
 #Width 812
 #Height 380
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 4, 137, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 3, 187, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 7, 187, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 2, 237, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 6, 237, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 5, 287, paint);
+    SkTextUtils::DrawString(canvas, "32-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 4, 137, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 3, 187, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 7, 187, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 2, 237, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 6, 237, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 5, 287, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -289,7 +319,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -297,7 +327,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -327,20 +357,25 @@
 #Example
 #Width 812
 #Height 380
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 4, 137, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 3, 187, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 7, 187, paint);
-    canvas->drawString("(low bits)", 5 + 20 * 2, 237, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 6, 237, paint);
-    canvas->drawString("(high bits)", 5 + 20 * 5, 287, paint);
+    SkTextUtils::DrawString(canvas, "32-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 4, 137, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 3, 187, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 7, 187, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 2, 237, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 6, 237, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 5, 287, paint, SkPaint::kCenter_Align);
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
         p.setColor(SK_ColorRED);
@@ -352,7 +387,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -360,7 +395,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -390,17 +425,22 @@
 #Example
 #Width 812
 #Height 685
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("64-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 135, paint);
+    SkTextUtils::DrawString(canvas, "64-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 135, paint, SkPaint::kCenter_Align);
     for (int i = 0; i < 4; ++i) {
-        canvas->drawString("(low bits)", 5 + 20 * 4, 187 + i * 100, paint);
-        canvas->drawString("(high bits)", 5 + 20 * 4, 237 + i * 100, paint);
+        SkTextUtils::DrawString(canvas, "(low bits)", 5 + 20 * 4, 187 + i * 100, paint, SkPaint::kCenter_Align);
+        SkTextUtils::DrawString(canvas, "(high bits)", 5 + 20 * 4, 237 + i * 100, paint, SkPaint::kCenter_Align);
     }
     auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {
         SkPaint p(paint);
@@ -413,7 +453,7 @@
                 int a = width - e[i];
                 if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {
                     char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};
-                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);
                     break;
                 }
             }
@@ -421,7 +461,7 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);
         }
         p.setStyle(SkPaint::kStroke_Style);
         for (int i = 0; i <= count; ++i) {
@@ -453,17 +493,22 @@
 #Example
 #Width 812
 #Height 685
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
 void draw(SkCanvas* canvas) {
     canvas->scale(1.25f, 1.25f);
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setTextSize(10);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawString("128-bit word", 5 + 20 * 16, 20, paint);
-    canvas->drawString("little endian byte order", 5 + 20 * 4, 135, paint);
+    SkTextUtils::DrawString(canvas, "128-bit word", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);
+    SkTextUtils::DrawString(canvas, "little endian byte order", 5 + 20 * 4, 135, paint, SkPaint::kCenter_Align);
     for (int i = 0; i < 4; ++i) {
-        canvas->drawString("(low bits)", 5 + 10 * 4, 187 + i * 100, paint);
-        canvas->drawString("(high bits)", 105 + 10 * 4, 237 + i * 100, paint);
+        SkTextUtils::DrawString(canvas, "(low bits)", 5 + 10 * 4, 187 + i * 100, paint, SkPaint::kCenter_Align);
+        SkTextUtils::DrawString(canvas, "(high bits)", 105 + 10 * 4, 237 + i * 100, paint, SkPaint::kCenter_Align);
     }
     auto drawBoxText = [=](SkScalar e[], const char* s[], const char* nums[] , 
              int count, int n, SkScalar yPos) -> void {
@@ -477,9 +522,9 @@
                 if (2 == count) {
                     x += stringIndex * 12 + (stringIndex ? 8 : 0);
                 }
-                canvas->drawString(nums[stringIndex], x, yPos - 5, p);
+                SkTextUtils::DrawString(canvas, nums[stringIndex], x, yPos - 5, p, SkPaint::kCenter_Align);
                 if (1 == count) {
-                    canvas->drawString(nums[stringIndex], xPos + 100, yPos - 5, p);
+                    SkTextUtils::DrawString(canvas, nums[stringIndex], xPos + 100, yPos - 5, p, SkPaint::kCenter_Align);
                 }
                 ++stringIndex;
             }
@@ -487,9 +532,9 @@
         }
         p.setColor(SK_ColorBLACK);
         for (int i = 0; i < count; ++i) {
-            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 5, yPos + 10, p);
+            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 5, yPos + 10, p, SkPaint::kCenter_Align);
             if (1 == count) {
-                canvas->drawString(s[i], 105 + (e[i] + e[i + 1]) * 5, yPos + 10, p);
+                SkTextUtils::DrawString(canvas, s[i], 105 + (e[i] + e[i + 1]) * 5, yPos + 10, p, SkPaint::kCenter_Align);
             }
         }
         p.setStyle(SkPaint::kStroke_Style);
@@ -533,10 +578,16 @@
 #Example
 #Width 480
 #Height 330
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
+void draw(SkCanvas* canvas) {
     SkPaint srcPaint;
     srcPaint.setAntiAlias(true);
     SkPaint labelPaint = srcPaint;
-    labelPaint.setTextAlign(SkPaint::kCenter_Align);
     labelPaint.setTextSize(16);
     SkPaint dstPaint = labelPaint;
     dstPaint.setTextSize(80);
@@ -559,15 +610,16 @@
                         SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,
                         SkBlendMode::kDstIn, SkBlendMode::kDstOut,
                         SkBlendMode::kClear, SkBlendMode::kXor } ) {
-        canvas->drawString("&", 50, 80, dstPaint);
+        SkTextUtils::DrawString(canvas, "&", 50, 80, dstPaint, SkPaint::kCenter_Align);
         srcPaint.setBlendMode(blend);
         canvas->drawBitmap(srcBits, 0, 0, &srcPaint);
-        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);
         canvas->translate(80, 0);
         if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {
             canvas->translate(-80 * 5, 100);
         }
     }
+}
 ##
 ##
 
@@ -575,10 +627,16 @@
 #Example
 #Width 480
 #Height 330
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
+void draw(SkCanvas* canvas) {
     SkPaint srcPaint;
     srcPaint.setAntiAlias(true);
     SkPaint labelPaint = srcPaint;
-    labelPaint.setTextAlign(SkPaint::kCenter_Align);
     labelPaint.setTextSize(16);
     SkPaint dstPaint = labelPaint;
     dstPaint.setTextSize(80);
@@ -599,15 +657,16 @@
                         SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,
                         SkBlendMode::kDstIn, SkBlendMode::kDstOut,
                         SkBlendMode::kClear, SkBlendMode::kXor } ) {
-        canvas->drawString("&", 50, 80, dstPaint);
+        SkTextUtils::DrawString(canvas, "&", 50, 80, dstPaint, SkPaint::kCenter_Align);
         srcPaint.setBlendMode(blend);
         canvas->drawPath(srcPath, srcPaint);
-        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);
         canvas->translate(80, 0);
         if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {
             canvas->translate(-80 * 5, 100);
         }
     }
+}
 ##
 ##
 
@@ -615,10 +674,16 @@
 #Example
 #Width 480
 #Height 330
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
+void draw(SkCanvas* canvas) {
     SkPaint srcPaint;
     srcPaint.setAntiAlias(true);
     SkPaint labelPaint = srcPaint;
-    labelPaint.setTextAlign(SkPaint::kCenter_Align);
     labelPaint.setTextSize(16);
     SkPaint dstPaint = labelPaint;
     dstPaint.setTextSize(80);
@@ -634,15 +699,16 @@
             SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,
             SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,
             SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply } ) {
-        canvas->drawString("&", 50, 80, dstPaint);
+        SkTextUtils::DrawString(canvas, "&", 50, 80, dstPaint, SkPaint::kCenter_Align);
         srcPaint.setBlendMode(blend);
         canvas->drawPath(srcPath, srcPaint);
-        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
+        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);
         canvas->translate(90, 0);
         if (SkBlendMode::kLighten == blend || SkBlendMode::kDifference == blend) {
             canvas->translate(-90 * 5, 100);
         }
     }
+}
 ##
 ##
 
@@ -650,29 +716,37 @@
 #Example
 #Width 480
 #Height 110
-    SkPaint srcPaint;
-    srcPaint.setAntiAlias(true);
-    SkPaint labelPaint = srcPaint;
-    labelPaint.setTextAlign(SkPaint::kCenter_Align);
-    labelPaint.setTextSize(16);
-    SkPaint dstPaint = labelPaint;
-    dstPaint.setTextSize(80);
-    dstPaint.setColor(0xFF606080);
-    dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
 
-    srcPaint.setColor(0xFFcc6633);
-    SkPath srcPath;
-    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};
-    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);
-    canvas->drawColor(0, SkBlendMode::kClear);
-    for (auto blend : { SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,
-                        SkBlendMode::kLuminosity } ) {
-        canvas->drawString("&", 50, 80, dstPaint);
-        srcPaint.setBlendMode(blend);
-        canvas->drawPath(srcPath, srcPaint);
-        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);
-        canvas->translate(90, 0);
-    }
+void draw(SkCanvas* canvas) {
+    SkPaint srcPaint;

+    srcPaint.setAntiAlias(true);

+    SkPaint labelPaint = srcPaint;

+    labelPaint.setTextSize(16);

+    SkPaint dstPaint = labelPaint;

+    dstPaint.setTextSize(80);

+    dstPaint.setColor(0xFF606080);

+    dstPaint.setTypeface(SkTypeface::MakeFromName("Roboto", SkFontStyle::Bold()));

+

+    srcPaint.setColor(0xFFcc6633);

+    SkPath srcPath;

+    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};

+    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);

+    canvas->drawColor(0, SkBlendMode::kClear);

+    for (auto blend : { SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,

+                        SkBlendMode::kLuminosity } ) {

+        SkTextUtils::DrawString(canvas, "&", 50, 80, dstPaint, SkPaint::kCenter_Align);

+        srcPaint.setBlendMode(blend);

+        canvas->drawPath(srcPath, srcPaint);

+        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint,

+                SkPaint::kCenter_Align);

+        canvas->translate(90, 0);

+    }

+}
 ##
 ##
 
@@ -680,10 +754,16 @@
 #Example
 #Width 480
 #Height 110
+#Function
+###$
+#include "SkTextUtils.h"
+$$$#
+##
+
+void draw(SkCanvas* canvas) {
     SkPaint srcPaint;
     srcPaint.setAntiAlias(true);
     SkPaint labelPaint = srcPaint;
-    labelPaint.setTextAlign(SkPaint::kCenter_Align);
     labelPaint.setTextSize(16);
     SkPaint dstPaint = labelPaint;
     dstPaint.setTextSize(80);
@@ -703,18 +783,19 @@
     canvas->drawColor(0, SkBlendMode::kClear);
     srcPaint.setBlendMode(SkBlendMode::kModulate);
     for (auto step: { 1, 2 } ) {
-        canvas->drawString("&", 50, 80, dstPaint);
+        SkTextUtils::DrawString(canvas, "&", 50, 80, dstPaint, SkPaint::kCenter_Align);
         if (1 == step) {
             canvas->drawBitmap(srcBits, 0, 0, &srcPaint);
-            canvas->drawString("Bitmap", 50, 18, labelPaint);
+            SkTextUtils::DrawString(canvas, "Bitmap", 50, 18, labelPaint, SkPaint::kCenter_Align);
         } else {
             canvas->drawPath(srcPath, srcPaint);
-            canvas->drawString("Geometry", 50, 18, labelPaint);
+            SkTextUtils::DrawString(canvas, "Geometry", 50, 18, labelPaint, SkPaint::kCenter_Align);
         }
-        canvas->drawString(SkBlendMode_Name(SkBlendMode::kModulate), 50, 100, labelPaint);
+        SkTextUtils::DrawString(canvas, SkBlendMode_Name(SkBlendMode::kModulate), 50, 100, labelPaint,

+                SkPaint::kCenter_Align);
         canvas->translate(120, 0);
     }
-
+}
 ##
 ##
 
diff --git a/docs/undocumented.bmh b/docs/undocumented.bmh
index 2c31124..a6bf6ee 100644
--- a/docs/undocumented.bmh
+++ b/docs/undocumented.bmh
@@ -354,6 +354,18 @@
 #Subtopic ##
 #Subtopic Engine
 ##
+#Enum SkTextEncoding
+#Const kUTF8_SkTextEncoding 0
+##
+#Const kUTF16_SkTextEncoding 1
+##
+#Const kUTF32_SkTextEncoding 2
+##
+#Const kGlyphID_SkTextEncoding 3
+##
+##
+#Class SkFont
+##
 #Topic ##
 
 #Topic Font_Manager
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h
index 36a3671..907241c 100644
--- a/include/core/SkTextBlob.h
+++ b/include/core/SkTextBlob.h
@@ -67,7 +67,7 @@
         @return            SkTextBlob constructed from one run
     */
     static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
-                                          SkPaint::TextEncoding = SkPaint::kUTF8_TextEncoding);
+                                      SkPaint::TextEncoding encoding = SkPaint::kUTF8_TextEncoding);
 
     /** Creates SkTextBlob with a single run. string meaning depends on SkPaint::TextEncoding;
         by default, string is encoded as UTF-8.
diff --git a/site/user/api/SkCanvas_Reference.md b/site/user/api/SkCanvas_Reference.md
index ac871c3..db8187b 100644
--- a/site/user/api/SkCanvas_Reference.md
+++ b/site/user/api/SkCanvas_Reference.md
@@ -5486,7 +5486,7 @@
 
 ### Example
 
-<div><fiddle-embed name="3ce367af833428b08e75d8a22fe67808"></fiddle-embed></div>
+<div><fiddle-embed name="935c8f8b9782d297a73d7186f6ef7945"></fiddle-embed></div>
 
 ### See Also
 
@@ -5964,7 +5964,7 @@
 
 ### Example
 
-<div><fiddle-embed name="4cf70f8d194867d053d7e177e5088445"></fiddle-embed></div>
+<div><fiddle-embed name="4e8b7409531c9211a2afcf632005a38c"></fiddle-embed></div>
 
 ### Example
 
diff --git a/site/user/api/SkImageInfo_Reference.md b/site/user/api/SkImageInfo_Reference.md
index f154a86..81eee9f 100644
--- a/site/user/api/SkImageInfo_Reference.md
+++ b/site/user/api/SkImageInfo_Reference.md
@@ -439,7 +439,7 @@
 Pixels are fully opaque as if its <a href='SkColor_Reference#Alpha'>Color Alpha</a> was set to one, and should
 always be paired with <a href='#kOpaque_SkAlphaType'>kOpaque_SkAlphaType</a>.
 
-![Color_Type_RGB_565](https://fiddle.skia.org/i/f5981f4d2337dc5b6ee2d1d0c2a05078_raster.png "")
+![Color_Type_RGB_565](https://fiddle.skia.org/i/21e703b1aba5f2404f94f3db34d4f7cb_raster.png "")
 
 ### Example
 
@@ -458,7 +458,7 @@
 Note that <a href='#kARGB_4444_SkColorType'>kARGB_4444_SkColorType</a> is misnamed; the acronym does not
 describe the actual component order.
 
-![Color_Type_ARGB_4444](https://fiddle.skia.org/i/0441bdba65a19aa72b75b7fa62d22121_raster.png "")
+![Color_Type_ARGB_4444](https://fiddle.skia.org/i/bdc77b69231f1e1699e245944f1b239c_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: blue, green, and red components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If blue, green, or red is greater than alpha,
@@ -487,7 +487,7 @@
 <a href='#kRGBA_8888_SkColorType'>kRGBA_8888_SkColorType</a> encodes ARGB into a 32-bit word. Each component:
 red, green, blue, alpha; use eight bits, describing 256 levels.
 
-![Color_Type_RGBA_8888](https://fiddle.skia.org/i/4ccd35f27fe73dce8cce8c75e18df23c_raster.png "")
+![Color_Type_RGBA_8888](https://fiddle.skia.org/i/98d5232ae83a71fecf35713bcd635fdc_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: red, green, and blue components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If red, green, or blue is greater than alpha,
@@ -523,7 +523,7 @@
 their <a href='SkColor_Reference#Alpha'>Color Alpha</a> was set to one, and should always be paired with
 <a href='#kOpaque_SkAlphaType'>kOpaque_SkAlphaType</a>.
 
-![Color_Type_RGB_888](https://fiddle.skia.org/i/fecfe58c25cfc1b1e411e5eb50f7d8d1_raster.png "")
+![Color_Type_RGB_888](https://fiddle.skia.org/i/a11d984d5880664ca15dbac5beed44a3_raster.png "")
 
 ### Example
 
@@ -540,7 +540,7 @@
 <a href='#kBGRA_8888_SkColorType'>kBGRA_8888_SkColorType</a> encodes ARGB into a 32-bit word. Each component:
 blue, green, red, and alpha; use eight bits, describing 256 levels.
 
-![Color_Type_BGRA_8888](https://fiddle.skia.org/i/babd0e12db21a88c74d4e88aa40268ab_raster.png "")
+![Color_Type_BGRA_8888](https://fiddle.skia.org/i/743a950f1df07936e8a5fcb2a91208c4_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: blue, green, and red components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If blue, green, or red is greater than alpha,
@@ -579,7 +579,7 @@
 At present, <a href='SkColor_Reference#Color'>Color</a> in <a href='SkPaint_Reference#Paint'>Paint</a> does not provide enough precision to
 draw all colors possible to a <a href='#kRGBA_1010102_SkColorType'>kRGBA_1010102_SkColorType</a> <a href='SkSurface_Reference#Surface'>Surface</a>.
 
-![Color_Type_RGBA_1010102](https://fiddle.skia.org/i/6c470410001ad8f1ee9f58204c66f1bb_raster.png "")
+![Color_Type_RGBA_1010102](https://fiddle.skia.org/i/2ee75d2bd4e59dc7ab97a96d86fd9bfc_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: red, green, and blue components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If red, green, or blue is greater than the
@@ -614,7 +614,7 @@
 At present, <a href='SkColor_Reference#Color'>Color</a> in <a href='SkPaint_Reference#Paint'>Paint</a> does not provide enough precision to
 draw all colors possible to a <a href='#kRGB_101010x_SkColorType'>kRGB_101010x_SkColorType</a> <a href='SkSurface_Reference#Surface'>Surface</a>.
 
-![Color_Type_RGB_101010](https://fiddle.skia.org/i/c22477b11dabaa3e3a0b5bb33a7733cd_raster.png "")
+![Color_Type_RGB_101010](https://fiddle.skia.org/i/719fea0149e040ac1178fe298d4f7c7a_raster.png "")
 
 ### Example
 
@@ -657,7 +657,7 @@
 Meaningful colors are represented by the range 0.0 to 1.0, although smaller
 and larger values may be useful when used in combination with <a href='undocumented#Transfer_Mode'>Transfer Mode</a>.
 
-![Color_Type_RGBA_F16](https://fiddle.skia.org/i/9344796c059ff5e4f057595e781905b3_raster.png "")
+![Color_Type_RGBA_F16](https://fiddle.skia.org/i/adc8262f27f1ac048984b4cbff9334ac_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: blue, green, and red components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If blue, green, or red is greater than alpha,
@@ -694,7 +694,7 @@
 Meaningful colors are represented by the range 0.0 to 1.0, although smaller
 and larger values may be useful when used in combination with <a href='undocumented#Transfer_Mode'>Transfer Mode</a>.
 
-![Color_Type_RGBA_F32](https://fiddle.skia.org/i/b26119f9312d5f5d4011bf2dac94fafe_raster.png "")
+![Color_Type_RGBA_F32](https://fiddle.skia.org/i/36efa3247a841d0a46aee987a05e9fc2_raster.png "")
 
 If paired with <a href='#kPremul_SkAlphaType'>kPremul_SkAlphaType</a>: blue, green, and red components are
 <a href='undocumented#Premultiply'>Premultiplied</a> by the alpha value. If blue, green, or red is greater than alpha,
@@ -1329,7 +1329,7 @@
 
 ### Example
 
-<div><fiddle-embed name="588a0a763d78c1b3b3ea0b2a6e39fda6"></fiddle-embed></div>
+<div><fiddle-embed name="e2491817695290d0218be77f091b8460"></fiddle-embed></div>
 
 ### See Also
 
@@ -1351,7 +1351,7 @@
 
 ### Example
 
-<div><fiddle-embed name="b79ea956d4cb89a483bfa48bba09df85"></fiddle-embed></div>
+<div><fiddle-embed name="72c35baaeddca1d912edf93d19429c8e"></fiddle-embed></div>
 
 ### See Also
 
@@ -1622,7 +1622,7 @@
 
 ### Example
 
-<div><fiddle-embed name="dcdc308a1a2089db47b8375178491832"></fiddle-embed></div>
+<div><fiddle-embed name="22df72732e898a11773fbfe07388a546"></fiddle-embed></div>
 
 ### See Also
 
@@ -1752,7 +1752,7 @@
 
 ### Example
 
-<div><fiddle-embed name="454add968099811053e2b372238472e3"></fiddle-embed></div>
+<div><fiddle-embed name="fe3c5a755d3dde29bba058a583f18901"></fiddle-embed></div>
 
 ### See Also
 
diff --git a/site/user/api/SkImage_Reference.md b/site/user/api/SkImage_Reference.md
index ccd48cb..f918145 100644
--- a/site/user/api/SkImage_Reference.md
+++ b/site/user/api/SkImage_Reference.md
@@ -1239,7 +1239,7 @@
 
 ### Example
 
-<div><fiddle-embed name="39a6d0bbeac6d957c2338e0bff865cf8"></fiddle-embed></div>
+<div><fiddle-embed name="9aec65fc252ffc9982fa8867433eca18"></fiddle-embed></div>
 
 ### See Also
 
@@ -1261,7 +1261,7 @@
 
 ### Example
 
-<div><fiddle-embed name="60a063a2b210915f38401c83d4dba9e6"></fiddle-embed></div>
+<div><fiddle-embed name="a4f53a0b6ac85e7bc3887245b728530d"></fiddle-embed></div>
 
 ### See Also
 
@@ -1660,7 +1660,7 @@
 
 ### Example
 
-<div><fiddle-embed name="27a0ab44659201f1aa2ac7fea73368c2" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="9cf5c62a3d2243e6577ae563f360ea9d" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
@@ -1695,7 +1695,7 @@
 
 ### Example
 
-<div><fiddle-embed name="8f7281446008cf4a9910fe73f44fa8d6" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="afc62f38aebc56af8e425297ec67dd37" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
@@ -2154,7 +2154,7 @@
 
 ### Example
 
-<div><fiddle-embed name="b14d9debfe87295373b44a179992a999" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="eeec9e07e604b44d0208899a2fe5bef5" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
@@ -2180,7 +2180,7 @@
 
 ### Example
 
-<div><fiddle-embed name="c77bfb00fb82e378eea4b7f7c18a8b84" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="ecdbaff44a02c310ef672b7d393c6dea" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
@@ -2206,7 +2206,7 @@
 
 ### Example
 
-<div><fiddle-embed name="505a6d9458394b1deb5d2f6c44e1cd76" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="aed5f399915d40bb5d133ab586e5bac3" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
@@ -2417,7 +2417,7 @@
 
 ### Example
 
-<div><fiddle-embed name="25305461b916baf40d7d379e04a5589c" gpu="true"></fiddle-embed></div>
+<div><fiddle-embed name="f031c2a53f6a57833dc0127e674553da" gpu="true"></fiddle-embed></div>
 
 ### See Also
 
diff --git a/site/user/api/SkPaint_Reference.md b/site/user/api/SkPaint_Reference.md
index 249a95c..8d7cd7b 100644
--- a/site/user/api/SkPaint_Reference.md
+++ b/site/user/api/SkPaint_Reference.md
@@ -3703,7 +3703,7 @@
 
 ### Example
 
-<div><fiddle-embed name="702617fd9ebc3f12e30081b5db93e8a8"><div>Each position separately moves the glyph in drawPosText.
+<div><fiddle-embed name="6ee1866e4da0064d9d340b07e05f0aca"><div>Each position separately moves the glyph in drawPosText.
 </div></fiddle-embed></div>
 
 <a name='SkPaint_getTextAlign'></a>
@@ -3714,24 +3714,7 @@
 <a href='#SkPaint_Align'>Align</a> <a href='#SkPaint_getTextAlign'>getTextAlign</a>() const
 </pre>
 
-Returns <a href='#Text_Align'>Text Align</a>.
-Returns <a href='#SkPaint_kLeft_Align'>kLeft Align</a> if <a href='#Text_Align'>Text Align</a> has not been set.
-
-### Return Value
-
-text placement relative to position
-
-### Example
-
-<div><fiddle-embed name="2df932f526e810f74c89d30ec3f4c947">
-
-#### Example Output
-
-~~~~
-kLeft_Align == default
-~~~~
-
-</fiddle-embed></div>
+Deprecated.
 
 <a name='SkPaint_setTextAlign'></a>
 
@@ -3741,21 +3724,7 @@
 void    <a href='#SkPaint_setTextAlign'>setTextAlign</a>(<a href='#SkPaint_Align'>Align</a> align)
 </pre>
 
-Sets <a href='#Text_Align'>Text Align</a> to <a href='#SkPaint_setTextAlign_align'>align</a>.
-Has no effect if <a href='#SkPaint_setTextAlign_align'>align</a> is an invalid value.
-
-### Parameters
-
-<table>  <tr>    <td><a name='SkPaint_setTextAlign_align'><code><strong>align</strong></code></a></td>
-    <td>text placement relative to position</td>
-  </tr>
-</table>
-
-### Example
-
-<div><fiddle-embed name="d37540afd918506ac2594665ca63979b"><div><a href='undocumented#Text'>Text</a> is left-aligned by default, and then set to center. Setting the
-alignment out of range has no effect.
-</div></fiddle-embed></div>
+Deprecated.
 
 <a name='Text_Size'></a>
 
diff --git a/site/user/api/SkPath_Reference.md b/site/user/api/SkPath_Reference.md
index 4b1c351..7fd3e10 100644
--- a/site/user/api/SkPath_Reference.md
+++ b/site/user/api/SkPath_Reference.md
@@ -391,7 +391,7 @@
 
 ### Example
 
-<div><fiddle-embed name="0de03d9c939b6238318b7366866e8722"></fiddle-embed></div>
+<div><fiddle-embed name="4bbae00b40ed2cfcd0007921ad693a7b"></fiddle-embed></div>
 
 ### See Also
 
@@ -799,7 +799,7 @@
 
 ### Example
 
-<div><fiddle-embed name="d84cd32b0bfd9ad2714f753120ed0ee1"></fiddle-embed></div>
+<div><fiddle-embed name="d2c33dc791cd165dcc2423226ba5b095"></fiddle-embed></div>
 
 ### See Also
 
@@ -2923,14 +2923,14 @@
 
 ### Example
 
-<div><fiddle-embed name="d9c6435f26f37b3d63c664a99028f77f"></fiddle-embed></div>
+<div><fiddle-embed name="386000684073fccabc224d7d6dc81cd9"></fiddle-embed></div>
 
 If last <a href='#Path'>Path</a> <a href='SkPoint_Reference#Point'>Point</a> does not start <a href='#Arc'>Arc</a>, <a href='#SkPath_arcTo'>arcTo</a> appends connecting <a href='undocumented#Line'>Line</a> to <a href='#Path'>Path</a>.
 The length of <a href='SkPoint_Reference#Vector'>Vector</a> from (<a href='#SkPath_arcTo_2_x1'>x1</a>, <a href='#SkPath_arcTo_2_y1'>y1</a>) to (<a href='#SkPath_arcTo_2_x2'>x2</a>, <a href='#SkPath_arcTo_2_y2'>y2</a>) does not affect <a href='#Arc'>Arc</a>.
 
 ### Example
 
-<div><fiddle-embed name="01d2ddfd539ab86a86989e210640dffc"></fiddle-embed></div>
+<div><fiddle-embed name="78f3c65fa900610bb52518989b547095"></fiddle-embed></div>
 
 <a href='#Arc'>Arc</a> sweep is always less than 180 degrees. If <a href='#SkPath_arcTo_2_radius'>radius</a> is zero, or if
 tangents are nearly parallel, <a href='#SkPath_arcTo'>arcTo</a> appends <a href='undocumented#Line'>Line</a> from last <a href='#Path'>Path</a> <a href='SkPoint_Reference#Point'>Point</a> to (<a href='#SkPath_arcTo_2_x1'>x1</a>, <a href='#SkPath_arcTo_2_y1'>y1</a>).
@@ -3758,7 +3758,7 @@
 
 ### Example
 
-<div><fiddle-embed name="ab9753174060e4a551727ef3af12924d"></fiddle-embed></div>
+<div><fiddle-embed name="f1122d6fffddac0167e96fab4b9a862f"></fiddle-embed></div>
 
 ### See Also
 
diff --git a/site/user/api/SkRRect_Reference.md b/site/user/api/SkRRect_Reference.md
index 132daa8..2977611 100644
--- a/site/user/api/SkRRect_Reference.md
+++ b/site/user/api/SkRRect_Reference.md
@@ -264,7 +264,7 @@
 
 ### Example
 
-<div><fiddle-embed name="38a559936ea7c8d482098c189ee5c9b8"></fiddle-embed></div>
+<div><fiddle-embed name="a4233634c75b72fc7a2815ddb69bd669"></fiddle-embed></div>
 
 ### See Also
 
@@ -335,7 +335,7 @@
 
 ### Example
 
-<div><fiddle-embed name="3afe4ea247923e06326aeb2b165c7485"></fiddle-embed></div>
+<div><fiddle-embed name="099d79ecfbdfb0a19c10deb7201859c3"></fiddle-embed></div>
 
 ### See Also
 
@@ -358,7 +358,7 @@
 
 ### Example
 
-<div><fiddle-embed name="e2dcdad0e9cb7ba3e78a9871e9229753"></fiddle-embed></div>
+<div><fiddle-embed name="bc931c9a6eb8ffe7ea8d3fb47e07a475"></fiddle-embed></div>
 
 ### See Also
 
@@ -382,7 +382,7 @@
 
 ### Example
 
-<div><fiddle-embed name="ab9b3aef7896aee80b780789848fbba4"><div>The first radii are scaled down proportionately until both x-axis and y-axis fit
+<div><fiddle-embed name="4dfdb28d8343958425f2c1323fe8170d"><div>The first radii are scaled down proportionately until both x-axis and y-axis fit
 within the bounds. After scaling, x-axis radius is smaller than half the width;
 left <a href='#RRect'>Round Rect</a> is not an oval. The second radii are equal to half the
 dimensions; right <a href='#RRect'>Round Rect</a> is an oval.
@@ -410,7 +410,7 @@
 
 ### Example
 
-<div><fiddle-embed name="65bbb109483ed79edb32027cf71851eb"></fiddle-embed></div>
+<div><fiddle-embed name="f6959ea422a7c6e98ddfad216a52c707"></fiddle-embed></div>
 
 ### See Also
 
@@ -434,7 +434,7 @@
 
 ### Example
 
-<div><fiddle-embed name="568cb730e66d0df09a7d9bd9d6142c9e"></fiddle-embed></div>
+<div><fiddle-embed name="429f6dfd4cf6287df3c3c77fa7681c99"></fiddle-embed></div>
 
 ### See Also
 
@@ -460,7 +460,7 @@
 
 ### Example
 
-<div><fiddle-embed name="e4ba9346ee5c2d37d5e504f8cc678544"></fiddle-embed></div>
+<div><fiddle-embed name="b62c183dc435d1fc091111fb2f3c3f8e"></fiddle-embed></div>
 
 ### See Also
 
@@ -551,7 +551,7 @@
 
 ### Example
 
-<div><fiddle-embed name="ebcc50ed30240e94de8439d21dd8171c"></fiddle-embed></div>
+<div><fiddle-embed name="81345f7619a072bb2b0cf59810fe86d0"></fiddle-embed></div>
 
 ### See Also
 
@@ -1346,7 +1346,7 @@
 
 ### Example
 
-<div><fiddle-embed name="884447c809921cfaebc87aeb63dedd48"></fiddle-embed></div>
+<div><fiddle-embed name="0bb057140e4119234bdd2e8dd2f0fa19"></fiddle-embed></div>
 
 ### See Also
 
@@ -1371,7 +1371,7 @@
 
 ### Example
 
-<div><fiddle-embed name="d28709aa457742391842a9ab1f21b5fa"></fiddle-embed></div>
+<div><fiddle-embed name="8cc1f21c98c0416f7724ad218f557a00"></fiddle-embed></div>
 
 ### See Also
 
@@ -1416,7 +1416,7 @@
 
 ### Example
 
-<div><fiddle-embed name="1466c844a78fd05a7362537347e360ca"></fiddle-embed></div>
+<div><fiddle-embed name="d6f5a3d21727ddc15e10ef4d5103ff91"></fiddle-embed></div>
 
 ### See Also
 
@@ -1450,7 +1450,7 @@
 
 ### Example
 
-<div><fiddle-embed name="b877c0adff35470865a57aa150bf5329"></fiddle-embed></div>
+<div><fiddle-embed name="50969745cf2b23544362f4cff5592b75"></fiddle-embed></div>
 
 ### See Also
 
@@ -1486,7 +1486,7 @@
 
 ### Example
 
-<div><fiddle-embed name="99ccc6862bb9fe3ca35228eee9f9725d"></fiddle-embed></div>
+<div><fiddle-embed name="68a5d24f22e2d798608fce8a20e47fd0"></fiddle-embed></div>
 
 ### See Also
 
diff --git a/site/user/api/SkTextBlobBuilder_Reference.md b/site/user/api/SkTextBlobBuilder_Reference.md
index df5f899..a290e89 100644
--- a/site/user/api/SkTextBlobBuilder_Reference.md
+++ b/site/user/api/SkTextBlobBuilder_Reference.md
@@ -26,6 +26,12 @@
                                   const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr);
     const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a>(const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& font, int count,
                                  const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr);
+    const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRun_2'>allocRun</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count, <a href='undocumented#SkScalar'>SkScalar</a> x, <a href='undocumented#SkScalar'>SkScalar</a> y,
+                              const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr);
+    const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRunPosH_2'>allocRunPosH</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count, <a href='undocumented#SkScalar'>SkScalar</a> y,
+                                  const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr);
+    const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRunPos_2'>allocRunPos</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count,
+                                 const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr);
 };
 </pre>
 
@@ -91,7 +97,7 @@
 
 ### See Also
 
-<a href='#SkTextBlobBuilder_allocRun'>allocRun</a> <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a> <a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a>
+<a href='#SkTextBlobBuilder_allocRun'>allocRun</a><sup><a href='#SkTextBlobBuilder_allocRun_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a><sup><a href='#SkTextBlobBuilder_allocRunPos_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a><sup><a href='#SkTextBlobBuilder_allocRunPosH_2'>[2]</a></sup>
 
 <a name='SkTextBlobBuilder_empty_constructor'></a>
 
@@ -229,7 +235,64 @@
 
 ### See Also
 
-<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a> <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a>
+<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a><sup><a href='#SkTextBlobBuilder_allocRunPosH_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a><sup><a href='#SkTextBlobBuilder_allocRunPos_2'>[2]</a></sup>
+
+<a name='SkTextBlobBuilder_allocRun_2'></a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
+const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRun'>allocRun</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count, <a href='undocumented#SkScalar'>SkScalar</a> x, <a href='undocumented#SkScalar'>SkScalar</a> y,
+                          const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr)
+</pre>
+
+Returns run with storage for <a href='undocumented#Glyph'>Glyphs</a>. Caller must write <a href='#SkTextBlobBuilder_allocRun_2_count'>count</a> <a href='undocumented#Glyph'>Glyphs</a> to
+<a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs before next call to FontBlobBuilder.
+
+<a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.utf8text, and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.clusters should be ignored.
+
+<a href='undocumented#Glyph'>Glyphs</a> share <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> in <a href='#SkTextBlobBuilder_allocRun_2_font'>font</a>, including: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
+<a href='SkPaint_Reference#Text_Skew_X'>Paint Text Skew X</a>, <a href='SkPaint_Reference#Text_Align'>Paint Text Align</a>, <a href='SkPaint_Reference#Hinting'>Paint Hinting</a>, <a href='SkPaint_Reference#Anti_Alias'>Anti Alias</a>, <a href='SkPaint_Reference#Fake_Bold'>Paint Fake Bold</a>,
+<a href='SkPaint_Reference#Font_Embedded_Bitmaps'>Font Embedded Bitmaps</a>, <a href='SkPaint_Reference#Full_Hinting_Spacing'>Full Hinting Spacing</a>, <a href='SkPaint_Reference#LCD_Text'>LCD Text</a>, <a href='SkPaint_Reference#Linear_Text'>Linear Text</a>,
+and <a href='SkPaint_Reference#Subpixel_Text'>Subpixel Text</a>.
+
+<a href='undocumented#Glyph'>Glyphs</a> are positioned on a baseline at (<a href='#SkTextBlobBuilder_allocRun_2_x'>x</a>, <a href='#SkTextBlobBuilder_allocRun_2_y'>y</a>), using <a href='#SkTextBlobBuilder_allocRun_2_font'>font</a> <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> to
+determine their relative placement.
+
+<a href='#SkTextBlobBuilder_allocRun_2_bounds'>bounds</a> defines an optional bounding box, used to suppress drawing when <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a>
+<a href='#SkTextBlobBuilder_allocRun_2_bounds'>bounds</a> does not intersect <a href='SkSurface_Reference#Surface'>Surface</a> <a href='#SkTextBlobBuilder_allocRun_2_bounds'>bounds</a>. If <a href='#SkTextBlobBuilder_allocRun_2_bounds'>bounds</a> is nullptr, <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a> <a href='#SkTextBlobBuilder_allocRun_2_bounds'>bounds</a>
+is computed from (<a href='#SkTextBlobBuilder_allocRun_2_x'>x</a>, <a href='#SkTextBlobBuilder_allocRun_2_y'>y</a>) and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a>.
+
+### Parameters
+
+<table>  <tr>    <td><a name='SkTextBlobBuilder_allocRun_2_font'><code><strong>font</strong></code></a></td>
+    <td><a href='undocumented#Font'>Font</a> used for this run</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRun_2_count'><code><strong>count</strong></code></a></td>
+    <td>number of glyphs</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRun_2_x'><code><strong>x</strong></code></a></td>
+    <td>horizontal offset within the blob</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRun_2_y'><code><strong>y</strong></code></a></td>
+    <td>vertical offset within the blob</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRun_2_bounds'><code><strong>bounds</strong></code></a></td>
+    <td>optional run bounding box</td>
+  </tr>
+</table>
+
+### Return Value
+
+writable glyph buffer
+
+### Example
+
+<div><fiddle-embed name="f0e584aec20eaee7a5bfed62aa885eee"></fiddle-embed></div>
+
+### See Also
+
+<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a><sup><a href='#SkTextBlobBuilder_allocRunPosH_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a><sup><a href='#SkTextBlobBuilder_allocRunPos_2'>[2]</a></sup>
 
 <a name='SkTextBlobBuilder_allocRunPosH'></a>
 
@@ -284,7 +347,62 @@
 
 ### See Also
 
-<a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a>
+<a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a><sup><a href='#SkTextBlobBuilder_allocRunPos_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a><sup><a href='#SkTextBlobBuilder_allocRun_2'>[2]</a></sup>
+
+<a name='SkTextBlobBuilder_allocRunPosH_2'></a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
+const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count, <a href='undocumented#SkScalar'>SkScalar</a> y,
+                              const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr)
+</pre>
+
+Returns run with storage for <a href='undocumented#Glyph'>Glyphs</a> and positions along baseline. Caller must
+write <a href='#SkTextBlobBuilder_allocRunPosH_2_count'>count</a> <a href='undocumented#Glyph'>Glyphs</a> to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs, and <a href='#SkTextBlobBuilder_allocRunPosH_2_count'>count</a> <a href='undocumented#Scalar'>Scalars</a> to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos;
+before next call to FontBlobBuilder.
+
+<a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.utf8text, and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.clusters should be ignored.
+
+<a href='undocumented#Glyph'>Glyphs</a> share <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> in <a href='#SkTextBlobBuilder_allocRunPosH_2_font'>font</a>, including: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
+<a href='SkPaint_Reference#Text_Skew_X'>Paint Text Skew X</a>, <a href='SkPaint_Reference#Text_Align'>Paint Text Align</a>, <a href='SkPaint_Reference#Hinting'>Paint Hinting</a>, <a href='SkPaint_Reference#Anti_Alias'>Anti Alias</a>, <a href='SkPaint_Reference#Fake_Bold'>Paint Fake Bold</a>,
+<a href='SkPaint_Reference#Font_Embedded_Bitmaps'>Font Embedded Bitmaps</a>, <a href='SkPaint_Reference#Full_Hinting_Spacing'>Full Hinting Spacing</a>, <a href='SkPaint_Reference#LCD_Text'>LCD Text</a>, <a href='SkPaint_Reference#Linear_Text'>Linear Text</a>,
+and <a href='SkPaint_Reference#Subpixel_Text'>Subpixel Text</a>.
+
+<a href='undocumented#Glyph'>Glyphs</a> are positioned on a baseline at <a href='#SkTextBlobBuilder_allocRunPosH_2_y'>y</a>, using x-axis positions written by
+caller to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos.
+
+<a href='#SkTextBlobBuilder_allocRunPosH_2_bounds'>bounds</a> defines an optional bounding box, used to suppress drawing when <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a>
+<a href='#SkTextBlobBuilder_allocRunPosH_2_bounds'>bounds</a> does not intersect <a href='SkSurface_Reference#Surface'>Surface</a> <a href='#SkTextBlobBuilder_allocRunPosH_2_bounds'>bounds</a>. If <a href='#SkTextBlobBuilder_allocRunPosH_2_bounds'>bounds</a> is nullptr, <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a> <a href='#SkTextBlobBuilder_allocRunPosH_2_bounds'>bounds</a>
+is computed from <a href='#SkTextBlobBuilder_allocRunPosH_2_y'>y</a>, <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos, and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a>.
+
+### Parameters
+
+<table>  <tr>    <td><a name='SkTextBlobBuilder_allocRunPosH_2_font'><code><strong>font</strong></code></a></td>
+    <td><a href='undocumented#Font'>Font</a> used for this run</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRunPosH_2_count'><code><strong>count</strong></code></a></td>
+    <td>number of <a href='undocumented#Glyph'>Glyphs</a></td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRunPosH_2_y'><code><strong>y</strong></code></a></td>
+    <td>vertical offset within the blob</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRunPosH_2_bounds'><code><strong>bounds</strong></code></a></td>
+    <td>optional run bounding box</td>
+  </tr>
+</table>
+
+### Return Value
+
+writable glyph buffer and x-axis position buffer
+
+### Example
+
+<div><fiddle-embed name="c77ac50f506106fdfef94d20bc1a6934"></fiddle-embed></div>
+
+### See Also
+
+<a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a><sup><a href='#SkTextBlobBuilder_allocRunPos_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a><sup><a href='#SkTextBlobBuilder_allocRun_2'>[2]</a></sup>
 
 <a name='SkTextBlobBuilder_allocRunPos'></a>
 
@@ -331,9 +449,60 @@
 
 ### Example
 
-<div><fiddle-embed name="f65c92ff5bfcc95ba58a2ba4d67f944f"></fiddle-embed></div>
+<div><fiddle-embed name="2a11d3c287f785f3808dcbce08ccb435"></fiddle-embed></div>
 
 ### See Also
 
-<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a>
+<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a><sup><a href='#SkTextBlobBuilder_allocRunPosH_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a><sup><a href='#SkTextBlobBuilder_allocRun_2'>[2]</a></sup>
+
+<a name='SkTextBlobBuilder_allocRunPos_2'></a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
+const <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>& <a href='#SkTextBlobBuilder_allocRunPos'>allocRunPos</a>(const <a href='undocumented#SkFont'>SkFont</a>& font, int count, const <a href='SkRect_Reference#SkRect'>SkRect</a>* bounds = nullptr)
+</pre>
+
+Returns run with storage for <a href='undocumented#Glyph'>Glyphs</a> and <a href='SkPoint_Reference#Point'>Point</a> positions. Caller must
+write <a href='#SkTextBlobBuilder_allocRunPos_2_count'>count</a> <a href='undocumented#Glyph'>Glyphs</a> to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs, and <a href='#SkTextBlobBuilder_allocRunPos_2_count'>count</a> <a href='SkPoint_Reference#Point'>Points</a> to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos;
+before next call to FontBlobBuilder.
+
+<a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.utf8text, and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.clusters should be ignored.
+
+<a href='undocumented#Glyph'>Glyphs</a> share <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> in <a href='#SkTextBlobBuilder_allocRunPos_2_font'>font</a>, including: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
+<a href='SkPaint_Reference#Text_Skew_X'>Paint Text Skew X</a>, <a href='SkPaint_Reference#Text_Align'>Paint Text Align</a>, <a href='SkPaint_Reference#Hinting'>Paint Hinting</a>, <a href='SkPaint_Reference#Anti_Alias'>Anti Alias</a>, <a href='SkPaint_Reference#Fake_Bold'>Paint Fake Bold</a>,
+<a href='SkPaint_Reference#Font_Embedded_Bitmaps'>Font Embedded Bitmaps</a>, <a href='SkPaint_Reference#Full_Hinting_Spacing'>Full Hinting Spacing</a>, <a href='SkPaint_Reference#LCD_Text'>LCD Text</a>, <a href='SkPaint_Reference#Linear_Text'>Linear Text</a>,
+and <a href='SkPaint_Reference#Subpixel_Text'>Subpixel Text</a>.
+
+<a href='undocumented#Glyph'>Glyphs</a> are positioned using <a href='SkPoint_Reference#Point'>Points</a> written by caller to <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos, using
+two <a href='undocumented#Scalar'>Scalar</a> values for each <a href='SkPoint_Reference#Point'>Point</a>.
+
+<a href='#SkTextBlobBuilder_allocRunPos_2_bounds'>bounds</a> defines an optional bounding box, used to suppress drawing when <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a>
+<a href='#SkTextBlobBuilder_allocRunPos_2_bounds'>bounds</a> does not intersect <a href='SkSurface_Reference#Surface'>Surface</a> <a href='#SkTextBlobBuilder_allocRunPos_2_bounds'>bounds</a>. If <a href='#SkTextBlobBuilder_allocRunPos_2_bounds'>bounds</a> is nullptr, <a href='SkTextBlob_Reference#Text_Blob'>Text Blob</a> <a href='#SkTextBlobBuilder_allocRunPos_2_bounds'>bounds</a>
+is computed from <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.pos, and <a href='#SkTextBlobBuilder_RunBuffer'>RunBuffer</a>.glyphs <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a>.
+
+### Parameters
+
+<table>  <tr>    <td><a name='SkTextBlobBuilder_allocRunPos_2_font'><code><strong>font</strong></code></a></td>
+    <td><a href='undocumented#Font'>Font</a> used for this run</td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRunPos_2_count'><code><strong>count</strong></code></a></td>
+    <td>number of <a href='undocumented#Glyph'>Glyphs</a></td>
+  </tr>
+  <tr>    <td><a name='SkTextBlobBuilder_allocRunPos_2_bounds'><code><strong>bounds</strong></code></a></td>
+    <td>optional run bounding box</td>
+  </tr>
+</table>
+
+### Return Value
+
+writable glyph buffer and <a href='SkPoint_Reference#Point'>Point</a> buffer
+
+### Example
+
+<div><fiddle-embed name="da4fcb4a972b500996be9aff6c6c40e1"></fiddle-embed></div>
+
+### See Also
+
+<a href='#SkTextBlobBuilder_allocRunPosH'>allocRunPosH</a><sup><a href='#SkTextBlobBuilder_allocRunPosH_2'>[2]</a></sup> <a href='#SkTextBlobBuilder_allocRun'>allocRun</a><sup><a href='#SkTextBlobBuilder_allocRun_2'>[2]</a></sup>
 
diff --git a/site/user/api/SkTextBlob_Reference.md b/site/user/api/SkTextBlob_Reference.md
index 774f2bd..6be4c72 100644
--- a/site/user/api/SkTextBlob_Reference.md
+++ b/site/user/api/SkTextBlob_Reference.md
@@ -11,8 +11,10 @@
 public:
     const <a href='SkRect_Reference#SkRect'>SkRect</a>& <a href='#SkTextBlob_bounds'>bounds</a>() const;
     uint32_t <a href='#SkTextBlob_uniqueID'>uniqueID</a>() const;
-    static <a href='undocumented#sk_sp'>sk_sp</a><<a href='#SkTextBlob'>SkTextBlob</a>> <a href='#SkTextBlob_MakeFromText'>MakeFromText</a>( const void* text, size_t byteLength, const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint);
-    static <a href='undocumented#sk_sp'>sk_sp</a><<a href='#SkTextBlob'>SkTextBlob</a>> <a href='#SkTextBlob_MakeFromString'>MakeFromString</a>(const char* string, const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint);
+    static <a href='undocumented#sk_sp'>sk_sp</a><<a href='#SkTextBlob'>SkTextBlob</a>> <a href='#SkTextBlob_MakeFromText'>MakeFromText</a>(const void* text, size_t byteLength, const <a href='undocumented#SkFont'>SkFont</a>& font,
+                               <a href='SkPaint_Reference#SkPaint_TextEncoding'>SkPaint::TextEncoding</a> encoding = <a href='SkPaint_Reference#SkPaint_kUTF8_TextEncoding'>SkPaint::kUTF8_TextEncoding</a>);
+    static <a href='undocumented#sk_sp'>sk_sp</a><<a href='#SkTextBlob'>SkTextBlob</a>> <a href='#SkTextBlob_MakeFromString'>MakeFromString</a>(const char* string, const <a href='undocumented#SkFont'>SkFont</a>& font,
+                                    <a href='SkPaint_Reference#SkPaint_TextEncoding'>SkPaint::TextEncoding</a> encoding = <a href='SkPaint_Reference#SkPaint_kUTF8_TextEncoding'>SkPaint::kUTF8_TextEncoding</a>);
     size_t <a href='#SkTextBlob_serialize'>serialize</a>(const <a href='undocumented#SkSerialProcs'>SkSerialProcs</a>& procs, void* memory, size_t memory_size) const;
     <a href='undocumented#sk_sp'>sk_sp</a><<a href='undocumented#SkData'>SkData</a>> <a href='#SkTextBlob_serialize_2'>serialize</a>(const <a href='undocumented#SkSerialProcs'>SkSerialProcs</a>& procs) const;
     static <a href='undocumented#sk_sp'>sk_sp</a><<a href='#SkTextBlob'>SkTextBlob</a>> <a href='#SkTextBlob_Deserialize'>Deserialize</a>(const void* data, size_t size,
@@ -75,15 +77,14 @@
 ---
 
 <pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
-static <a href='undocumented#sk_sp'>sk sp</a>&lt;<a href='#SkTextBlob'>SkTextBlob</a>&gt; <a href='#SkTextBlob_MakeFromText'>MakeFromText</a>(
-            const void* text, size_t byteLength,
-                                      const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint)
+static <a href='undocumented#sk_sp'>sk sp</a>&lt;<a href='#SkTextBlob'>SkTextBlob</a>&gt; <a href='#SkTextBlob_MakeFromText'>MakeFromText</a>(const void* text, size_t byteLength, const <a href='undocumented#SkFont'>SkFont</a>& font,
+                                      <a href='SkPaint_Reference#SkPaint_TextEncoding'>SkPaint::TextEncoding</a> encoding = <a href='SkPaint_Reference#SkPaint_kUTF8_TextEncoding'>SkPaint::kUTF8 TextEncoding</a>)
 </pre>
 
 Creates <a href='#Text_Blob'>Text Blob</a> with a single run. <a href='#SkTextBlob_MakeFromText_text'>text</a> meaning depends on <a href='SkPaint_Reference#Text_Encoding'>Paint Text Encoding</a>;
 by default, <a href='#SkTextBlob_MakeFromText_text'>text</a> is encoded as UTF-8.
 
-<a href='#SkTextBlob_MakeFromText_paint'>paint</a> contains attributes used to define the run <a href='#SkTextBlob_MakeFromText_text'>text</a>: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
+<a href='#SkTextBlob_MakeFromText_font'>font</a> contains attributes used to define the run <a href='#SkTextBlob_MakeFromText_text'>text</a>: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
 <a href='SkPaint_Reference#Text_Skew_X'>Paint Text Skew X</a>, <a href='SkPaint_Reference#Text_Align'>Paint Text Align</a>, <a href='SkPaint_Reference#Hinting'>Paint Hinting</a>, <a href='SkPaint_Reference#Anti_Alias'>Anti Alias</a>, <a href='SkPaint_Reference#Fake_Bold'>Paint Fake Bold</a>,
 <a href='SkPaint_Reference#Font_Embedded_Bitmaps'>Font Embedded Bitmaps</a>, <a href='SkPaint_Reference#Full_Hinting_Spacing'>Full Hinting Spacing</a>, <a href='SkPaint_Reference#LCD_Text'>LCD Text</a>, <a href='SkPaint_Reference#Linear_Text'>Linear Text</a>,
 and <a href='SkPaint_Reference#Subpixel_Text'>Subpixel Text</a>.
@@ -96,9 +97,13 @@
   <tr>    <td><a name='SkTextBlob_MakeFromText_byteLength'><code><strong>byteLength</strong></code></a></td>
     <td>byte length of <a href='#SkTextBlob_MakeFromText_text'>text</a> array</td>
   </tr>
-  <tr>    <td><a name='SkTextBlob_MakeFromText_paint'><code><strong>paint</strong></code></a></td>
+  <tr>    <td><a name='SkTextBlob_MakeFromText_font'><code><strong>font</strong></code></a></td>
     <td><a href='#SkTextBlob_MakeFromText_text'>text</a> size, typeface, <a href='#SkTextBlob_MakeFromText_text'>text</a> scale, and so on, used to draw</td>
   </tr>
+  <tr>    <td><a name='SkTextBlob_MakeFromText_encoding'><code><strong>encoding</strong></code></a></td>
+    <td>one of: <a href='undocumented#kUTF8_SkTextEncoding'>kUTF8_SkTextEncoding</a>, <a href='undocumented#kUTF16_SkTextEncoding'>kUTF16_SkTextEncoding</a>,
+<a href='undocumented#kUTF32_SkTextEncoding'>kUTF32_SkTextEncoding</a>, <a href='undocumented#kGlyphID_SkTextEncoding'>kGlyphID_SkTextEncoding</a></td>
+  </tr>
 </table>
 
 ### Return Value
@@ -107,7 +112,7 @@
 
 ### Example
 
-<div><fiddle-embed name="74686684967a310dc06fe2915b0a4798"></fiddle-embed></div>
+<div><fiddle-embed name="bec2252bc36dc8fd023015629d60c405"></fiddle-embed></div>
 
 ### See Also
 
@@ -118,13 +123,14 @@
 ---
 
 <pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
-static <a href='undocumented#sk_sp'>sk sp</a>&lt;<a href='#SkTextBlob'>SkTextBlob</a>&gt; <a href='#SkTextBlob_MakeFromString'>MakeFromString</a>(const char* string, const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint)
+static <a href='undocumented#sk_sp'>sk sp</a>&lt;<a href='#SkTextBlob'>SkTextBlob</a>&gt; <a href='#SkTextBlob_MakeFromString'>MakeFromString</a>(const char* string, const <a href='undocumented#SkFont'>SkFont</a>& font,
+                                       <a href='SkPaint_Reference#SkPaint_TextEncoding'>SkPaint::TextEncoding</a> encoding = <a href='SkPaint_Reference#SkPaint_kUTF8_TextEncoding'>SkPaint::kUTF8 TextEncoding</a>)
 </pre>
 
 Creates <a href='#Text_Blob'>Text Blob</a> with a single run. <a href='#SkTextBlob_MakeFromString_string'>string</a> meaning depends on <a href='SkPaint_Reference#Text_Encoding'>Paint Text Encoding</a>;
 by default, <a href='#SkTextBlob_MakeFromString_string'>string</a> is encoded as UTF-8.
 
-<a href='#SkTextBlob_MakeFromString_paint'>paint</a> contains <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> used to define the run text: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
+<a href='#SkTextBlob_MakeFromString_font'>font</a> contains <a href='SkPaint_Reference#Font_Metrics'>Paint Font Metrics</a> used to define the run text: <a href='undocumented#Typeface'>Typeface</a>, <a href='SkPaint_Reference#Text_Size'>Paint Text Size</a>, <a href='SkPaint_Reference#Text_Scale_X'>Paint Text Scale X</a>,
 <a href='SkPaint_Reference#Text_Skew_X'>Paint Text Skew X</a>, <a href='SkPaint_Reference#Text_Align'>Paint Text Align</a>, <a href='SkPaint_Reference#Hinting'>Paint Hinting</a>, <a href='SkPaint_Reference#Anti_Alias'>Anti Alias</a>, <a href='SkPaint_Reference#Fake_Bold'>Paint Fake Bold</a>,
 <a href='SkPaint_Reference#Font_Embedded_Bitmaps'>Font Embedded Bitmaps</a>, <a href='SkPaint_Reference#Full_Hinting_Spacing'>Full Hinting Spacing</a>, <a href='SkPaint_Reference#LCD_Text'>LCD Text</a>, <a href='SkPaint_Reference#Linear_Text'>Linear Text</a>,
 and <a href='SkPaint_Reference#Subpixel_Text'>Subpixel Text</a>.
@@ -134,9 +140,13 @@
 <table>  <tr>    <td><a name='SkTextBlob_MakeFromString_string'><code><strong>string</strong></code></a></td>
     <td>character code points or <a href='undocumented#Glyph'>Glyphs</a> drawn</td>
   </tr>
-  <tr>    <td><a name='SkTextBlob_MakeFromString_paint'><code><strong>paint</strong></code></a></td>
+  <tr>    <td><a name='SkTextBlob_MakeFromString_font'><code><strong>font</strong></code></a></td>
     <td>text size, typeface, text scale, and so on, used to draw</td>
   </tr>
+  <tr>    <td><a name='SkTextBlob_MakeFromString_encoding'><code><strong>encoding</strong></code></a></td>
+    <td>one of: <a href='undocumented#kUTF8_SkTextEncoding'>kUTF8_SkTextEncoding</a>, <a href='undocumented#kUTF16_SkTextEncoding'>kUTF16_SkTextEncoding</a>,
+<a href='undocumented#kUTF32_SkTextEncoding'>kUTF32_SkTextEncoding</a>, <a href='undocumented#kGlyphID_SkTextEncoding'>kGlyphID_SkTextEncoding</a></td>
+  </tr>
 </table>
 
 ### Return Value
@@ -145,7 +155,7 @@
 
 ### Example
 
-<div><fiddle-embed name="705b26bb5e361369d897eeb511b6a184"></fiddle-embed></div>
+<div><fiddle-embed name="a5af182e793eed3f2bb3b0efc2cf4852"></fiddle-embed></div>
 
 ### See Also
 
diff --git a/site/user/api/catalog.htm b/site/user/api/catalog.htm
index e1d8c8f..fb00cab 100644
--- a/site/user/api/catalog.htm
+++ b/site/user/api/catalog.htm
@@ -1582,13 +1582,6 @@
     "name": "SkPaint::getStyle",
         "stdout": "SkPaint::kFill_Style == paint.getStyle()\\n"
     },
-        "SkPaint_getTextAlign": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    SkDebugf(\"kLeft_Align %c= default\\n\", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');\n}",
-    "hash": "2df932f526e810f74c89d30ec3f4c947",
-    "file": "SkPaint_Reference",
-    "name": "SkPaint::getTextAlign",
-        "stdout": "kLeft_Align == default\\n"
-    },
         "SkPaint_getTextEncoding": {
     "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    SkDebugf(\"kUTF8_TextEncoding %c= text encoding\\n\",\n            SkPaint::kUTF8_TextEncoding == paint.getTextEncoding() ? '=' : '!');\n    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);\n    SkDebugf(\"kGlyphID_TextEncoding %c= text encoding\\n\",\n            SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding() ? '=' : '!');\n}",
     "hash": "c6cc2780a9828b3af8c4621c12b29a1b",
@@ -3891,114 +3884,114 @@
     "name": "Color_Constants_4"
 },
     "Illustrations_Blend_Mode_Overview_Color_Blends": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextAlign(SkPaint::kCenter_Align);\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,\n                        SkBlendMode::kLuminosity } ) {\n        canvas->drawString(\"&\", 50, 80, dstPaint);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);\n        canvas->translate(90, 0);\n    }\n}",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kHue, SkBlendMode::kSaturation, SkBlendMode::kColor,\n                        SkBlendMode::kLuminosity } ) {\n        SkTextUtils::DrawString(canvas, \"&\", 50, 80, dstPaint, SkPaint::kCenter_Align);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint,\n                SkPaint::kCenter_Align);\n        canvas->translate(90, 0);\n    }\n}\n",
     "width": 480,
     "height": 110,
-    "hash": "03710c1770728da885fa4ac24a19d5d1",
+    "hash": "6a95ff41078ca855131f8d8b4fde29f2",
     "file": "illustrations",
     "name": "Blend_Mode_Overview_Color_Blends"
 },
     "Illustrations_Blend_Mode_Overview_Lighten_Darken": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextAlign(SkPaint::kCenter_Align);\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kPlus, SkBlendMode::kScreen, SkBlendMode::kOverlay,\n            SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,\n            SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,\n            SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply } ) {\n        canvas->drawString(\"&\", 50, 80, dstPaint);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);\n        canvas->translate(90, 0);\n        if (SkBlendMode::kLighten == blend || SkBlendMode::kDifference == blend) {\n            canvas->translate(-90 * 5, 100);\n        }\n    }\n}",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kPlus, SkBlendMode::kScreen, SkBlendMode::kOverlay,\n            SkBlendMode::kDarken, SkBlendMode::kLighten, SkBlendMode::kColorDodge,\n            SkBlendMode::kColorBurn, SkBlendMode::kHardLight, SkBlendMode::kSoftLight,\n            SkBlendMode::kDifference, SkBlendMode::kExclusion, SkBlendMode::kMultiply } ) {\n        SkTextUtils::DrawString(canvas, \"&\", 50, 80, dstPaint, SkPaint::kCenter_Align);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);\n        canvas->translate(90, 0);\n        if (SkBlendMode::kLighten == blend || SkBlendMode::kDifference == blend) {\n            canvas->translate(-90 * 5, 100);\n        }\n    }\n}\n",
     "width": 480,
     "height": 330,
-    "hash": "8e04f89252632da0fffe713f07f2296f",
+    "hash": "39e81a69cd300e53976e815e5024398c",
     "file": "illustrations",
     "name": "Blend_Mode_Overview_Lighten_Darken"
 },
     "Illustrations_Blend_Mode_Overview_Modulate_Blend": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextAlign(SkPaint::kCenter_Align);\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    SkBitmap srcBits;\n    srcBits.allocN32Pixels(80, 84);\n    SkCanvas srcCanvas(srcBits);\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    srcBits.eraseColor(0);\n    srcCanvas.drawPath(srcPath, srcPaint);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    srcPaint.setBlendMode(SkBlendMode::kModulate);\n    for (auto step: { 1, 2 } ) {\n        canvas->drawString(\"&\", 50, 80, dstPaint);\n        if (1 == step) {\n            canvas->drawBitmap(srcBits, 0, 0, &srcPaint);\n            canvas->drawString(\"Bitmap\", 50, 18, labelPaint);\n        } else {\n            canvas->drawPath(srcPath, srcPaint);\n            canvas->drawString(\"Geometry\", 50, 18, labelPaint);\n        }\n        canvas->drawString(SkBlendMode_Name(SkBlendMode::kModulate), 50, 100, labelPaint);\n        canvas->translate(120, 0);\n    }\n}",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    SkBitmap srcBits;\n    srcBits.allocN32Pixels(80, 84);\n    SkCanvas srcCanvas(srcBits);\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    srcBits.eraseColor(0);\n    srcCanvas.drawPath(srcPath, srcPaint);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    srcPaint.setBlendMode(SkBlendMode::kModulate);\n    for (auto step: { 1, 2 } ) {\n        SkTextUtils::DrawString(canvas, \"&\", 50, 80, dstPaint, SkPaint::kCenter_Align);\n        if (1 == step) {\n            canvas->drawBitmap(srcBits, 0, 0, &srcPaint);\n            SkTextUtils::DrawString(canvas, \"Bitmap\", 50, 18, labelPaint, SkPaint::kCenter_Align);\n        } else {\n            canvas->drawPath(srcPath, srcPaint);\n            SkTextUtils::DrawString(canvas, \"Geometry\", 50, 18, labelPaint, SkPaint::kCenter_Align);\n        }\n        SkTextUtils::DrawString(canvas, SkBlendMode_Name(SkBlendMode::kModulate), 50, 100, labelPaint,\n                SkPaint::kCenter_Align);\n        canvas->translate(120, 0);\n    }\n}\n",
     "width": 480,
     "height": 110,
-    "hash": "d8abdd8fb56f9e69342d745d425c4a17",
+    "hash": "34840d6e411e78af50d4f5144296ef6a",
     "file": "illustrations",
     "name": "Blend_Mode_Overview_Modulate_Blend"
 },
     "Illustrations_Blend_Mode_Overview_Porter_Duff": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextAlign(SkPaint::kCenter_Align);\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    SkBitmap srcBits;\n    srcBits.allocN32Pixels(80, 84);\n    SkCanvas srcCanvas(srcBits);\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    srcBits.eraseColor(0);\n    srcCanvas.drawPath(srcPath, srcPaint);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,\n                        SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,\n                        SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,\n                        SkBlendMode::kDstIn, SkBlendMode::kDstOut,\n                        SkBlendMode::kClear, SkBlendMode::kXor } ) {\n        canvas->drawString(\"&\", 50, 80, dstPaint);\n        srcPaint.setBlendMode(blend);\n        canvas->drawBitmap(srcBits, 0, 0, &srcPaint);\n        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);\n        canvas->translate(80, 0);\n        if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {\n            canvas->translate(-80 * 5, 100);\n        }\n    }\n}",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    SkBitmap srcBits;\n    srcBits.allocN32Pixels(80, 84);\n    SkCanvas srcCanvas(srcBits);\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    srcBits.eraseColor(0);\n    srcCanvas.drawPath(srcPath, srcPaint);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,\n                        SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,\n                        SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,\n                        SkBlendMode::kDstIn, SkBlendMode::kDstOut,\n                        SkBlendMode::kClear, SkBlendMode::kXor } ) {\n        SkTextUtils::DrawString(canvas, \"&\", 50, 80, dstPaint, SkPaint::kCenter_Align);\n        srcPaint.setBlendMode(blend);\n        canvas->drawBitmap(srcBits, 0, 0, &srcPaint);\n        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);\n        canvas->translate(80, 0);\n        if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {\n            canvas->translate(-80 * 5, 100);\n        }\n    }\n}\n",
     "width": 480,
     "height": 330,
-    "hash": "8c27fb2a58f63505cffa74c1c79e16ba",
+    "hash": "ebb1f51cfbae33baefacb2e4196c9013",
     "file": "illustrations",
     "name": "Blend_Mode_Overview_Porter_Duff"
 },
     "Illustrations_Blend_Mode_Overview_Porter_Duff_2": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextAlign(SkPaint::kCenter_Align);\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    SkBitmap dstBits;\n    dstBits.allocN32Pixels(80, 80);\n    SkCanvas dstCanvas(dstBits);\n    for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,\n                        SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,\n                        SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,\n                        SkBlendMode::kDstIn, SkBlendMode::kDstOut,\n                        SkBlendMode::kClear, SkBlendMode::kXor } ) {\n        canvas->drawString(\"&\", 50, 80, dstPaint);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        canvas->drawString(SkBlendMode_Name(blend), 50, 100, labelPaint);\n        canvas->translate(80, 0);\n        if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {\n            canvas->translate(-80 * 5, 100);\n        }\n    }\n}",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint srcPaint;\n    srcPaint.setAntiAlias(true);\n    SkPaint labelPaint = srcPaint;\n    labelPaint.setTextSize(16);\n    SkPaint dstPaint = labelPaint;\n    dstPaint.setTextSize(80);\n    dstPaint.setColor(0xFF606080);\n    dstPaint.setTypeface(SkTypeface::MakeFromName(\"Roboto\", SkFontStyle::Bold()));\n    srcPaint.setColor(0xFFcc6633);\n    SkPath srcPath;\n    const SkPoint points[] = {{20, 20}, {80, 45}, {45, 80}};\n    srcPath.addPoly(points, SK_ARRAY_COUNT(points), true);\n    canvas->drawColor(0, SkBlendMode::kClear);\n    SkBitmap dstBits;\n    dstBits.allocN32Pixels(80, 80);\n    SkCanvas dstCanvas(dstBits);\n    for (auto blend : { SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcOver,\n                        SkBlendMode::kSrcIn, SkBlendMode::kSrcOut,\n                        SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstOver,\n                        SkBlendMode::kDstIn, SkBlendMode::kDstOut,\n                        SkBlendMode::kClear, SkBlendMode::kXor } ) {\n        SkTextUtils::DrawString(canvas, \"&\", 50, 80, dstPaint, SkPaint::kCenter_Align);\n        srcPaint.setBlendMode(blend);\n        canvas->drawPath(srcPath, srcPaint);\n        SkTextUtils::DrawString(canvas, SkBlendMode_Name(blend), 50, 100, labelPaint, SkPaint::kCenter_Align);\n        canvas->translate(80, 0);\n        if (SkBlendMode::kSrcOut == blend || SkBlendMode::kDstOut == blend) {\n            canvas->translate(-80 * 5, 100);\n        }\n    }\n}\n",
     "width": 480,
     "height": 330,
-    "hash": "50ebbb0162bbf60524a196236d66c915",
+    "hash": "8e87d55e01bb2bfd71361156d78dde0c",
     "file": "illustrations",
     "name": "Blend_Mode_Overview_Porter_Duff_2"
 },
     "Illustrations_Image_Info_Color_Type_ARGB_4444": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"16-bit word\", 5 + 20 * 8, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 4, 8, 12, 16 };\n    const char* labels[] = { \"red\", \"green\", \"blue\", \"alpha\" };\n    drawBoxText(&edges[0], &labels[0], 4, 15, 45);\n    drawBoxText(&edges[0], &labels[2], 2, 7, 110);\n    drawBoxText(&edges[0], &labels[0], 2, 7, 160);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"16-bit word\", 5 + 20 * 8, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 4, 8, 12, 16 };\n    const char* labels[] = { \"red\", \"green\", \"blue\", \"alpha\" };\n    drawBoxText(&edges[0], &labels[0], 4, 15, 45);\n    drawBoxText(&edges[0], &labels[2], 2, 7, 110);\n    drawBoxText(&edges[0], &labels[0], 2, 7, 160);\n}\n",
     "width": 415,
     "height": 250,
-    "hash": "0441bdba65a19aa72b75b7fa62d22121",
+    "hash": "bdc77b69231f1e1699e245944f1b239c",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_ARGB_4444"
 },
     "Illustrations_Image_Info_Color_Type_BGRA_8888": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"32-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"alpha\", \"red\", \"green\", \"blue\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"32-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"alpha\", \"red\", \"green\", \"blue\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
     "width": 812,
     "height": 365,
-    "hash": "babd0e12db21a88c74d4e88aa40268ab",
+    "hash": "743a950f1df07936e8a5fcb2a91208c4",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_BGRA_8888"
 },
     "Illustrations_Image_Info_Color_Type_RGBA_1010102": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"32-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 4, 137, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 3, 187, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 7, 187, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 2, 237, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 6, 237, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 5, 287, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 2, 12, 22, 32,\n                         0, 8,\n                         0, 6, 8,\n                         0, 4, 8,\n                         0, 2, 8\n                        };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 4, 31, 45);\n    drawBoxText(&edges[5], &labels[3], 1, 7, 110);\n    drawBoxText(&edges[7], &labels[2], 2, 7, 160);\n    drawBoxText(&edges[10], &labels[1], 2, 7, 210);\n    drawBoxText(&edges[13], &labels[0], 2, 7, 260);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"32-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 4, 137, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 3, 187, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 7, 187, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 2, 237, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 6, 237, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 5, 287, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 2, 12, 22, 32,\n                         0, 8,\n                         0, 6, 8,\n                         0, 4, 8,\n                         0, 2, 8\n                        };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 4, 31, 45);\n    drawBoxText(&edges[5], &labels[3], 1, 7, 110);\n    drawBoxText(&edges[7], &labels[2], 2, 7, 160);\n    drawBoxText(&edges[10], &labels[1], 2, 7, 210);\n    drawBoxText(&edges[13], &labels[0], 2, 7, 260);\n}\n",
     "width": 812,
     "height": 380,
-    "hash": "6c470410001ad8f1ee9f58204c66f1bb",
+    "hash": "2ee75d2bd4e59dc7ab97a96d86fd9bfc",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGBA_1010102"
 },
     "Illustrations_Image_Info_Color_Type_RGBA_8888": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"32-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"32-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
     "width": 812,
     "height": 365,
-    "hash": "4ccd35f27fe73dce8cce8c75e18df23c",
+    "hash": "98d5232ae83a71fecf35713bcd635fdc",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGBA_8888"
 },
     "Illustrations_Image_Info_Color_Type_RGBA_F16": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"64-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 135, paint);\n    for (int i = 0; i < 4; ++i) {\n        canvas->drawString(\"(low bits)\", 5 + 20 * 4, 187 + i * 100, paint);\n        canvas->drawString(\"(high bits)\", 5 + 20 * 4, 237 + i * 100, paint);\n    }\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 16, 32,\n                         0, 8\n                       };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 2, 63, 45);\n    drawBoxText(&edges[0], &labels[2], 2, 31, 95);\n    drawBoxText(&edges[3], &labels[3], 1, 7, 160);\n    drawBoxText(&edges[3], &labels[3], 1, 7, 210);\n    drawBoxText(&edges[3], &labels[2], 1, 7, 260);\n    drawBoxText(&edges[3], &labels[2], 1, 7, 310);\n    drawBoxText(&edges[3], &labels[1], 1, 7, 360);\n    drawBoxText(&edges[3], &labels[1], 1, 7, 410);\n    drawBoxText(&edges[3], &labels[0], 1, 7, 460);\n    drawBoxText(&edges[3], &labels[0], 1, 7, 510);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"64-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 135, paint, SkPaint::kCenter_Align);\n    for (int i = 0; i < 4; ++i) {\n        SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 4, 187 + i * 100, paint, SkPaint::kCenter_Align);\n        SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 4, 237 + i * 100, paint, SkPaint::kCenter_Align);\n    }\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 16, 32,\n                         0, 8\n                       };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 2, 63, 45);\n    drawBoxText(&edges[0], &labels[2], 2, 31, 95);\n    drawBoxText(&edges[3], &labels[3], 1, 7, 160);\n    drawBoxText(&edges[3], &labels[3], 1, 7, 210);\n    drawBoxText(&edges[3], &labels[2], 1, 7, 260);\n    drawBoxText(&edges[3], &labels[2], 1, 7, 310);\n    drawBoxText(&edges[3], &labels[1], 1, 7, 360);\n    drawBoxText(&edges[3], &labels[1], 1, 7, 410);\n    drawBoxText(&edges[3], &labels[0], 1, 7, 460);\n    drawBoxText(&edges[3], &labels[0], 1, 7, 510);\n}\n",
     "width": 812,
     "height": 685,
-    "hash": "9344796c059ff5e4f057595e781905b3",
+    "hash": "adc8262f27f1ac048984b4cbff9334ac",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGBA_F16"
 },
     "Illustrations_Image_Info_Color_Type_RGBA_F32": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"128-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 135, paint);\n    for (int i = 0; i < 4; ++i) {\n        canvas->drawString(\"(low bits)\", 5 + 10 * 4, 187 + i * 100, paint);\n        canvas->drawString(\"(high bits)\", 105 + 10 * 4, 237 + i * 100, paint);\n    }\n    auto drawBoxText = [=](SkScalar e[], const char* s[], const char* nums[] , \n             int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int stringIndex = 0;\n        for (int i = n; i >= 0; --i) {\n            if (0 == i || n == i || 32 == i || 31 == i) {\n                int x = xPos;\n                if (2 == count) {\n                    x += stringIndex * 12 + (stringIndex ? 8 : 0);\n                }\n                canvas->drawString(nums[stringIndex], x, yPos - 5, p);\n                if (1 == count) {\n                    canvas->drawString(nums[stringIndex], xPos + 100, yPos - 5, p);\n                }\n                ++stringIndex;\n            }\n            xPos += 9;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 5, yPos + 10, p);\n            if (1 == count) {\n                canvas->drawString(s[i], 105 + (e[i] + e[i + 1]) * 5, yPos + 10, p);\n            }\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 10, yPos, 5 + e[i] * 10, yPos + 15, p);\n            if (1 == count) {\n                canvas->drawLine(105 + e[i] * 10, yPos, 105 + e[i] * 10, yPos + 15, p);\n            }\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 10, yPos + i * 15,\n                             5 + e[count] * 10, yPos + i * 15, p);\n            if (1 == count) {\n                canvas->drawLine(105 + e[0] * 10, yPos + i * 15,\n                                 105 + e[count] * 10, yPos + i * 15, p);\n            }\n        }\n    };\n    SkScalar edges[] = { 0, 32, 64,\n                         0, 8\n                       };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    const char* nums128[] = { \"127\", \"96\", \"95\", \"64\"};\n    const char* nums64[] = { \"63\", \"32\", \"31\", \"0\"};\n    const char* nums8[] = { \"7\", \"0\"};\n    drawBoxText(&edges[0], &labels[0], nums128, 2, 63, 45);\n    drawBoxText(&edges[0], &labels[2], nums64, 2, 63, 95);\n    drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 160);\n    drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 210);\n    drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 260);\n    drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 310);\n    drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 360);\n    drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 410);\n    drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 460);\n    drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 510);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"128-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 135, paint, SkPaint::kCenter_Align);\n    for (int i = 0; i < 4; ++i) {\n        SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 10 * 4, 187 + i * 100, paint, SkPaint::kCenter_Align);\n        SkTextUtils::DrawString(canvas, \"(high bits)\", 105 + 10 * 4, 237 + i * 100, paint, SkPaint::kCenter_Align);\n    }\n    auto drawBoxText = [=](SkScalar e[], const char* s[], const char* nums[] , \n             int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int stringIndex = 0;\n        for (int i = n; i >= 0; --i) {\n            if (0 == i || n == i || 32 == i || 31 == i) {\n                int x = xPos;\n                if (2 == count) {\n                    x += stringIndex * 12 + (stringIndex ? 8 : 0);\n                }\n                SkTextUtils::DrawString(canvas, nums[stringIndex], x, yPos - 5, p, SkPaint::kCenter_Align);\n                if (1 == count) {\n                    SkTextUtils::DrawString(canvas, nums[stringIndex], xPos + 100, yPos - 5, p, SkPaint::kCenter_Align);\n                }\n                ++stringIndex;\n            }\n            xPos += 9;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 5, yPos + 10, p, SkPaint::kCenter_Align);\n            if (1 == count) {\n                SkTextUtils::DrawString(canvas, s[i], 105 + (e[i] + e[i + 1]) * 5, yPos + 10, p, SkPaint::kCenter_Align);\n            }\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 10, yPos, 5 + e[i] * 10, yPos + 15, p);\n            if (1 == count) {\n                canvas->drawLine(105 + e[i] * 10, yPos, 105 + e[i] * 10, yPos + 15, p);\n            }\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 10, yPos + i * 15,\n                             5 + e[count] * 10, yPos + i * 15, p);\n            if (1 == count) {\n                canvas->drawLine(105 + e[0] * 10, yPos + i * 15,\n                                 105 + e[count] * 10, yPos + i * 15, p);\n            }\n        }\n    };\n    SkScalar edges[] = { 0, 32, 64,\n                         0, 8\n                       };\n    const char* labels[] = { \"alpha\", \"blue\", \"green\", \"red\" };\n    const char* nums128[] = { \"127\", \"96\", \"95\", \"64\"};\n    const char* nums64[] = { \"63\", \"32\", \"31\", \"0\"};\n    const char* nums8[] = { \"7\", \"0\"};\n    drawBoxText(&edges[0], &labels[0], nums128, 2, 63, 45);\n    drawBoxText(&edges[0], &labels[2], nums64, 2, 63, 95);\n    drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 160);\n    drawBoxText(&edges[3], &labels[3], nums8, 1, 7, 210);\n    drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 260);\n    drawBoxText(&edges[3], &labels[2], nums8, 1, 7, 310);\n    drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 360);\n    drawBoxText(&edges[3], &labels[1], nums8, 1, 7, 410);\n    drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 460);\n    drawBoxText(&edges[3], &labels[0], nums8, 1, 7, 510);\n}\n",
     "width": 812,
     "height": 685,
-    "hash": "b26119f9312d5f5d4011bf2dac94fafe",
+    "hash": "36efa3247a841d0a46aee987a05e9fc2",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGBA_F32"
 },
     "Illustrations_Image_Info_Color_Type_RGB_101010": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"32-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 4, 137, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 3, 187, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 7, 187, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 2, 237, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 6, 237, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 5, 287, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 2, 12, 22, 32,\n                         0, 8,\n                         0, 6, 8,\n                         0, 4, 8,\n                         0, 2, 8\n                        };\n    const char* labels[] = { \"unused\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 4, 31, 45);\n    drawBoxText(&edges[5], &labels[3], 1, 7, 110);\n    drawBoxText(&edges[7], &labels[2], 2, 7, 160);\n    drawBoxText(&edges[10], &labels[1], 2, 7, 210);\n    drawBoxText(&edges[13], &labels[0], 2, 7, 260);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"32-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 4, 137, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 3, 187, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 7, 187, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 2, 237, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 6, 237, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 5, 287, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 2, 12, 22, 32,\n                         0, 8,\n                         0, 6, 8,\n                         0, 4, 8,\n                         0, 2, 8\n                        };\n    const char* labels[] = { \"unused\", \"blue\", \"green\", \"red\" };\n    drawBoxText(&edges[0], &labels[0], 4, 31, 45);\n    drawBoxText(&edges[5], &labels[3], 1, 7, 110);\n    drawBoxText(&edges[7], &labels[2], 2, 7, 160);\n    drawBoxText(&edges[10], &labels[1], 2, 7, 210);\n    drawBoxText(&edges[13], &labels[0], 2, 7, 260);\n}\n",
     "width": 812,
     "height": 380,
-    "hash": "c22477b11dabaa3e3a0b5bb33a7733cd",
+    "hash": "719fea0149e040ac1178fe298d4f7c7a",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGB_101010"
 },
     "Illustrations_Image_Info_Color_Type_RGB_565": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"16-bit word\", 5 + 20 * 8, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    canvas->drawString(\"(low bits)\", 5 + 20 * 1.5f, 137, paint);\n    canvas->drawString(\"(high bits)\", 5 + 20 * 6.5f, 187, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 5, 11, 16,\n                         0, 3, 8,\n                         0, 5, 8 };\n    const char* labels[] = { \"red\", \"green\", \"blue\" };\n    drawBoxText(&edges[0], &labels[0], 3, 15, 45);\n    drawBoxText(&edges[4], &labels[1], 2, 7, 110);\n    drawBoxText(&edges[7], &labels[0], 2, 7, 160);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"16-bit word\", 5 + 20 * 8, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(low bits)\", 5 + 20 * 1.5f, 137, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"(high bits)\", 5 + 20 * 6.5f, 187, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 5, 11, 16,\n                         0, 3, 8,\n                         0, 5, 8 };\n    const char* labels[] = { \"red\", \"green\", \"blue\" };\n    drawBoxText(&edges[0], &labels[0], 3, 15, 45);\n    drawBoxText(&edges[4], &labels[1], 2, 7, 110);\n    drawBoxText(&edges[7], &labels[0], 2, 7, 160);\n}\n",
     "width": 415,
     "height": 250,
-    "hash": "f5981f4d2337dc5b6ee2d1d0c2a05078",
+    "hash": "21e703b1aba5f2404f94f3db34d4f7cb",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGB_565"
 },
     "Illustrations_Image_Info_Color_Type_RGB_888": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"32-bit word\", 5 + 20 * 16, 20, paint);\n    canvas->drawString(\"little endian byte order\", 5 + 20 * 4, 85, paint);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"(unused)\", \"blue\", \"green\", \"red\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    canvas->scale(1.25f, 1.25f);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(10);\n    SkTextUtils::DrawString(canvas, \"32-bit word\", 5 + 20 * 16, 20, paint, SkPaint::kCenter_Align);\n    SkTextUtils::DrawString(canvas, \"little endian byte order\", 5 + 20 * 4, 85, paint, SkPaint::kCenter_Align);\n    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {\n        SkPaint p(paint);\n        p.setColor(SK_ColorRED);\n        SkScalar xPos = 15;\n        int width = n % 32 + 1;\n        int lastN = n > 32 ? 32 : 0;\n        for (; n >= lastN; --n) {\n            for (int i = 0; i <= count; ++i) {\n                int a = width - e[i];\n                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {\n                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\\0'};\n                    SkTextUtils::DrawString(canvas, n >= 10 ? num : &num[1], xPos, yPos - 5, p, SkPaint::kCenter_Align);\n                    break;\n                }\n            }\n            xPos += 20;\n        }\n        p.setColor(SK_ColorBLACK);\n        for (int i = 0; i < count; ++i) {\n            SkTextUtils::DrawString(canvas, s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p, SkPaint::kCenter_Align);\n        }\n        p.setStyle(SkPaint::kStroke_Style);\n        for (int i = 0; i <= count; ++i) {\n            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);\n        }\n        for (int i = 0; i < 2; ++i) {\n            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);\n        }\n    };\n    SkScalar edges[] = { 0, 8, 16, 24, 32 };\n    const char* labels[] = { \"(unused)\", \"blue\", \"green\", \"red\" };\n    drawBoxText(edges, &labels[0], 4, 31, 45);\n    drawBoxText(edges, &labels[3], 1, 7, 110);\n    drawBoxText(edges, &labels[2], 1, 7, 160);\n    drawBoxText(edges, &labels[1], 1, 7, 210);\n    drawBoxText(edges, &labels[0], 1, 7, 260);\n}\n",
     "width": 812,
     "height": 365,
-    "hash": "fecfe58c25cfc1b1e411e5eb50f7d8d1",
+    "hash": "a11d984d5880664ca15dbac5beed44a3",
     "file": "illustrations",
     "name": "Image_Info_Color_Type_RGB_888"
 },
@@ -4267,10 +4260,10 @@
     "name": "Stroke_Width"
 },
     "Paint_Text_Align": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setTextSize(40);\n    SkPoint position[] = {{100, 50}, {150, 40}};\n    for (SkPaint::Align a : { SkPaint::kLeft_Align,\n                              SkPaint::kCenter_Align,\n                              SkPaint::kRight_Align}) {\n        paint.setTextAlign(a);\n        canvas->drawPosText(\"Aa\", 2, position, paint);\n        canvas->translate(0, 50);\n    }\n}\n",
+    "code": "#include \"SkTextUtils.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setTextSize(40);\n    for (SkPaint::Align a : { SkPaint::kLeft_Align,\n                              SkPaint::kCenter_Align,\n                              SkPaint::kRight_Align}) {\n        SkTextUtils::DrawString(canvas, \"Aa\", 100, 50, paint, a);\n        canvas->translate(0, 50);\n    }\n}\n",
     "width": 256,
     "height": 160,
-    "hash": "702617fd9ebc3f12e30081b5db93e8a8",
+    "hash": "6ee1866e4da0064d9d340b07e05f0aca",
     "file": "SkPaint_Reference",
     "name": "Text_Align"
 },
@@ -5115,10 +5108,10 @@
     "name": "SkCanvas::drawPatch"
 },
     "SkCanvas_drawPatch_2": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    SkPoint cubics[] = { { 3, 1 },    { 4, 2 }, { 5, 1 },    { 7, 3 },\n                      /* { 7, 3 }, */ { 6, 4 }, { 7, 5 },    { 5, 7 },\n                      /* { 5, 7 }, */ { 4, 6 }, { 3, 7 },    { 1, 5 },\n                      /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };\n    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };\n    canvas->scale(30, 30);\n    canvas->drawPatch(cubics, colors, nullptr, paint);\n    SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},\n            {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},\n            {0.5f,3.2f} };\n    paint.setTextSize(18.f / 30);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    for (int i = 0; i< 10; ++i) {\n       char digit = '0' + i;\n       canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);\n    }\n    canvas->drawString(\"10\", text[10].fX, text[10].fY, paint);\n    canvas->drawString(\"11\", text[11].fX, text[11].fY, paint);\n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);\n    canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    SkPoint cubics[] = { { 3, 1 },    { 4, 2 }, { 5, 1 },    { 7, 3 },\n                      /* { 7, 3 }, */ { 6, 4 }, { 7, 5 },    { 5, 7 },\n                      /* { 5, 7 }, */ { 4, 6 }, { 3, 7 },    { 1, 5 },\n                      /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };\n    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };\n    canvas->scale(30, 30);\n    canvas->drawPatch(cubics, colors, nullptr, paint);\n    SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},\n            {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},\n            {0.5f,3.2f} };\n    paint.setTextSize(18.f / 30);\n    for (int i = 0; i< 10; ++i) {\n       char digit = '0' + i;\n       canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);\n    }\n    canvas->drawString(\"10\", text[10].fX, text[10].fY, paint);\n    canvas->drawString(\"11\", text[11].fX, text[11].fY, paint);\n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);\n    canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);\n}\n",
     "width": 256,
     "height": 256,
-    "hash": "4cf70f8d194867d053d7e177e5088445",
+    "hash": "4e8b7409531c9211a2afcf632005a38c",
     "file": "SkCanvas_Reference",
     "name": "SkCanvas::drawPatch_2"
 },
@@ -5283,10 +5276,10 @@
     "name": "SkCanvas::drawTextBlob_2"
 },
     "SkCanvas_drawTextRSXform": {
-    "code": "void draw(SkCanvas* canvas) {\n    const int iterations = 26;\n    SkRSXform transforms[iterations];\n    char alphabet[iterations];\n    SkScalar angle = 0;\n    SkScalar scale = 1;\n    for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {\n        const SkScalar s = SkScalarSin(angle) * scale;\n        const SkScalar c = SkScalarCos(angle) * scale;\n        transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);\n        angle += .45;\n        scale += .2;\n        alphabet[i] = 'A' + i;\n    }\n    SkPaint paint;\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->translate(110, 138);\n    canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    const int iterations = 26;\n    SkRSXform transforms[iterations];\n    char alphabet[iterations];\n    SkScalar angle = 0;\n    SkScalar scale = 1;\n    for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {\n        const SkScalar s = SkScalarSin(angle) * scale;\n        const SkScalar c = SkScalarCos(angle) * scale;\n        transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);\n        angle += .45;\n        scale += .2;\n        alphabet[i] = 'A' + i;\n    }\n    SkPaint paint;\n    canvas->translate(110, 138);\n    canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);\n}\n",
     "width": 256,
     "height": 256,
-    "hash": "3ce367af833428b08e75d8a22fe67808",
+    "hash": "935c8f8b9782d297a73d7186f6ef7945",
     "file": "SkCanvas_Reference",
     "name": "SkCanvas::drawTextRSXform"
 },
@@ -5963,18 +5956,18 @@
     "name": "SkImageInfo::SkImageInfo()"
 },
     "SkImageInfo_gammaCloseToSRGB": {
-    "code": "void draw(SkCanvas* canvas) {\n    const int width = 256;\n    const int height = 64;\n    auto drawLabel = [=](const char* what, bool closeToSRGB) -> void {\n        SkString string;\n        string.printf(\"%s gamma is %s\" \"close to sRGB\", what, closeToSRGB ? \"\" : \"not \");\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawString(string, width / 2, 56, paint);\n    };\n    SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };\n    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };\n    SkPaint gradPaint;\n    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,\n                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));\n    canvas->drawRect(SkRect::MakeWH(width, height), gradPaint);\n    drawLabel(\"canvas\", canvas->imageInfo().gammaCloseToSRGB());\n    SkBitmap bitmap;\n    SkImageInfo offscreenInfo = SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType);\n    bitmap.allocPixels(offscreenInfo);\n    SkCanvas sRGBOffscreen(bitmap);\n    sRGBOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"offscreen\", offscreenInfo.gammaCloseToSRGB());\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    const int width = 256;\n    const int height = 64;\n    auto drawLabel = [=](const char* what, bool closeToSRGB) -> void {\n        SkString string;\n        string.printf(\"%s gamma is %s\" \"close to sRGB\", what, closeToSRGB ? \"\" : \"not \");\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        canvas->drawString(string, 20, 56, paint);\n    };\n    SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };\n    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };\n    SkPaint gradPaint;\n    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,\n                    SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));\n    canvas->drawRect(SkRect::MakeWH(width, height), gradPaint);\n    drawLabel(\"canvas\", canvas->imageInfo().gammaCloseToSRGB());\n    SkBitmap bitmap;\n    SkImageInfo offscreenInfo = SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType);\n    bitmap.allocPixels(offscreenInfo);\n    SkCanvas sRGBOffscreen(bitmap);\n    sRGBOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"offscreen\", offscreenInfo.gammaCloseToSRGB());\n}",
     "width": 256,
     "height": 144,
-    "hash": "dcdc308a1a2089db47b8375178491832",
+    "hash": "22df72732e898a11773fbfe07388a546",
     "file": "SkImageInfo_Reference",
     "name": "SkImageInfo::gammaCloseToSRGB"
 },
     "SkImageInfo_height": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 20);\n    canvas->drawBitmap(source, 0, 0);\n    SkImageInfo imageInfo = source.info();\n    SkPaint paint;\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawLine(imageInfo.width() + 10, 0, imageInfo.width() + 10, imageInfo.height(), paint);\n    canvas->drawString(\"height\", imageInfo.width() + 34, imageInfo.height() / 2, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 20);\n    canvas->drawBitmap(source, 0, 0);\n    SkImageInfo imageInfo = source.info();\n    SkPaint paint;\n    canvas->drawLine(imageInfo.width() + 10, 0, imageInfo.width() + 10, imageInfo.height(), paint);\n    canvas->drawString(\"height\", imageInfo.width() + 15, imageInfo.height() / 2, paint);\n}",
     "width": 256,
     "height": 96,
-    "hash": "b79ea956d4cb89a483bfa48bba09df85",
+    "hash": "72c35baaeddca1d912edf93d19429c8e",
     "file": "SkImageInfo_Reference",
     "name": "SkImageInfo::height()"
 },
@@ -5987,10 +5980,10 @@
     "name": "SkImageInfo::makeAlphaType"
 },
     "SkImageInfo_makeColorSpace": {
-    "code": "void draw(SkCanvas* canvas) {\n    const int width = 256;\n    const int height = 64;\n    auto drawLabel = [=](const char* what, bool closeToSRGB) -> void {\n        SkString string;\n        string.printf(\"%s gamma is %s\" \"close to sRGB\", what, closeToSRGB ? \"\" : \"not \");\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawString(string, width / 2, 56, paint);\n    };\n    SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };\n    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };\n    SkPaint gradPaint;\n    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,\n            SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));\n    canvas->drawRect(SkRect::MakeWH(width, height), gradPaint);\n    drawLabel(\"canvas\", canvas->imageInfo().gammaCloseToSRGB());\n    SkBitmap bitmap;\n    SkImageInfo offscreenInfo = SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType);\n    bitmap.allocPixels(offscreenInfo);\n    SkCanvas sRGBOffscreen(bitmap);\n    sRGBOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"offscreen\", offscreenInfo.gammaCloseToSRGB());\n    SkImageInfo linearGamma =\n            offscreenInfo.makeColorSpace(offscreenInfo.colorSpace()->makeLinearGamma());\n    bitmap.allocPixels(linearGamma);\n    SkCanvas lgOffscreen(bitmap);\n    lgOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"linear\", linearGamma.gammaCloseToSRGB());\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    const int width = 256;\n    const int height = 64;\n    auto drawLabel = [=](const char* what, bool closeToSRGB) -> void {\n        SkString string;\n        string.printf(\"%s gamma is %s\" \"close to sRGB\", what, closeToSRGB ? \"\" : \"not \");\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        canvas->drawString(string, 20, 56, paint);\n    };\n    SkColor  gradColors[] = { 0xFFFF7F00, 0xFF00FF7F,  0xFF0000FF, 0xFF7F7FFF };\n    SkPoint  gradPoints[] = { { 0, 0 }, { width, 0 }, { width * 2, 0 }, { width * 3, 0 } };\n    SkPaint gradPaint;\n    gradPaint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,\n            SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));\n    canvas->drawRect(SkRect::MakeWH(width, height), gradPaint);\n    drawLabel(\"canvas\", canvas->imageInfo().gammaCloseToSRGB());\n    SkBitmap bitmap;\n    SkImageInfo offscreenInfo = SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType);\n    bitmap.allocPixels(offscreenInfo);\n    SkCanvas sRGBOffscreen(bitmap);\n    sRGBOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"offscreen\", offscreenInfo.gammaCloseToSRGB());\n    SkImageInfo linearGamma =\n            offscreenInfo.makeColorSpace(offscreenInfo.colorSpace()->makeLinearGamma());\n    bitmap.allocPixels(linearGamma);\n    SkCanvas lgOffscreen(bitmap);\n    lgOffscreen.drawRect(SkRect::MakeWH(width, height), gradPaint);\n    canvas->translate(0, 80);\n    canvas->drawBitmap(bitmap, 0, 0);\n    drawLabel(\"linear\", linearGamma.gammaCloseToSRGB());\n}",
     "width": 256,
     "height": 224,
-    "hash": "454add968099811053e2b372238472e3",
+    "hash": "fe3c5a755d3dde29bba058a583f18901",
     "file": "SkImageInfo_Reference",
     "name": "SkImageInfo::makeColorSpace"
 },
@@ -6011,10 +6004,10 @@
     "name": "SkImageInfo::makeWH"
 },
     "SkImageInfo_width": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawBitmap(source, 0, 0);\n    SkImageInfo imageInfo = source.info();\n    canvas->translate(0, imageInfo.height());\n    SkPaint paint;\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawLine(0, 10, imageInfo.width(), 10, paint);\n    canvas->drawString(\"width\", imageInfo.width() / 2, 25, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawBitmap(source, 0, 0);\n    SkImageInfo imageInfo = source.info();\n    canvas->translate(0, imageInfo.height());\n    SkPaint paint;\n    canvas->drawLine(0, 10, imageInfo.width(), 10, paint);\n    canvas->drawString(\"width\", imageInfo.width() / 2 - 15, 25, paint);\n}",
     "width": 256,
     "height": 96,
-    "hash": "588a0a763d78c1b3b3ea0b2a6e39fda6",
+    "hash": "e2491817695290d0218be77f091b8460",
     "file": "SkImageInfo_Reference",
     "name": "SkImageInfo::width()"
 },
@@ -6179,10 +6172,10 @@
     "name": "SkImage::getBackendTexture"
 },
     "SkImage_height": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawImage(image, 0, 0);\n    canvas->translate(image->width(), 0);\n    SkPaint paint;\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawLine(10, 0, 10, image->height(), paint);\n    canvas->drawString(\"height\", 34, image->height() / 2, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawImage(image, 0, 0);\n    canvas->translate(image->width(), 0);\n    SkPaint paint;\n    canvas->drawLine(10, 0, 10, image->height(), paint);\n    canvas->drawString(\"height\", 34, image->height() / 2, paint);\n}",
     "width": 256,
     "height": 96,
-    "hash": "60a063a2b210915f38401c83d4dba9e6",
+    "hash": "a4f53a0b6ac85e7bc3887245b728530d",
     "file": "SkImage_Reference",
     "name": "SkImage::height()"
 },
@@ -6195,26 +6188,26 @@
     "name": "SkImage::isLazyGenerated"
 },
     "SkImage_isLazyGenerated_a": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, image->width() / 2, image->height() / 4, paint);\n        canvas->drawString(\n                image->isLazyGenerated() ? \"is lazily generated\" : \"not lazily generated\",\n                image->width() / 2, image->height() * 3 / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, 30, image->height() / 4, paint);\n        canvas->drawString(\n                image->isLazyGenerated() ? \"is lazily generated\" : \"not lazily generated\",\n                20, image->height() * 3 / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}\n",
     "width": 256,
     "height": 256,
-    "hash": "25305461b916baf40d7d379e04a5589c",
+    "hash": "f031c2a53f6a57833dc0127e674553da",
     "file": "SkImage_Reference",
     "name": "SkImage::isLazyGenerated_2"
 },
     "SkImage_isTextureBacked": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, image->width() / 2, image->height() / 4, paint);\n        canvas->drawString(image->isTextureBacked() ? \"is GPU texture\" : \"not GPU texture\",\n                           image->width() / 2, image->height() * 3 / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, 30, image->height() / 4, paint);\n        canvas->drawString(image->isTextureBacked() ? \"is GPU texture\" : \"not GPU texture\",\n                           20, image->height() * 3 / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
     "width": 256,
     "height": 256,
-    "hash": "27a0ab44659201f1aa2ac7fea73368c2",
+    "hash": "9cf5c62a3d2243e6577ae563f360ea9d",
     "file": "SkImage_Reference",
     "name": "SkImage::isTextureBacked"
 },
     "SkImage_isValid": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, image->width() / 2, image->height() / 4, paint);\n        if (canvas->getGrContext()) {\n            canvas->drawString(image->isValid(canvas->getGrContext()) ? \"is valid on GPU\" :\n                    \"not valid on GPU\", image->width() / 2, image->height() * 5 / 8, paint);\n        }\n        canvas->drawString(image->isValid(nullptr) ? \"is valid on CPU\" :\n                \"not valid on CPU\", image->width() / 2, image->height() * 7 / 8, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        canvas->drawImage(image, 0, 0);\n        canvas->drawString(label, image->width() / 2, image->height() / 4, paint);\n        if (canvas->getGrContext()) {\n            canvas->drawString(image->isValid(canvas->getGrContext()) ? \"is valid on GPU\" :\n                    \"not valid on GPU\", 20, image->height() * 5 / 8, paint);\n        }\n        canvas->drawString(image->isValid(nullptr) ? \"is valid on CPU\" :\n                \"not valid on CPU\", 20, image->height() * 7 / 8, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
     "width": 256,
     "height": 256,
-    "hash": "8f7281446008cf4a9910fe73f44fa8d6",
+    "hash": "afc62f38aebc56af8e425297ec67dd37",
     "file": "SkImage_Reference",
     "name": "SkImage::isValid"
 },
@@ -6227,18 +6220,18 @@
     "name": "SkImage::makeColorSpace"
 },
     "SkImage_makeNonTextureImage": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        sk_sp<SkImage> nonTexture(image->makeNonTextureImage());\n        canvas->drawImage(nonTexture, 0, 0);\n        canvas->drawString(label, nonTexture->width() / 2, nonTexture->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        sk_sp<SkImage> nonTexture(image->makeNonTextureImage());\n        canvas->drawImage(nonTexture, 0, 0);\n        canvas->drawString(label, 20, nonTexture->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
     "width": 256,
     "height": 256,
-    "hash": "c77bfb00fb82e378eea4b7f7c18a8b84",
+    "hash": "ecdbaff44a02c310ef672b7d393c6dea",
     "file": "SkImage_Reference",
     "name": "SkImage::makeNonTextureImage"
 },
     "SkImage_makeRasterImage": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        sk_sp<SkImage> raster(image->makeRasterImage());\n        canvas->drawImage(raster, 0, 0);\n        canvas->drawString(label, raster->width() / 2, raster->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, const char* label) -> void {\n        if (nullptr == image) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        sk_sp<SkImage> raster(image->makeRasterImage());\n        canvas->drawImage(raster, 0, 0);\n        canvas->drawString(label, 20, raster->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(canvas->getGrContext(), backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, \"backEndTexture\");\n}",
     "width": 256,
     "height": 256,
-    "hash": "505a6d9458394b1deb5d2f6c44e1cd76",
+    "hash": "aed5f399915d40bb5d133ab586e5bac3",
     "file": "SkImage_Reference",
     "name": "SkImage::makeRasterImage"
 },
@@ -6267,10 +6260,10 @@
     "name": "SkImage::makeSubset"
 },
     "SkImage_makeTextureImage": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, GrContext* context, const char* label) -> void {\n        if (nullptr == image || nullptr == context) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));\n        canvas->drawImage(texture, 0, 0);\n        canvas->drawString(label, texture->width() / 2, texture->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    GrContext* context = canvas->getGrContext();\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(context, backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, context, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, context, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, context, \"backEndTexture\");\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawImage = [=](sk_sp<SkImage> image, GrContext* context, const char* label) -> void {\n        if (nullptr == image || nullptr == context) {\n            return;\n        }\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        sk_sp<SkImage> texture(image->makeTextureImage(context, nullptr));\n        canvas->drawImage(texture, 0, 0);\n        canvas->drawString(label, 20, texture->height() / 4, paint);\n    };\n    sk_sp<SkImage> bitmapImage(SkImage::MakeFromBitmap(source));\n    GrContext* context = canvas->getGrContext();\n    sk_sp<SkImage> textureImage(SkImage::MakeFromTexture(context, backEndTexture,\n                                kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,\n                                kOpaque_SkAlphaType, nullptr));\n    drawImage(image, context, \"image\");\n    canvas->translate(image->width(), 0);\n    drawImage(bitmapImage, context, \"source\");\n    canvas->translate(-image->width(), image->height());\n    drawImage(textureImage, context, \"backEndTexture\");\n}",
     "width": 256,
     "height": 256,
-    "hash": "b14d9debfe87295373b44a179992a999",
+    "hash": "eeec9e07e604b44d0208899a2fe5bef5",
     "file": "SkImage_Reference",
     "name": "SkImage::makeTextureImage"
 },
@@ -6331,10 +6324,10 @@
     "name": "SkImage::uniqueID"
 },
     "SkImage_width": {
-    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawImage(image, 0, 0);\n    canvas->translate(0, image->height());\n    SkPaint paint;\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawLine(0, 10, image->width(), 10, paint);\n    canvas->drawString(\"width\", image->width() / 2, 25, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    canvas->translate(10, 10);\n    canvas->drawImage(image, 0, 0);\n    canvas->translate(0, image->height());\n    SkPaint paint;\n    canvas->drawLine(0, 10, image->width(), 10, paint);\n    canvas->drawString(\"width\", image->width() / 2 - 15, 25, paint);\n}",
     "width": 256,
     "height": 96,
-    "hash": "39a6d0bbeac6d957c2338e0bff865cf8",
+    "hash": "9aec65fc252ffc9982fa8867433eca18",
     "file": "SkImage_Reference",
     "name": "SkImage::width()"
 },
@@ -7298,14 +7291,6 @@
     "file": "SkPaint_Reference",
     "name": "SkPaint::setStyle"
 },
-    "SkPaint_setTextAlign": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setTextSize(40);\n    canvas->drawString(\"Aa\", 100, 50, paint);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"Aa\", 100, 100, paint);\n    paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);\n    canvas->drawString(\"Aa\", 100, 150, paint);\n}\n",
-    "width": 256,
-    "height": 160,
-    "hash": "d37540afd918506ac2594665ca63979b",
-    "file": "SkPaint_Reference",
-    "name": "SkPaint::setTextAlign"
-},
     "SkPaint_setTypeface": {
     "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setTypeface(SkTypeface::MakeFromName(\"monospace\", SkFontStyle()));\n    canvas->drawString(\"hamburgerfons\", 10, 30, paint);\n    paint.setTypeface(nullptr);\n    canvas->drawString(\"hamburgerfons\", 10, 50, paint);\n}\n",
     "width": 256,
@@ -7355,10 +7340,10 @@
     "name": "SkPath::Convexity"
 },
     "SkPath_Direction": {
-    "code": "void draw(SkCanvas* canvas) {\n    const SkPoint arrow[] = { {40, -5}, {45, 0}, {40, 5} };\n    const SkRect rect = {10, 10, 90, 90};\n    SkPaint rectPaint;\n    rectPaint.setAntiAlias(true);\n    SkPaint textPaint(rectPaint);\n    textPaint.setTextAlign(SkPaint::kCenter_Align);\n    rectPaint.setStyle(SkPaint::kStroke_Style);\n    SkPaint arrowPaint(rectPaint);\n    SkPath arrowPath;\n    arrowPath.addPoly(arrow, SK_ARRAY_COUNT(arrow), true);\n    arrowPaint.setPathEffect(SkPath1DPathEffect::Make(arrowPath, 320, 0,\n                             SkPath1DPathEffect::kRotate_Style));\n    for (auto direction : { SkPath::kCW_Direction, SkPath::kCCW_Direction } ) {\n        canvas->drawRect(rect, rectPaint);\n        for (unsigned start : { 0, 1, 2, 3 } ) {\n           SkPath path;\n           path.addRect(rect, direction, start);\n           canvas->drawPath(path, arrowPaint);\n       }\n       canvas->drawString(SkPath::kCW_Direction == direction ? \"CW\" : \"CCW\",  rect.centerX(),\n            rect.centerY(), textPaint);\n       canvas->translate(120, 0);\n    }\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    const SkPoint arrow[] = { {40, -5}, {45, 0}, {40, 5} };\n    const SkRect rect = {10, 10, 90, 90};\n    SkPaint rectPaint;\n    rectPaint.setAntiAlias(true);\n    SkPaint textPaint(rectPaint);\n    rectPaint.setStyle(SkPaint::kStroke_Style);\n    SkPaint arrowPaint(rectPaint);\n    SkPath arrowPath;\n    arrowPath.addPoly(arrow, SK_ARRAY_COUNT(arrow), true);\n    arrowPaint.setPathEffect(SkPath1DPathEffect::Make(arrowPath, 320, 0,\n                             SkPath1DPathEffect::kRotate_Style));\n    for (auto direction : { SkPath::kCW_Direction, SkPath::kCCW_Direction } ) {\n        canvas->drawRect(rect, rectPaint);\n        for (unsigned start : { 0, 1, 2, 3 } ) {\n           SkPath path;\n           path.addRect(rect, direction, start);\n           canvas->drawPath(path, arrowPaint);\n       }\n       canvas->drawString(SkPath::kCW_Direction == direction ? \"CW\" : \"CCW\",  rect.centerX(),\n            rect.centerY(), textPaint);\n       canvas->translate(120, 0);\n    }\n}\n",
     "width": 256,
     "height": 100,
-    "hash": "0de03d9c939b6238318b7366866e8722",
+    "hash": "4bbae00b40ed2cfcd0007921ad693a7b",
     "file": "SkPath_Reference",
     "name": "SkPath::Direction"
 },
@@ -7371,10 +7356,10 @@
     "name": "SkPath::FillType"
 },
     "SkPath_FillType_a": {
-    "code": "void draw(SkCanvas* canvas) {\n   SkPath path;\n   path.addRect({20, 10, 80, 70}, SkPath::kCW_Direction);\n   path.addRect({40, 30, 100, 90}, SkPath::kCW_Direction);\n   SkPaint strokePaint;\n   strokePaint.setStyle(SkPaint::kStroke_Style);\n   SkRect clipRect = {0, 0, 128, 128};\n   canvas->drawPath(path, strokePaint);\n   canvas->drawLine({0, 50}, {120, 50}, strokePaint);\n   SkPaint textPaint;\n   textPaint.setAntiAlias(true);\n   textPaint.setTextAlign(SkPaint::kCenter_Align);\n   SkScalar textHPos[] = { 10, 30, 60, 90, 110 };\n   canvas->drawPosTextH(\"01210\", 5, textHPos, 48, textPaint);\n   textPaint.setTextSize(18);\n   canvas->translate(0, 128);\n   canvas->scale(.5f, .5f);\n   canvas->drawString(\"inverse\", 384, 150, textPaint);\n   SkPaint fillPaint;\n   for (auto fillType : { SkPath::kWinding_FillType, SkPath::kEvenOdd_FillType,\n                      SkPath::kInverseWinding_FillType, SkPath::kInverseEvenOdd_FillType } ) {\n        canvas->save();\n        canvas->clipRect(clipRect);\n        path.setFillType(fillType);\n        canvas->drawPath(path, fillPaint);\n        canvas->restore();\n        canvas->drawString(fillType & 1 ? \"even-odd\" : \"winding\", 64, 170, textPaint);\n        canvas->translate(128, 0);\n    }\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n   SkPath path;\n   path.addRect({20, 10, 80, 70}, SkPath::kCW_Direction);\n   path.addRect({40, 30, 100, 90}, SkPath::kCW_Direction);\n   SkPaint strokePaint;\n   strokePaint.setStyle(SkPaint::kStroke_Style);\n   SkRect clipRect = {0, 0, 128, 128};\n   canvas->drawPath(path, strokePaint);\n   canvas->drawLine({0, 50}, {120, 50}, strokePaint);\n   SkPaint textPaint;\n   textPaint.setAntiAlias(true);\n   SkScalar textHPos[] = { 10, 30, 60, 90, 110 };\n   canvas->drawPosTextH(\"01210\", 5, textHPos, 48, textPaint);\n   textPaint.setTextSize(18);\n   canvas->translate(0, 128);\n   canvas->scale(.5f, .5f);\n   canvas->drawString(\"inverse\", 384, 150, textPaint);\n   SkPaint fillPaint;\n   for (auto fillType : { SkPath::kWinding_FillType, SkPath::kEvenOdd_FillType,\n                      SkPath::kInverseWinding_FillType, SkPath::kInverseEvenOdd_FillType } ) {\n        canvas->save();\n        canvas->clipRect(clipRect);\n        path.setFillType(fillType);\n        canvas->drawPath(path, fillPaint);\n        canvas->restore();\n        canvas->drawString(fillType & 1 ? \"even-odd\" : \"winding\", 64, 170, textPaint);\n        canvas->translate(128, 0);\n    }\n}\n",
     "width": 256,
     "height": 230,
-    "hash": "d84cd32b0bfd9ad2714f753120ed0ee1",
+    "hash": "d2c33dc791cd165dcc2423226ba5b095",
     "file": "SkPath_Reference",
     "name": "SkPath::FillType_2"
 },
@@ -7411,10 +7396,10 @@
     "name": "SkPath::addOval"
 },
     "SkPath_addOval_2": {
-    "code": "void draw(SkCanvas* canvas) {\n    const SkPoint arrow[] = { {0, -5}, {10, 0}, {0, 5} };\n    const SkRect rect = {10, 10, 54, 54};\n    SkPaint ovalPaint;\n    ovalPaint.setAntiAlias(true);\n    SkPaint textPaint(ovalPaint);\n    textPaint.setTextAlign(SkPaint::kCenter_Align);\n    ovalPaint.setStyle(SkPaint::kStroke_Style);\n    SkPaint arrowPaint(ovalPaint);\n    SkPath arrowPath;\n    arrowPath.addPoly(arrow, SK_ARRAY_COUNT(arrow), true);\n    arrowPaint.setPathEffect(SkPath1DPathEffect::Make(arrowPath, 176, 0,\n                             SkPath1DPathEffect::kRotate_Style));\n    for (auto direction : { SkPath::kCW_Direction, SkPath::kCCW_Direction } ) {\n        for (unsigned start : { 0, 1, 2, 3 } ) {\n           SkPath path;\n           path.addOval(rect, direction, start);\n           canvas->drawPath(path, ovalPaint);\n           canvas->drawPath(path, arrowPaint);\n           canvas->drawText(&\"0123\"[start], 1, rect.centerX(), rect.centerY() + 5, textPaint);\n           canvas->translate(64, 0);\n       }\n       canvas->translate(-256, 72);\n       canvas->drawString(SkPath::kCW_Direction == direction ? \"clockwise\" : \"counterclockwise\",\n                          128, 0, textPaint);\n    }\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    const SkPoint arrow[] = { {0, -5}, {10, 0}, {0, 5} };\n    const SkRect rect = {10, 10, 54, 54};\n    SkPaint ovalPaint;\n    ovalPaint.setAntiAlias(true);\n    SkPaint textPaint(ovalPaint);\n    ovalPaint.setStyle(SkPaint::kStroke_Style);\n    SkPaint arrowPaint(ovalPaint);\n    SkPath arrowPath;\n    arrowPath.addPoly(arrow, SK_ARRAY_COUNT(arrow), true);\n    arrowPaint.setPathEffect(SkPath1DPathEffect::Make(arrowPath, 176, 0,\n                             SkPath1DPathEffect::kRotate_Style));\n    for (auto direction : { SkPath::kCW_Direction, SkPath::kCCW_Direction } ) {\n        for (unsigned start : { 0, 1, 2, 3 } ) {\n           SkPath path;\n           path.addOval(rect, direction, start);\n           canvas->drawPath(path, ovalPaint);\n           canvas->drawPath(path, arrowPaint);\n           canvas->drawText(&\"0123\"[start], 1, rect.centerX(), rect.centerY() + 5, textPaint);\n           canvas->translate(64, 0);\n       }\n       canvas->translate(-256, 72);\n       canvas->drawString(SkPath::kCW_Direction == direction ? \"clockwise\" : \"counterclockwise\",\n                          128, 0, textPaint);\n    }\n}\n",
     "width": 256,
     "height": 160,
-    "hash": "ab9753174060e4a551727ef3af12924d",
+    "hash": "f1122d6fffddac0167e96fab4b9a862f",
     "file": "SkPath_Reference",
     "name": "SkPath::addOval_2"
 },
@@ -7523,18 +7508,18 @@
     "name": "SkPath::arcTo"
 },
     "SkPath_arcTo_2": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint tangentPaint;\n    tangentPaint.setAntiAlias(true);\n    SkPaint textPaint(tangentPaint);\n    tangentPaint.setStyle(SkPaint::kStroke_Style);\n    tangentPaint.setColor(SK_ColorGRAY);\n    SkPaint arcPaint(tangentPaint);\n    arcPaint.setStrokeWidth(5);\n    arcPaint.setColor(SK_ColorBLUE);\n    SkPath path;\n    SkPoint pts[] = { {56, 20}, {200, 20}, {90, 190} };\n    SkScalar radius = 50;\n    path.moveTo(pts[0]);\n    path.arcTo(pts[1], pts[2], radius);\n    canvas->drawLine(pts[0], pts[1], tangentPaint);\n    canvas->drawLine(pts[1], pts[2], tangentPaint);\n    SkPoint lastPt;\n    (void) path.getLastPt(&lastPt);\n    SkVector radial = pts[2] - pts[1];\n    radial.setLength(radius);\n    SkPoint center = { lastPt.fX - radial.fY, lastPt.fY + radial.fX };\n    canvas->drawCircle(center, radius, tangentPaint);\n    canvas->drawLine(lastPt, center, tangentPaint);\n    radial = pts[1] - pts[0];\n    radial.setLength(radius);\n    SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };\n    canvas->drawLine(center, arcStart, tangentPaint);\n    canvas->drawPath(path, arcPaint);\n    textPaint.setTextAlign(SkPaint::kRight_Align);\n    canvas->drawString(\"(x0, y0)\", pts[0].fX - 5, pts[0].fY, textPaint);\n    textPaint.setTextAlign(SkPaint::kLeft_Align);\n    canvas->drawString(\"(x1, y1)\", pts[1].fX + 5, pts[1].fY, textPaint);\n    textPaint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"(x2, y2)\", pts[2].fX, pts[2].fY + 15, textPaint);\n    textPaint.setTextAlign(SkPaint::kRight_Align);\n    canvas->drawString(\"radius\", center.fX + 15, center.fY + 25, textPaint);\n    canvas->drawString(\"radius\", center.fX - 3, center.fY - 16, textPaint);\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint tangentPaint;\n    tangentPaint.setAntiAlias(true);\n    SkPaint textPaint(tangentPaint);\n    tangentPaint.setStyle(SkPaint::kStroke_Style);\n    tangentPaint.setColor(SK_ColorGRAY);\n    SkPaint arcPaint(tangentPaint);\n    arcPaint.setStrokeWidth(5);\n    arcPaint.setColor(SK_ColorBLUE);\n    SkPath path;\n    SkPoint pts[] = { {56, 20}, {200, 20}, {90, 190} };\n    SkScalar radius = 50;\n    path.moveTo(pts[0]);\n    path.arcTo(pts[1], pts[2], radius);\n    canvas->drawLine(pts[0], pts[1], tangentPaint);\n    canvas->drawLine(pts[1], pts[2], tangentPaint);\n    SkPoint lastPt;\n    (void) path.getLastPt(&lastPt);\n    SkVector radial = pts[2] - pts[1];\n    radial.setLength(radius);\n    SkPoint center = { lastPt.fX - radial.fY, lastPt.fY + radial.fX };\n    canvas->drawCircle(center, radius, tangentPaint);\n    canvas->drawLine(lastPt, center, tangentPaint);\n    radial = pts[1] - pts[0];\n    radial.setLength(radius);\n    SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };\n    canvas->drawLine(center, arcStart, tangentPaint);\n    canvas->drawPath(path, arcPaint);\n    canvas->drawString(\"(x0, y0)\", pts[0].fX - 5, pts[0].fY, textPaint);\n    canvas->drawString(\"(x1, y1)\", pts[1].fX + 5, pts[1].fY, textPaint);\n    canvas->drawString(\"(x2, y2)\", pts[2].fX, pts[2].fY + 15, textPaint);\n    canvas->drawString(\"radius\", center.fX + 15, center.fY + 25, textPaint);\n    canvas->drawString(\"radius\", center.fX - 3, center.fY - 16, textPaint);\n}\n",
     "width": 256,
     "height": 226,
-    "hash": "d9c6435f26f37b3d63c664a99028f77f",
+    "hash": "386000684073fccabc224d7d6dc81cd9",
     "file": "SkPath_Reference",
     "name": "SkPath::arcTo_2"
 },
     "SkPath_arcTo_2_a": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint tangentPaint;\n    tangentPaint.setAntiAlias(true);\n    SkPaint textPaint(tangentPaint);\n    tangentPaint.setStyle(SkPaint::kStroke_Style);\n    tangentPaint.setColor(SK_ColorGRAY);\n    SkPaint arcPaint(tangentPaint);\n    arcPaint.setStrokeWidth(5);\n    arcPaint.setColor(SK_ColorBLUE);\n    SkPath path;\n    SkPoint pts[] = { {156, 20}, {200, 20}, {170, 50} };\n    SkScalar radius = 50;\n    path.moveTo(pts[0]);\n    path.arcTo(pts[1], pts[2], radius);\n    canvas->drawLine(pts[0], pts[1], tangentPaint);\n    canvas->drawLine(pts[1], pts[2], tangentPaint);\n    SkPoint lastPt;\n    (void) path.getLastPt(&lastPt);\n    SkVector radial = pts[2] - pts[1];\n    radial.setLength(radius);\n    SkPoint center = { lastPt.fX - radial.fY, lastPt.fY + radial.fX };\n    canvas->drawLine(lastPt, center, tangentPaint);\n    radial = pts[1] - pts[0];\n    radial.setLength(radius);\n    SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };\n    canvas->drawLine(center, arcStart, tangentPaint);\n    canvas->drawPath(path, arcPaint);\n    textPaint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"(x0, y0)\", pts[0].fX, pts[0].fY - 7, textPaint);\n    textPaint.setTextAlign(SkPaint::kLeft_Align);\n    canvas->drawString(\"(x1, y1)\", pts[1].fX + 5, pts[1].fY, textPaint);\n    textPaint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"(x2, y2)\", pts[2].fX, pts[2].fY + 15, textPaint);\n    textPaint.setTextAlign(SkPaint::kRight_Align);\n    canvas->drawString(\"radius\", center.fX + 15, center.fY + 25, textPaint);\n    canvas->drawString(\"radius\", center.fX - 5, center.fY - 20, textPaint);\n}\n",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint tangentPaint;\n    tangentPaint.setAntiAlias(true);\n    SkPaint textPaint(tangentPaint);\n    tangentPaint.setStyle(SkPaint::kStroke_Style);\n    tangentPaint.setColor(SK_ColorGRAY);\n    SkPaint arcPaint(tangentPaint);\n    arcPaint.setStrokeWidth(5);\n    arcPaint.setColor(SK_ColorBLUE);\n    SkPath path;\n    SkPoint pts[] = { {156, 20}, {200, 20}, {170, 50} };\n    SkScalar radius = 50;\n    path.moveTo(pts[0]);\n    path.arcTo(pts[1], pts[2], radius);\n    canvas->drawLine(pts[0], pts[1], tangentPaint);\n    canvas->drawLine(pts[1], pts[2], tangentPaint);\n    SkPoint lastPt;\n    (void) path.getLastPt(&lastPt);\n    SkVector radial = pts[2] - pts[1];\n    radial.setLength(radius);\n    SkPoint center = { lastPt.fX - radial.fY, lastPt.fY + radial.fX };\n    canvas->drawLine(lastPt, center, tangentPaint);\n    radial = pts[1] - pts[0];\n    radial.setLength(radius);\n    SkPoint arcStart = { center.fX + radial.fY, center.fY - radial.fX };\n    canvas->drawLine(center, arcStart, tangentPaint);\n    canvas->drawPath(path, arcPaint);\n    canvas->drawString(\"(x0, y0)\", pts[0].fX, pts[0].fY - 7, textPaint);\n    canvas->drawString(\"(x1, y1)\", pts[1].fX + 5, pts[1].fY, textPaint);\n    canvas->drawString(\"(x2, y2)\", pts[2].fX, pts[2].fY + 15, textPaint);\n    canvas->drawString(\"radius\", center.fX + 15, center.fY + 25, textPaint);\n    canvas->drawString(\"radius\", center.fX - 5, center.fY - 20, textPaint);\n}\n",
     "width": 256,
     "height": 128,
-    "hash": "01d2ddfd539ab86a86989e210640dffc",
+    "hash": "78f3c65fa900610bb52518989b547095",
     "file": "SkPath_Reference",
     "name": "SkPath::arcTo_2_2"
 },
@@ -8307,18 +8292,18 @@
     "name": "SkRRect::MakeRectXY"
 },
     "SkRRect_Type": {
-    "code": "void draw(SkCanvas* canvas) {\n    struct Radii { SkVector data[4]; };\n    auto drawRRectType = [=](const SkRect& rect, const Radii& radii) {\n        SkRRect rrect;\n        rrect.setRectRadii(rect, radii.data);\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        const char* typeStr[] = { \"empty\", \"rect\", \"oval\", \"simple\", \"nine patch\", \"complex\" };\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        canvas->drawString(typeStr[(int) rrect.type()], rect.centerX(), rect.bottom() + 20, paint);\n        paint.setStyle(SkPaint::kStroke_Style);       \n        canvas->drawRRect(rrect, paint);\n    };\n    drawRRectType({ 45,  30,  45,  30}, {{{ 5,  5}, { 5,  5}, { 5,  5}, { 5,  5}}});\n    drawRRectType({ 90,  10, 140,  30}, {{{ 0,  0}, { 0,  0}, { 0,  0}, { 0,  0}}});\n    drawRRectType({160,  10, 210,  30}, {{{25, 10}, {25, 10}, {25, 10}, {25, 10}}});\n    drawRRectType({ 20,  80,  70, 100}, {{{ 5,  5}, { 5,  5}, { 5,  5}, { 5,  5}}});\n    drawRRectType({ 90,  80, 140, 100}, {{{ 5,  5}, {10,  5}, {10,  5}, { 5,  5}}});\n    drawRRectType({160,  80, 210, 100}, {{{ 5,  5}, {10,  5}, { 5,  5}, { 5,  5}}});\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    struct Radii { SkVector data[4]; };\n    auto drawRRectType = [=](const SkRect& rect, const Radii& radii) {\n        SkRRect rrect;\n        rrect.setRectRadii(rect, radii.data);\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        const char* typeStr[] = { \"empty\", \"rect\", \"oval\", \"simple\", \"nine patch\", \"complex\" };\n        canvas->drawString(typeStr[(int) rrect.type()], rect.centerX(), rect.bottom() + 20, paint);\n        paint.setStyle(SkPaint::kStroke_Style);       \n        canvas->drawRRect(rrect, paint);\n    };\n    drawRRectType({ 45,  30,  45,  30}, {{{ 5,  5}, { 5,  5}, { 5,  5}, { 5,  5}}});\n    drawRRectType({ 90,  10, 140,  30}, {{{ 0,  0}, { 0,  0}, { 0,  0}, { 0,  0}}});\n    drawRRectType({160,  10, 210,  30}, {{{25, 10}, {25, 10}, {25, 10}, {25, 10}}});\n    drawRRectType({ 20,  80,  70, 100}, {{{ 5,  5}, { 5,  5}, { 5,  5}, { 5,  5}}});\n    drawRRectType({ 90,  80, 140, 100}, {{{ 5,  5}, {10,  5}, {10,  5}, { 5,  5}}});\n    drawRRectType({160,  80, 210, 100}, {{{ 5,  5}, {10,  5}, { 5,  5}, { 5,  5}}});\n}",
     "width": 256,
     "height": 128,
-    "hash": "38a559936ea7c8d482098c189ee5c9b8",
+    "hash": "a4233634c75b72fc7a2815ddb69bd669",
     "file": "SkRRect_Reference",
     "name": "SkRRect::Type"
 },
     "SkRRect_contains": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkRect test = {10, 10, 110, 80};\n    SkRRect rrect = SkRRect::MakeRect(test);\n    SkRRect oval = SkRRect::MakeOval(test);\n    test.inset(10, 10);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(rrect.contains(test) ? \"contains\" : \"does not contain\", 55, 100, paint);\n    canvas->drawString(oval.contains(test) ? \"contains\" : \"does not contain\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawRect(test, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(oval, paint);\n    canvas->drawRect(test, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkRect test = {10, 10, 110, 80};\n    SkRRect rrect = SkRRect::MakeRect(test);\n    SkRRect oval = SkRRect::MakeOval(test);\n    test.inset(10, 10);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    canvas->drawString(rrect.contains(test) ? \"contains\" : \"does not contain\", 55, 100, paint);\n    canvas->drawString(oval.contains(test) ? \"contains\" : \"does not contain\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawRect(test, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(oval, paint);\n    canvas->drawRect(test, paint);\n}",
     "width": 256,
     "height": 110,
-    "hash": "884447c809921cfaebc87aeb63dedd48",
+    "hash": "0bb057140e4119234bdd2e8dd2f0fa19",
     "file": "SkRRect_Reference",
     "name": "SkRRect::contains()"
 },
@@ -8363,10 +8348,10 @@
     "name": "SkRRect::getBounds"
 },
     "SkRRect_getSimpleRadii": {
-    "code": "void draw(SkCanvas* canvas) {\n    auto drawDetails = [=](const SkRRect& rrect) {\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextAlign(SkPaint::kCenter_Align);\n        paint.setTextSize(12);\n        canvas->drawRRect(rrect, paint);\n        SkVector corner = rrect.getSimpleRadii();\n        std::string label = \"corner: \" + std::to_string(corner.fX).substr(0, 3) + \", \" +\n                        std::to_string(corner.fY).substr(0, 3);\n        canvas->drawString(label.c_str(), 64, 90, paint);\n        canvas->translate(128, 0);\n    };\n    SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});\n    drawDetails(rrect);\n    rrect.setRectXY(rrect.getBounds(), 5, 8);\n    drawDetails(rrect);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    auto drawDetails = [=](const SkRRect& rrect) {\n        SkPaint paint;\n        paint.setAntiAlias(true);\n        paint.setTextSize(12);\n        canvas->drawRRect(rrect, paint);\n        SkVector corner = rrect.getSimpleRadii();\n        std::string label = \"corner: \" + std::to_string(corner.fX).substr(0, 3) + \", \" +\n                        std::to_string(corner.fY).substr(0, 3);\n        canvas->drawString(label.c_str(), 64, 90, paint);\n        canvas->translate(128, 0);\n    };\n    SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});\n    drawDetails(rrect);\n    rrect.setRectXY(rrect.getBounds(), 5, 8);\n    drawDetails(rrect);\n}",
     "width": 256,
     "height": 100,
-    "hash": "ebcc50ed30240e94de8439d21dd8171c",
+    "hash": "81345f7619a072bb2b0cf59810fe86d0",
     "file": "SkRRect_Reference",
     "name": "SkRRect::getSimpleRadii"
 },
@@ -8395,58 +8380,58 @@
     "name": "SkRRect::inset_2"
 },
     "SkRRect_isComplex": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkVector radii[] = {{25, 30}, {40, 30}, {40, 30}, {20, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isComplex() ? \"complex\" : \"not complex\", 64, 90, paint);\n    radii[0].fX = 20;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isComplex() ? \"complex\" : \"not complex\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkVector radii[] = {{25, 30}, {40, 30}, {40, 30}, {20, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isComplex() ? \"complex\" : \"not complex\", 64, 90, paint);\n    radii[0].fX = 20;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isComplex() ? \"complex\" : \"not complex\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "e4ba9346ee5c2d37d5e504f8cc678544",
+    "hash": "b62c183dc435d1fc091111fb2f3c3f8e",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isComplex"
 },
     "SkRRect_isEmpty": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 10, 5);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isEmpty() ? \"empty\" : \"not empty\", 64, 90, paint);\n    rrect.inset(40, 0);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isEmpty() ? \"empty\" : \"not empty\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 10, 5);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isEmpty() ? \"empty\" : \"not empty\", 64, 90, paint);\n    rrect.inset(40, 0);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isEmpty() ? \"empty\" : \"not empty\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "3afe4ea247923e06326aeb2b165c7485",
+    "hash": "099d79ecfbdfb0a19c10deb7201859c3",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isEmpty"
 },
     "SkRRect_isNinePatch": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkVector radii[] = {{20, 30}, {40, 30}, {40, 30}, {20, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isNinePatch() ? \"9 patch\" : \"not 9 patch\", 64, 90, paint);\n    radii[0].fX = 35;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isNinePatch() ? \"9 patch\" : \"not 9 patch\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkVector radii[] = {{20, 30}, {40, 30}, {40, 30}, {20, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isNinePatch() ? \"9 patch\" : \"not 9 patch\", 64, 90, paint);\n    radii[0].fX = 35;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isNinePatch() ? \"9 patch\" : \"not 9 patch\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "568cb730e66d0df09a7d9bd9d6142c9e",
+    "hash": "429f6dfd4cf6287df3c3c77fa7681c99",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isNinePatch"
 },
     "SkRRect_isOval": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isOval() ? \"oval\" : \"not oval\", 64, 90, paint);\n    rrect.setRectXY(rrect.getBounds(), 35, 25);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isOval() ? \"oval\" : \"not oval\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isOval() ? \"oval\" : \"not oval\", 64, 90, paint);\n    rrect.setRectXY(rrect.getBounds(), 35, 25);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isOval() ? \"oval\" : \"not oval\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "ab9b3aef7896aee80b780789848fbba4",
+    "hash": "4dfdb28d8343958425f2c1323fe8170d",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isOval"
 },
     "SkRRect_isRect": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isRect() ? \"rect\" : \"not rect\", 64, 90, paint);\n    SkVector radii[] = {{10, 10}, {0, 0}, {0, 0}, {0, 0}};\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isRect() ? \"rect\" : \"not rect\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isRect() ? \"rect\" : \"not rect\", 64, 90, paint);\n    SkVector radii[] = {{10, 10}, {0, 0}, {0, 0}, {0, 0}};\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isRect() ? \"rect\" : \"not rect\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "e2dcdad0e9cb7ba3e78a9871e9229753",
+    "hash": "bc931c9a6eb8ffe7ea8d3fb47e07a475",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isRect"
 },
     "SkRRect_isSimple": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    paint.setTextSize(16);\n    SkVector radii[] = {{40, 30}, {40, 30}, {40, 30}, {40, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isSimple() ? \"simple\" : \"not simple\", 64, 90, paint);\n    radii[0].fX = 35;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isSimple() ? \"simple\" : \"not simple\", 64, 90, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextSize(16);\n    SkVector radii[] = {{40, 30}, {40, 30}, {40, 30}, {40, 30}};\n    SkRRect rrect;\n    rrect.setRectRadii({30, 10, 100, 60}, radii);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isSimple() ? \"simple\" : \"not simple\", 64, 90, paint);\n    radii[0].fX = 35;\n    rrect.setRectRadii(rrect.getBounds(), radii);\n    canvas->translate(128, 0);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawString(rrect.isSimple() ? \"simple\" : \"not simple\", 64, 90, paint);\n}",
     "width": 256,
     "height": 100,
-    "hash": "65bbb109483ed79edb32027cf71851eb",
+    "hash": "f6959ea422a7c6e98ddfad216a52c707",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isSimple"
 },
     "SkRRect_isValid": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});\n    SkRRect corrupt = rrect;\n    *((float*) &corrupt) = 120;\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(rrect.isValid() ? \"is valid\" : \"is corrupted\", 55, 100, paint);\n    canvas->drawString(corrupt.isValid() ? \"is valid\" : \"is corrupted\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(corrupt, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});\n    SkRRect corrupt = rrect;\n    *((float*) &corrupt) = 120;\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    canvas->drawString(rrect.isValid() ? \"is valid\" : \"is corrupted\", 55, 100, paint);\n    canvas->drawString(corrupt.isValid() ? \"is valid\" : \"is corrupted\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(corrupt, paint);\n}",
     "width": 256,
     "height": 110,
-    "hash": "d28709aa457742391842a9ab1f21b5fa",
+    "hash": "8cc1f21c98c0416f7724ad218f557a00",
     "file": "SkRRect_Reference",
     "name": "SkRRect::isValid"
 },
@@ -8491,10 +8476,10 @@
     "name": "SkRRect::outset_2"
 },
     "SkRRect_readFromMemory": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkVector radii[] = {{5, 5},  {10, 10}, {15, 15}, {5, 5}};\n    SkRRect rrect;\n    rrect.setRectRadii({10, 10, 110, 80}, radii);\n    char storage[SkRRect::kSizeInMemory];\n    rrect.writeToMemory(storage);\n    SkRRect copy;\n    copy.readFromMemory(storage, sizeof(storage));\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(\"copy\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(copy, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkVector radii[] = {{5, 5},  {10, 10}, {15, 15}, {5, 5}};\n    SkRRect rrect;\n    rrect.setRectRadii({10, 10, 110, 80}, radii);\n    char storage[SkRRect::kSizeInMemory];\n    rrect.writeToMemory(storage);\n    SkRRect copy;\n    copy.readFromMemory(storage, sizeof(storage));\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(\"copy\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(copy, paint);\n}",
     "width": 256,
     "height": 110,
-    "hash": "b877c0adff35470865a57aa150bf5329",
+    "hash": "50969745cf2b23544362f4cff5592b75",
     "file": "SkRRect_Reference",
     "name": "SkRRect::readFromMemory"
 },
@@ -8547,10 +8532,10 @@
     "name": "SkRRect::setRectXY"
 },
     "SkRRect_transform": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkVector radii[] = {{5, 5},  {10, 10}, {15, 15}, {5, 5}};\n    SkRRect rrect;\n    rrect.setRectRadii({10, 10, 110, 80}, radii);\n    SkRRect transformed;\n    SkMatrix matrix = SkMatrix::MakeRectToRect(rrect.rect(), {140, 30, 220, 80},\n                                               SkMatrix::kCenter_ScaleToFit);\n    bool success = rrect.transform(matrix, &transformed);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(success ? \"transformed\" : \"transform failed\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawRRect(transformed, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkVector radii[] = {{5, 5},  {10, 10}, {15, 15}, {5, 5}};\n    SkRRect rrect;\n    rrect.setRectRadii({10, 10, 110, 80}, radii);\n    SkRRect transformed;\n    SkMatrix matrix = SkMatrix::MakeRectToRect(rrect.rect(), {140, 30, 220, 80},\n                                               SkMatrix::kCenter_ScaleToFit);\n    bool success = rrect.transform(matrix, &transformed);\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(success ? \"transformed\" : \"transform failed\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->drawRRect(transformed, paint);\n}",
     "width": 256,
     "height": 110,
-    "hash": "99ccc6862bb9fe3ca35228eee9f9725d",
+    "hash": "68a5d24f22e2d798608fce8a20e47fd0",
     "file": "SkRRect_Reference",
     "name": "SkRRect::transform()"
 },
@@ -8563,10 +8548,10 @@
     "name": "SkRRect::type()"
 },
     "SkRRect_writeToMemory": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});\n    char storage[SkRRect::kSizeInMemory];\n    rrect.writeToMemory(storage);\n    SkRRect copy;\n    copy.readFromMemory(storage, sizeof(storage));\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    paint.setTextAlign(SkPaint::kCenter_Align);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(\"copy\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(copy, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});\n    char storage[SkRRect::kSizeInMemory];\n    rrect.writeToMemory(storage);\n    SkRRect copy;\n    copy.readFromMemory(storage, sizeof(storage));\n    SkPaint paint;\n    paint.setAntiAlias(true);\n    canvas->drawString(\"rrect\", 55, 100, paint);\n    canvas->drawString(\"copy\", 185, 100, paint);    \n    paint.setStyle(SkPaint::kStroke_Style);\n    canvas->drawRRect(rrect, paint);\n    canvas->translate(120, 0);\n    canvas->drawRRect(copy, paint);\n}",
     "width": 256,
     "height": 110,
-    "hash": "1466c844a78fd05a7362537347e360ca",
+    "hash": "d6f5a3d21727ddc15e10ef4d5103ff91",
     "file": "SkRRect_Reference",
     "name": "SkRRect::writeToMemory"
 },
@@ -9075,10 +9060,10 @@
     "name": "SkTextBlobBuilder::allocRun"
 },
     "SkTextBlobBuilder_allocRunPos": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkTextBlobBuilder builder;\n    SkPaint paint, glyphPaint;\n    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);\n    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(glyphPaint, 5);\n    paint.textToGlyphs(\"hello\", 5, run.glyphs);\n    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};\n    memcpy(run.pos, positions, sizeof(positions));\n    canvas->drawTextBlob(builder.make(), 20, 20, paint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkTextBlobBuilder builder;\n    SkPaint paint, font;\n    font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);\n    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(font, 5);\n    paint.textToGlyphs(\"hello\", 5, run.glyphs);\n    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};\n    memcpy(run.pos, positions, sizeof(positions));\n    canvas->drawTextBlob(builder.make(), 20, 20, paint);\n}",
     "width": 256,
     "height": 90,
-    "hash": "f65c92ff5bfcc95ba58a2ba4d67f944f",
+    "hash": "2a11d3c287f785f3808dcbce08ccb435",
     "file": "SkTextBlobBuilder_Reference",
     "name": "SkTextBlobBuilder::allocRunPos"
 },
@@ -9090,6 +9075,30 @@
     "file": "SkTextBlobBuilder_Reference",
     "name": "SkTextBlobBuilder::allocRunPosH"
 },
+    "SkTextBlobBuilder_allocRunPosH_2": {
+    "code": "void draw(SkCanvas* canvas) {\n    SkTextBlobBuilder builder;\n    SkPaint paint;\n    SkFont font;\n    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPosH(font, 5, 20);\n    paint.textToGlyphs(\"hello\", 5, run.glyphs);\n    SkScalar positions[] = {0, 10, 20, 40, 80};\n    memcpy(run.pos, positions, sizeof(positions));\n    canvas->drawTextBlob(builder.make(), 20, 20, paint);\n}",
+    "width": 256,
+    "height": 60,
+    "hash": "c77ac50f506106fdfef94d20bc1a6934",
+    "file": "SkTextBlobBuilder_Reference",
+    "name": "SkTextBlobBuilder::allocRunPosH_2"
+},
+    "SkTextBlobBuilder_allocRunPos_2": {
+    "code": "void draw(SkCanvas* canvas) {\n    SkTextBlobBuilder builder;\n    SkPaint paint;\n    SkFont font;\n    const SkTextBlobBuilder::RunBuffer& run = builder.allocRunPos(font, 5);\n    paint.textToGlyphs(\"hello\", 5, run.glyphs);\n    SkPoint positions[] = {{0, 0}, {10, 10}, {20, 20}, {40, 40}, {80, 80}};\n    memcpy(run.pos, positions, sizeof(positions));\n    canvas->drawTextBlob(builder.make(), 20, 20, paint);\n}",
+    "width": 256,
+    "height": 90,
+    "hash": "da4fcb4a972b500996be9aff6c6c40e1",
+    "file": "SkTextBlobBuilder_Reference",
+    "name": "SkTextBlobBuilder::allocRunPos_2"
+},
+    "SkTextBlobBuilder_allocRun_2": {
+    "code": "void draw(SkCanvas* canvas) {\n    SkTextBlobBuilder builder;\n    SkFont font;\n    SkPaint paint;\n    const SkTextBlobBuilder::RunBuffer& run = builder.allocRun(font, 5, 20, 20);\n    paint.textToGlyphs(\"hello\", 5, run.glyphs);\n    canvas->drawRect({20, 20, 30, 30}, paint);\n    canvas->drawTextBlob(builder.make(), 20, 20, paint);\n}",
+    "width": 256,
+    "height": 60,
+    "hash": "f0e584aec20eaee7a5bfed62aa885eee",
+    "file": "SkTextBlobBuilder_Reference",
+    "name": "SkTextBlobBuilder::allocRun_2"
+},
     "SkTextBlob_Deserialize": {
     "code": "#include \"SkSerialProcs.h\"\n\nvoid draw(SkCanvas* canvas) {\n    SkPaint blobPaint;\n    blobPaint.setTextSize(24);\n    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(\"Hello World!\", 12, blobPaint);\n    sk_sp<SkData> data = blob->serialize(SkSerialProcs());\n    uint16_t glyphs[6];\n    blobPaint.textToGlyphs(\"Hacker\", 6, glyphs);\n    memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));\n    sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());\n    canvas->drawTextBlob(copy, 20, 20, SkPaint());\n}",
     "width": 256,
@@ -9099,18 +9108,18 @@
     "name": "SkTextBlob::Deserialize"
 },
     "SkTextBlob_MakeFromString": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint blobPaint;\n    blobPaint.setColor(SK_ColorRED); // ignored\n    blobPaint.setTextSize(24);  // respected\n    blobPaint.setAntiAlias(true); // ignored\n    SkPaint canvasPaint = blobPaint;\n    canvasPaint.setColor(SK_ColorBLUE); // respected\n    canvasPaint.setTextSize(2); // ignored\n    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString(\"Hello World\", blobPaint);\n    canvas->drawTextBlob(blob, 20, 20, canvasPaint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkFont font;\n    font.setSize(24);\n    SkPaint canvasPaint;\n    canvasPaint.setColor(SK_ColorBLUE); // respected\n    canvasPaint.setTextSize(2); // ignored\n    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString(\"Hello World\", font);\n    canvas->drawTextBlob(blob, 20, 20, canvasPaint);\n}",
     "width": 256,
     "height": 24,
-    "hash": "705b26bb5e361369d897eeb511b6a184",
+    "hash": "a5af182e793eed3f2bb3b0efc2cf4852",
     "file": "SkTextBlob_Reference",
     "name": "SkTextBlob::MakeFromString"
 },
     "SkTextBlob_MakeFromText": {
-    "code": "void draw(SkCanvas* canvas) {\n    SkPaint blobPaint;\n    blobPaint.setColor(SK_ColorRED); // ignored\n    blobPaint.setTextSize(24);  // respected\n    blobPaint.setAntiAlias(true); // ignored\n    SkPaint canvasPaint = blobPaint;\n    canvasPaint.setColor(SK_ColorBLUE); // respected\n    canvasPaint.setTextSize(2); // ignored\n    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(\"Hello World\", 11, blobPaint);\n    canvas->drawTextBlob(blob, 20, 20, canvasPaint);\n}",
+    "code": "void draw(SkCanvas* canvas) {\n    SkFont font;\n    font.setSize(24);\n    SkPaint canvasPaint;\n    canvasPaint.setColor(SK_ColorBLUE); // respected\n    canvasPaint.setTextSize(2); // ignored\n    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(\"Hello World\", 11, font);\n    canvas->drawTextBlob(blob, 20, 20, canvasPaint);\n}",
     "width": 256,
     "height": 24,
-    "hash": "74686684967a310dc06fe2915b0a4798",
+    "hash": "bec2252bc36dc8fd023015629d60c405",
     "file": "SkTextBlob_Reference",
     "name": "SkTextBlob::MakeFromText"
 },
diff --git a/site/user/api/undocumented.md b/site/user/api/undocumented.md
index 43c610d..a72f93f 100644
--- a/site/user/api/undocumented.md
+++ b/site/user/api/undocumented.md
@@ -187,6 +187,46 @@
 
 <a name='Engine'></a>
 
+<a name='SkTextEncoding'></a>
+
+---
+
+### Constants
+
+<table style='border-collapse: collapse; width: 62.5em'>
+  <tr><th style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>Const</th>
+<th style='text-align: center; border: 2px solid #dddddd; padding: 8px; '>Value</th>
+<th style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>Description</th></tr>
+  <tr style='background-color: #f0f0f0; '>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a name='kUTF8_SkTextEncoding'><code>kUTF8_SkTextEncoding</code></a></td>
+    <td style='text-align: center; border: 2px solid #dddddd; padding: 8px; '>0</td>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>
+</td>
+  </tr>
+  <tr>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a name='kUTF16_SkTextEncoding'><code>kUTF16_SkTextEncoding</code></a></td>
+    <td style='text-align: center; border: 2px solid #dddddd; padding: 8px; '>1</td>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>
+</td>
+  </tr>
+  <tr style='background-color: #f0f0f0; '>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a name='kUTF32_SkTextEncoding'><code>kUTF32_SkTextEncoding</code></a></td>
+    <td style='text-align: center; border: 2px solid #dddddd; padding: 8px; '>2</td>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>
+</td>
+  </tr>
+  <tr>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a name='kGlyphID_SkTextEncoding'><code>kGlyphID_SkTextEncoding</code></a></td>
+    <td style='text-align: center; border: 2px solid #dddddd; padding: 8px; '>3</td>
+    <td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '>
+</td>
+  </tr>
+</table>
+
+<a name='SkFont'></a>
+
+---
+
 <a name='GrContext'></a>
 
 ---