Revert "Add color fonts."

This reverts commit c912d6133c66df7cde3d64adc76941856a12da64.

Reason for revert: Causing TSAN issues.

Original change's description:
> Add color fonts.
> 
> BUG=skia:7624
> 
> Change-Id: Id2b7449048591892ff802484d5e3745a7e1402bb
> Reviewed-on: https://skia-review.googlesource.com/109521
> Commit-Queue: Ben Wagner <bungeman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
> Reviewed-by: Herb Derby <herb@google.com>

TBR=mtklein@google.com,bungeman@google.com,herb@google.com

Change-Id: I2ccd1f00e91bb92b7059323c95da0dd3de954164
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:7624
Reviewed-on: https://skia-review.googlesource.com/116141
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 95a9bba..cc7468f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1277,11 +1277,7 @@
       "tools/debugger/SkObjectParser.cpp",
       "tools/fonts/SkRandomScalerContext.cpp",
       "tools/fonts/SkTestFontMgr.cpp",
-      "tools/fonts/SkTestFontMgr.h",
-      "tools/fonts/SkTestSVGTypeface.cpp",
-      "tools/fonts/SkTestSVGTypeface.h",
-      "tools/fonts/SkTestTypeface.cpp",
-      "tools/fonts/SkTestTypeface.h",
+      "tools/fonts/SkTestScalerContext.cpp",
       "tools/fonts/sk_tool_utils_font.cpp",
       "tools/picture_utils.cpp",
       "tools/random_parse_path.cpp",
@@ -1301,7 +1297,6 @@
     }
     deps = [
       ":common_flags",
-      ":experimental_svg_model",
       ":flags",
       "//third_party/libpng",
     ]
@@ -1672,17 +1667,6 @@
     ]
   }
 
-  test_app("create_test_font_color") {
-    sources = [
-      "tools/fonts/create_test_font_color.cpp",
-    ]
-    deps = [
-      ":flags",
-      ":skia",
-      ":tool_utils"
-    ]
-  }
-
   test_app("get_images_from_skps") {
     sources = [
       "tools/get_images_from_skps.cpp",
diff --git a/gm/fontmgr.cpp b/gm/fontmgr.cpp
index 58c569c..a0b2f5b 100644
--- a/gm/fontmgr.cpp
+++ b/gm/fontmgr.cpp
@@ -9,7 +9,6 @@
 #include "sk_tool_utils.h"
 #include "SkCanvas.h"
 #include "SkFontMgr.h"
-#include "SkPath.h"
 #include "SkGraphics.h"
 #include "SkTypeface.h"
 
@@ -225,7 +224,6 @@
         fontBounds.offset(x, y);
         SkPaint boundsPaint(glyphPaint);
         boundsPaint.setColor(boundsColor);
-        boundsPaint.setStyle(SkPaint::kStroke_Style);
         canvas->drawRect(fontBounds, boundsPaint);
 
         SkPaint::FontMetrics fm;
@@ -266,10 +264,6 @@
         }
         SkGlyphID str[] = { left, right, top, bottom };
         for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
-            SkPath path;
-            glyphPaint.getTextPath(&str[i], sizeof(str[0]), x, y, &path);
-            SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
-            glyphPaint.setStyle(style);
             canvas->drawText(&str[i], sizeof(str[0]), x, y, glyphPaint);
         }
     }
@@ -288,6 +282,7 @@
         paint.setAntiAlias(true);
         paint.setSubpixelText(true);
         paint.setTextSize(100);
+        paint.setStyle(SkPaint::kStroke_Style);
         paint.setTextScaleX(fScaleX);
         paint.setTextSkewX(fSkewX);
 
diff --git a/public.bzl b/public.bzl
index 407ad1c..fbd005b 100644
--- a/public.bzl
+++ b/public.bzl
@@ -457,10 +457,8 @@
         "tools/fonts/SkRandomScalerContext.h",
         "tools/fonts/SkTestFontMgr.cpp",
         "tools/fonts/SkTestFontMgr.h",
-        "tools/fonts/SkTestSVGTypeface.cpp",
-        "tools/fonts/SkTestSVGTypeface.h",
-        "tools/fonts/SkTestTypeface.cpp",
-        "tools/fonts/SkTestTypeface.h",
+        "tools/fonts/SkTestScalerContext.cpp",
+        "tools/fonts/SkTestScalerContext.h",
         "tools/fonts/sk_tool_utils_font.cpp",
         "tools/fonts/test_font_monospace.inc",
         "tools/fonts/test_font_sans_serif.inc",
diff --git a/resources/fonts/cbdt.ttf b/resources/fonts/cbdt.ttf
deleted file mode 100644
index bed498f..0000000
--- a/resources/fonts/cbdt.ttf
+++ /dev/null
Binary files differ
diff --git a/resources/fonts/colr.ttf b/resources/fonts/colr.ttf
deleted file mode 100644
index 42e2a08..0000000
--- a/resources/fonts/colr.ttf
+++ /dev/null
Binary files differ
diff --git a/resources/fonts/sbix.ttf b/resources/fonts/sbix.ttf
deleted file mode 100644
index 5eed8a9..0000000
--- a/resources/fonts/sbix.ttf
+++ /dev/null
Binary files differ
diff --git a/resources/fonts/svg/diamond.svg b/resources/fonts/svg/diamond.svg
deleted file mode 100644
index 826cb74..0000000
--- a/resources/fonts/svg/diamond.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- The default glyf will be much smaller than the colr glyf layers. -->
-<svg
-   version="1.1"
-   viewBox="0 0 158.75 211.66667"
-   height="800"
-   width="600">
-  <g
-     transform="translate(0,-85.333351)"
-     id="layer1">
-    <path
-       transform="matrix(1,0,0,1.3773044,0.80180858,-33.549844)"
-       d="m 79.11178,236.39392 c -5.497887,0 -73.0286729,-67.53078 -73.028673,-73.02867 -2e-7,-5.49789 67.530782,-73.028671 73.028669,-73.028672 5.497888,0 73.028674,67.530782 73.028674,73.028672 0,5.49789 -67.530782,73.02867 -73.02867,73.02867 z"
-       id="path5299"
-       style="fill:#ff2a2a;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-    <path
-       transform="matrix(0.60436993,0,0,0.81236352,32.100808,58.741857)"
-       d="m 79.11178,236.39392 c -5.497887,0 -73.0286729,-67.53078 -73.028673,-73.02867 -2e-7,-5.49789 67.530782,-73.028671 73.028669,-73.028672 5.497888,0 73.028674,67.530782 73.028674,73.028672 0,5.49789 -67.530782,73.02867 -73.02867,73.02867 z"
-       id="path5299-5"
-       style="fill:none;stroke:#2b0000;stroke-width:14.19605827;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-  </g>
-</svg>
diff --git a/resources/fonts/svg/empty.svg b/resources/fonts/svg/empty.svg
deleted file mode 100644
index d470cc5..0000000
--- a/resources/fonts/svg/empty.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Empty, so will not produce a glyf or bitmap entry. -->
-<svg
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   viewBox="0 0 0 0"
-   height="0"
-   width="0">
-</svg>
diff --git a/resources/fonts/svg/notdef.svg b/resources/fonts/svg/notdef.svg
deleted file mode 100644
index 3fbb9a0..0000000
--- a/resources/fonts/svg/notdef.svg
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- In the colr format should be filled with the current paint. -->
-<svg
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   viewBox="0 0 158.75 211.66667"
-   height="800"
-   width="600">
-  <g
-     transform="translate(0,-85.333351)"
-     id="layer1">
-    <rect
-       y="97.374527"
-       x="4.3011618"
-       height="195.32433"
-       width="150.42305"
-       id="rect4639"
-       style="fill:none;stroke:#2b0000;stroke-width:6.61458349;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-    <path
-       id="path5186"
-       d="M 14.967094,109.37681 144.05828,283.63654"
-       style="fill:none;stroke:#2b0000;stroke-width:6.61458349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-    <path
-       id="path5188"
-       d="M 146.19643,107.77319 14.699822,282.83473"
-       style="fill:none;stroke:#2b0000;stroke-width:6.61458349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-  </g>
-</svg>
diff --git a/resources/fonts/svg/smile.svg b/resources/fonts/svg/smile.svg
deleted file mode 100644
index 41d26b5..0000000
--- a/resources/fonts/svg/smile.svg
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- In the colr format the eyes and mouth should be filled with the current paint. -->
-<svg
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   viewBox="0 0 211.66666 211.66667"
-   height="800"
-   width="800">
-  <g
-     transform="translate(0,-85.333317)"
-     id="layer1">
-    <circle
-       r="98.273819"
-       cy="192.76852"
-       cx="104.81271"
-       id="path10"
-       style="fill:#000000;stroke-width:0.3084828" />
-    <circle
-       r="90.782074"
-       cy="192.32785"
-       cx="104.37203"
-       id="path12"
-       style="fill:#ffcc00;stroke-width:0.3084828" />
-    <ellipse
-       ry="20.032738"
-       rx="20.410715"
-       cy="159.88458"
-       cx="74.574615"
-       id="path62"
-       style="fill:#2b0000;stroke-width:0.26458332" />
-    <ellipse
-       ry="20.032738"
-       rx="20.410715"
-       cy="158.13309"
-       cx="138.02272"
-       id="path62-7"
-       style="fill:#2b0000;stroke-width:0.26458332" />
-    <path
-       d="m 163.09897,220.67157 a 58.248119,31.234499 0 0 1 -26.87407,29.28648 58.248119,31.234499 0 0 1 -60.863188,0.45572 58.248119,31.234499 0 0 1 -28.388544,-28.87269 l 58.126712,2.01564 z"
-       id="path113"
-       style="fill:#2b0000;stroke-width:0.26458332" />
-  </g>
-</svg>
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index abe1550..f0eb7b7 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -830,13 +830,6 @@
         HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &sc, nullptr, si, &numItems),
              "Could not itemize character.");
 
-        // Disable any attempt at shaping.
-        // Without this ScriptShape may return 0x80040200 (USP_E_SCRIPT_NOT_IN_FONT)
-        // when all that is desired here is a simple cmap lookup.
-        for (SCRIPT_ITEM& item : si) {
-            item.a.eScript = SCRIPT_UNDEFINED;
-        }
-
         // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 space glyphs.
         static const int maxGlyphs = 2;
         SCRIPT_VISATTR vsa[maxGlyphs];
diff --git a/tools/fonts/SkTestFontMgr.cpp b/tools/fonts/SkTestFontMgr.cpp
index 4513a2f..3b5d158 100644
--- a/tools/fonts/SkTestFontMgr.cpp
+++ b/tools/fonts/SkTestFontMgr.cpp
@@ -8,8 +8,6 @@
 #include "SkFontDescriptor.h"
 #include "SkTestFontMgr.h"
 #include "sk_tool_utils.h"
-#include "SkTestTypeface.h"
-#include "SkTestSVGTypeface.h"
 
 namespace {
 
@@ -17,28 +15,6 @@
     "Toy Liberation Sans",
     "Toy Liberation Serif",
     "Toy Liberation Mono",
-    "Emoji",
-};
-
-class JustOneTypefaceStyleSet final : public SkFontStyleSet {
-public:
-    explicit JustOneTypefaceStyleSet(sk_sp<SkTypeface> typeface) : fTypeface(std::move(typeface)) {}
-    int count() override { return 1; }
-
-    void getStyle(int index, SkFontStyle* style, SkString* name) override {
-        if (style) { *style = SkFontStyle::Normal(); }
-        if (name)  { *name = "Normal"; }
-    }
-
-    SkTypeface* createTypeface(int index) override {
-        return SkRef(fTypeface.get());
-    }
-
-    SkTypeface* matchStyle(const SkFontStyle& pattern) override {
-        return this->matchStyleCSS3(pattern);
-    }
-private:
-    sk_sp<SkTypeface> fTypeface;
 };
 
 class FontStyleSet final : public SkFontStyleSet {
@@ -93,7 +69,6 @@
         fFamilies[0] = sk_make_sp<FontStyleSet>(0);
         fFamilies[1] = sk_make_sp<FontStyleSet>(1);
         fFamilies[2] = sk_make_sp<FontStyleSet>(2);
-        fFamilies[3] = sk_make_sp<JustOneTypefaceStyleSet>(SkTestSVGTypeface::Default());
     }
 
     int onCountFamilies() const override { return SK_ARRAY_COUNT(fFamilies); }
@@ -111,7 +86,6 @@
             if (strstr(familyName,  "ans")) { return this->createStyleSet(0); }
             if (strstr(familyName, "erif")) { return this->createStyleSet(1); }
             if (strstr(familyName,  "ono")) { return this->createStyleSet(2); }
-            if (strstr(familyName,  "oji")) { return this->createStyleSet(3); }
         }
         return this->createStyleSet(0);
     }
@@ -164,7 +138,7 @@
     }
 
 private:
-    sk_sp<SkFontStyleSet> fFamilies[4];
+    sk_sp<FontStyleSet> fFamilies[3];
 };
 }
 
diff --git a/tools/fonts/SkTestSVGTypeface.cpp b/tools/fonts/SkTestSVGTypeface.cpp
deleted file mode 100644
index a4e3e49..0000000
--- a/tools/fonts/SkTestSVGTypeface.cpp
+++ /dev/null
@@ -1,1302 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Resources.h"
-#include "SkAdvancedTypefaceMetrics.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkColor.h"
-#include "SkData.h"
-#include "SkEncodedImageFormat.h"
-#include "SkFontDescriptor.h"
-#include "SkFontStyle.h"
-#include "SkGeometry.h"
-#include "SkGlyph.h"
-#include "SkImage.h"
-#include "SkImageInfo.h"
-#include "SkMask.h"
-#include "SkMatrix.h"
-#include "SkNoDrawCanvas.h"
-#include "SkOTUtils.h"
-#include "SkPaintPriv.h"
-#include "SkPath.h"
-#include "SkPathPriv.h"
-#include "SkPathEffect.h"
-#include "SkPathOps.h"
-#include "SkPixmap.h"
-#include "SkPointPriv.h"
-#include "SkRRect.h"
-#include "SkSVGDOM.h"
-#include "SkScalerContext.h"
-#include "SkSize.h"
-#include "SkStream.h"
-#include "SkSurface.h"
-#include "SkTestSVGTypeface.h"
-#include "SkTDArray.h"
-#include "SkTemplates.h"
-#include "SkUtils.h"
-
-#include <utility>
-
-class SkDescriptor;
-
-SkTestSVGTypeface::SkTestSVGTypeface(const char* name,
-                                     int upem,
-                                     const SkPaint::FontMetrics& fontMetrics,
-                                     const SkSVGTestTypefaceGlyphData* data, int dataCount,
-                                     const SkFontStyle& style)
-    : SkTypeface(style, false)
-    , fName(name)
-    , fUpem(upem)
-    , fFontMetrics(fontMetrics)
-    , fGlyphs(dataCount)
-{
-    for (int i = 0; i < dataCount; ++i) {
-        const SkSVGTestTypefaceGlyphData& datum = data[i];
-        std::unique_ptr<SkStreamAsset> stream = GetResourceAsStream(datum.fSvgResourcePath);
-        fCMap.set(datum.fUnicode, i);
-        if (!stream) {
-            fGlyphs.emplace_back(nullptr, datum);
-            continue;
-        }
-        sk_sp<SkSVGDOM> svg = SkSVGDOM::MakeFromStream(*stream.get());
-        if (!svg) {
-            fGlyphs.emplace_back(nullptr, datum);
-            continue;
-        }
-
-        const SkSize& sz = svg->containerSize();
-        if (sz.isEmpty()) {
-            fGlyphs.emplace_back(nullptr, datum);
-            continue;
-        }
-
-        fGlyphs.emplace_back(std::move(svg), datum);
-    }
-}
-
-SkTestSVGTypeface::~SkTestSVGTypeface() {}
-
-SkTestSVGTypeface::Glyph::Glyph(sk_sp<SkSVGDOM> svg, const SkSVGTestTypefaceGlyphData& data)
-    : fSvg(std::move(svg)), fOrigin(data.fOrigin), fAdvance(data.fAdvance) {}
-SkTestSVGTypeface::Glyph::~Glyph() {}
-
-void SkTestSVGTypeface::getAdvance(SkGlyph* glyph) const {
-    SkGlyphID glyphID = glyph->getGlyphID();
-    glyphID = glyphID < fGlyphs.count() ? glyphID : 0;
-
-    glyph->fAdvanceX = fGlyphs[glyphID].fAdvance;
-    glyph->fAdvanceY = 0;
-}
-
-void SkTestSVGTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) const {
-    *metrics = fFontMetrics;
-}
-
-void SkTestSVGTypeface::getPath(SkGlyphID glyphID, SkPath* path) const {
-    path->reset();
-}
-
-void SkTestSVGTypeface::onFilterRec(SkScalerContextRec* rec) const {
-    rec->setHinting(SkPaint::kNo_Hinting);
-}
-
-std::unique_ptr<SkAdvancedTypefaceMetrics> SkTestSVGTypeface::onGetAdvancedMetrics() const {
-    std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);
-    info->fFontName.set(fName);
-    int glyphCount = this->onCountGlyphs();
-
-    SkTDArray<SkUnichar>& toUnicode = info->fGlyphToUnicode;
-    toUnicode.setCount(glyphCount);
-    SkASSERT(glyphCount == SkToInt(fGlyphs.count()));
-    fCMap.foreach([&toUnicode](const SkUnichar& c, const SkGlyphID& g) {
-        toUnicode[g] = c;
-    });
-    return info;
-}
-
-void SkTestSVGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
-    desc->setFamilyName(fName.c_str());
-    desc->setStyle(this->fontStyle());
-    *isLocal = false;
-}
-
-int SkTestSVGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
-                                    uint16_t glyphs[], int glyphCount) const {
-    auto utf8  = (const      char*)chars;
-    auto utf16 = (const  uint16_t*)chars;
-    auto utf32 = (const SkUnichar*)chars;
-
-    for (int i = 0; i < glyphCount; i++) {
-        SkUnichar ch;
-        switch (encoding) {
-            case kUTF8_Encoding:  ch =  SkUTF8_NextUnichar(&utf8 ); break;
-            case kUTF16_Encoding: ch = SkUTF16_NextUnichar(&utf16); break;
-            case kUTF32_Encoding: ch =                    *utf32++; break;
-        }
-        if (glyphs) {
-            SkGlyphID* g = fCMap.find(ch);
-            glyphs[i] = g ? *g : 0;
-        }
-    }
-    return glyphCount;
-}
-
-void SkTestSVGTypeface::onGetFamilyName(SkString* familyName) const {
-    *familyName = fName;
-}
-
-SkTypeface::LocalizedStrings* SkTestSVGTypeface::onCreateFamilyNameIterator() const {
-    SkString familyName(fName);
-    SkString language("und"); //undetermined
-    return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
-}
-
-class SkTestSVGScalerContext : public SkScalerContext {
-public:
-    SkTestSVGScalerContext(sk_sp<SkTestSVGTypeface> face, const SkScalerContextEffects& effects,
-                           const SkDescriptor* desc)
-        : SkScalerContext(std::move(face), effects, desc)
-    {
-        fRec.getSingleMatrix(&fMatrix);
-        SkScalar upem = this->geTestSVGTypeface()->fUpem;
-        fMatrix.preScale(1.f/upem, 1.f/upem);
-    }
-
-protected:
-    SkTestSVGTypeface* geTestSVGTypeface() const {
-        return static_cast<SkTestSVGTypeface*>(this->getTypeface());
-    }
-
-    unsigned generateGlyphCount() override {
-        return this->geTestSVGTypeface()->onCountGlyphs();
-    }
-
-    uint16_t generateCharToGlyph(SkUnichar u) override {
-        uint16_t g;
-        (void) this->geTestSVGTypeface()->onCharsToGlyphs(&u, SkTypeface::kUTF32_Encoding, &g, 1);
-        return g;
-    }
-
-    void generateAdvance(SkGlyph* glyph) override {
-        this->geTestSVGTypeface()->getAdvance(glyph);
-
-        const SkVector advance = fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX),
-                                               SkFloatToScalar(glyph->fAdvanceY));
-        glyph->fAdvanceX = SkScalarToFloat(advance.fX);
-        glyph->fAdvanceY = SkScalarToFloat(advance.fY);
-    }
-
-    void generateMetrics(SkGlyph* glyph) override {
-        SkGlyphID glyphID = glyph->getGlyphID();
-        glyphID = glyphID < this->geTestSVGTypeface()->fGlyphs.count() ? glyphID : 0;
-
-        glyph->zeroMetrics();
-        glyph->fMaskFormat = SkMask::kARGB32_Format;
-        this->generateAdvance(glyph);
-
-        SkTestSVGTypeface::Glyph& glyphData = this->geTestSVGTypeface()->fGlyphs[glyphID];
-        if (!glyphData.fSvg) {
-            return;
-        }
-
-        SkSize containerSize = glyphData.fSvg->containerSize();
-        SkRect newBounds = SkRect::MakeXYWH(glyphData.fOrigin.fX, -glyphData.fOrigin.fY,
-                                            containerSize.fWidth, containerSize.fHeight);
-        fMatrix.mapRect(&newBounds);
-        SkScalar dx = SkFixedToScalar(glyph->getSubXFixed());
-        SkScalar dy = SkFixedToScalar(glyph->getSubYFixed());
-        newBounds.offset(dx, dy);
-
-        SkIRect ibounds;
-        newBounds.roundOut(&ibounds);
-        glyph->fLeft = ibounds.fLeft;
-        glyph->fTop = ibounds.fTop;
-        glyph->fWidth = ibounds.width();
-        glyph->fHeight = ibounds.height();
-    }
-
-    void generateImage(const SkGlyph& glyph) override {
-        SkGlyphID glyphID = glyph.getGlyphID();
-        glyphID = glyphID < this->geTestSVGTypeface()->fGlyphs.count() ? glyphID : 0;
-
-        SkBitmap bm;
-        // TODO: this should be SkImageInfo::MakeS32 when that passes all the tests.
-        bm.installPixels(SkImageInfo::MakeN32(glyph.fWidth, glyph.fHeight, kPremul_SkAlphaType),
-                         glyph.fImage, glyph.rowBytes());
-        bm.eraseColor(0);
-
-        SkTestSVGTypeface::Glyph& glyphData = this->geTestSVGTypeface()->fGlyphs[glyphID];
-
-        SkScalar dx = SkFixedToScalar(glyph.getSubXFixed());
-        SkScalar dy = SkFixedToScalar(glyph.getSubYFixed());
-
-        SkCanvas canvas(bm);
-        canvas.translate(-glyph.fLeft, -glyph.fTop);
-        canvas.translate(dx, dy);
-        canvas.concat(fMatrix);
-        canvas.translate(glyphData.fOrigin.fX, -glyphData.fOrigin.fY);
-
-        if (glyphData.fSvg) {
-            glyphData.fSvg->render(&canvas);
-        }
-    }
-
-    void generatePath(SkGlyphID glyph, SkPath* path) override {
-        this->geTestSVGTypeface()->getPath(glyph, path);
-        path->transform(fMatrix);
-    }
-
-    void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
-        this->geTestSVGTypeface()->getFontMetrics(metrics);
-        SkPaintPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY());
-    }
-
-private:
-    SkMatrix fMatrix;
-};
-
-SkScalerContext* SkTestSVGTypeface::onCreateScalerContext(
-    const SkScalerContextEffects& e, const SkDescriptor* desc) const
-{
-    return new SkTestSVGScalerContext(sk_ref_sp(const_cast<SkTestSVGTypeface*>(this)), e, desc);
-}
-
-// Recommended that the first four be .notdef, .null, CR, space
-constexpr const static SkSVGTestTypefaceGlyphData gGlyphs[] = {
-    {"fonts/svg/notdef.svg", {100,800}, 800, 0x0}, // .notdef
-    {"fonts/svg/empty.svg", {0,0}, 800, 0x0020}, // space
-    {"fonts/svg/diamond.svg", {100, 800}, 800, 0x2662}, // β™’
-    {"fonts/svg/smile.svg", {0,800}, 800, 0x1F600}, // πŸ˜€
-};
-
-sk_sp<SkTestSVGTypeface> SkTestSVGTypeface::Default() {
-    SkPaint::FontMetrics metrics;
-    metrics.fFlags = SkPaint::FontMetrics::kUnderlineThicknessIsValid_Flag |
-                     SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag  |
-                     SkPaint::FontMetrics::kStrikeoutThicknessIsValid_Flag |
-                     SkPaint::FontMetrics::kStrikeoutPositionIsValid_Flag;
-    metrics.fTop = -800;
-    metrics.fAscent = -800;
-    metrics.fDescent = 200;
-    metrics.fBottom = 200;
-    metrics.fLeading = 100;
-    metrics.fAvgCharWidth = 1000;
-    metrics.fMaxCharWidth = 1000;
-    metrics.fXMin = 0;
-    metrics.fXMax = 1000;
-    metrics.fXHeight = 500;
-    metrics.fCapHeight = 700;
-    metrics.fUnderlineThickness = 40;
-    metrics.fUnderlinePosition = 20;
-    metrics.fStrikeoutThickness = 20;
-    metrics.fStrikeoutPosition = -400;
-    return sk_make_sp<SkTestSVGTypeface>("Emoji", 1000, metrics, gGlyphs, SK_ARRAY_COUNT(gGlyphs),
-                                         SkFontStyle::Normal());
-}
-
-void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
-                                        const SkTArray<GlyfInfo>* glyfInfo) const
-{
-    int totalGlyphs = fGlyphs.count();
-    out->writeText("  <GlyphOrder>\n");
-    for (int i = 0; i < fGlyphs.count(); ++i) {
-        out->writeText("    <GlyphID name=\"glyf");
-        out->writeHexAsText(i, 4);
-        out->writeText("\"/>\n");
-    }
-    if (glyfInfo) {
-        for (int i = 0; i < fGlyphs.count(); ++i) {
-            for (int j = 0; j < (*glyfInfo)[i].fLayers.count(); ++j) {
-                out->writeText("    <GlyphID name=\"glyf");
-                    out->writeHexAsText(i, 4);
-                    out->writeText("l");
-                    out->writeHexAsText(j, 4);
-                    out->writeText("\"/>\n");
-                ++totalGlyphs;
-            }
-        }
-    }
-    out->writeText("  </GlyphOrder>\n");
-
-    out->writeText("  <head>\n");
-    out->writeText("    <tableVersion value=\"1.0\"/>\n");
-    out->writeText("    <fontRevision value=\"1.0\"/>\n");
-    out->writeText("    <checkSumAdjustment value=\"0xa9c3274\"/>\n");
-    out->writeText("    <magicNumber value=\"0x5f0f3cf5\"/>\n");
-    out->writeText("    <flags value=\"00000000 00011011\"/>\n");
-    out->writeText("    <unitsPerEm value=\"");
-        out->writeDecAsText(fUpem);
-        out->writeText("\"/>\n");
-    out->writeText("    <created value=\"Thu Feb 15 12:55:49 2018\"/>\n");
-    out->writeText("    <modified value=\"Thu Feb 15 12:55:49 2018\"/>\n");
-    // TODO: not recalculated for bitmap fonts?
-    out->writeText("    <xMin value=\"");
-        out->writeScalarAsText(fFontMetrics.fXMin);
-        out->writeText("\"/>\n");
-    out->writeText("    <yMin value=\"");
-        out->writeScalarAsText(-fFontMetrics.fBottom);
-        out->writeText("\"/>\n");
-    out->writeText("    <xMax value=\"");
-        out->writeScalarAsText(fFontMetrics.fXMax);
-        out->writeText("\"/>\n");
-    out->writeText("    <yMax value=\"");
-        out->writeScalarAsText(-fFontMetrics.fTop);
-        out->writeText("\"/>\n");
-
-    char macStyle[16] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-    if (this->fontStyle().weight() >= SkFontStyle::Bold().weight()) {
-        macStyle[0xF - 0x0] = '1'; // Bold
-    }
-    switch (this->fontStyle().slant()) {
-        case SkFontStyle::kUpright_Slant:
-            break;
-        case SkFontStyle::kItalic_Slant:
-            macStyle[0xF - 0x1] = '1'; // Italic
-            break;
-        case SkFontStyle::kOblique_Slant:
-            macStyle[0xF - 0x1] = '1'; // Italic
-            break;
-        default:
-            SK_ABORT("Unknown slant.");
-    }
-    if (this->fontStyle().width() <= SkFontStyle::kCondensed_Width) {
-        macStyle[0xF - 0x5] = '1'; // Condensed
-    } else if (this->fontStyle().width() >= SkFontStyle::kExpanded_Width) {
-        macStyle[0xF - 0x6] = '1'; // Extended
-    }
-    out->writeText("    <macStyle value=\"");
-        out->write(macStyle, 8);
-        out->writeText(" ");
-        out->write(macStyle + 8, 8);
-        out->writeText("\"/>\n");
-    out->writeText("    <lowestRecPPEM value=\"8\"/>\n");
-    out->writeText("    <fontDirectionHint value=\"2\"/>\n");
-    out->writeText("    <indexToLocFormat value=\"0\"/>\n");
-    out->writeText("    <glyphDataFormat value=\"0\"/>\n");
-    out->writeText("  </head>\n");
-
-    out->writeText("  <hhea>\n");
-    out->writeText("    <tableVersion value=\"0x00010000\"/>\n");
-    out->writeText("    <ascent value=\"");
-        out->writeDecAsText(-fFontMetrics.fAscent);
-        out->writeText("\"/>\n");
-    out->writeText("    <descent value=\"");
-        out->writeDecAsText(-fFontMetrics.fDescent);
-        out->writeText("\"/>\n");
-    out->writeText("    <lineGap value=\"");
-        out->writeDecAsText(fFontMetrics.fLeading);
-        out->writeText("\"/>\n");
-    out->writeText("    <advanceWidthMax value=\"0\"/>\n");
-    out->writeText("    <minLeftSideBearing value=\"0\"/>\n");
-    out->writeText("    <minRightSideBearing value=\"0\"/>\n");
-    out->writeText("    <xMaxExtent value=\"");
-        out->writeScalarAsText(fFontMetrics.fXMax - fFontMetrics.fXMin);
-        out->writeText("\"/>\n");
-    out->writeText("    <caretSlopeRise value=\"1\"/>\n");
-    out->writeText("    <caretSlopeRun value=\"0\"/>\n");
-    out->writeText("    <caretOffset value=\"0\"/>\n");
-    out->writeText("    <reserved0 value=\"0\"/>\n");
-    out->writeText("    <reserved1 value=\"0\"/>\n");
-    out->writeText("    <reserved2 value=\"0\"/>\n");
-    out->writeText("    <reserved3 value=\"0\"/>\n");
-    out->writeText("    <metricDataFormat value=\"0\"/>\n");
-    out->writeText("    <numberOfHMetrics value=\"0\"/>\n");
-    out->writeText("  </hhea>\n");
-
-    // Some of this table is going to be re-calculated, but we have to write it out anyway.
-    out->writeText("  <maxp>\n");
-    out->writeText("    <tableVersion value=\"0x10000\"/>\n");
-    out->writeText("    <numGlyphs value=\"");
-        out->writeDecAsText(totalGlyphs);
-        out->writeText("\"/>\n");
-    out->writeText("    <maxPoints value=\"4\"/>\n");
-    out->writeText("    <maxContours value=\"1\"/>\n");
-    out->writeText("    <maxCompositePoints value=\"0\"/>\n");
-    out->writeText("    <maxCompositeContours value=\"0\"/>\n");
-    out->writeText("    <maxZones value=\"1\"/>\n");
-    out->writeText("    <maxTwilightPoints value=\"0\"/>\n");
-    out->writeText("    <maxStorage value=\"0\"/>\n");
-    out->writeText("    <maxFunctionDefs value=\"10\"/>\n");
-    out->writeText("    <maxInstructionDefs value=\"0\"/>\n");
-    out->writeText("    <maxStackElements value=\"512\"/>\n");
-    out->writeText("    <maxSizeOfInstructions value=\"24\"/>\n");
-    out->writeText("    <maxComponentElements value=\"0\"/>\n");
-    out->writeText("    <maxComponentDepth value=\"0\"/>\n");
-    out->writeText("  </maxp>\n");
-
-    out->writeText("  <OS_2>\n");
-    out->writeText("    <version value=\"4\"/>\n");
-    out->writeText("    <xAvgCharWidth value=\"");
-        out->writeScalarAsText(fFontMetrics.fAvgCharWidth);
-        out->writeText("\"/>\n");
-    out->writeText("    <usWeightClass value=\"");
-        out->writeDecAsText(this->fontStyle().weight());
-        out->writeText("\"/>\n");
-    out->writeText("    <usWidthClass value=\"");
-        out->writeDecAsText(this->fontStyle().width());
-        out->writeText("\"/>\n");
-    out->writeText("    <fsType value=\"00000000 00000000\"/>\n");
-    out->writeText("    <ySubscriptXSize value=\"665\"/>\n");
-    out->writeText("    <ySubscriptYSize value=\"716\"/>\n");
-    out->writeText("    <ySubscriptXOffset value=\"0\"/>\n");
-    out->writeText("    <ySubscriptYOffset value=\"143\"/>\n");
-    out->writeText("    <ySuperscriptXSize value=\"665\"/>\n");
-    out->writeText("    <ySuperscriptYSize value=\"716\"/>\n");
-    out->writeText("    <ySuperscriptXOffset value=\"0\"/>\n");
-    out->writeText("    <ySuperscriptYOffset value=\"491\"/>\n");
-    out->writeText("    <yStrikeoutSize value=\"");
-        out->writeScalarAsText(fFontMetrics.fStrikeoutThickness);
-        out->writeText("\"/>\n");
-    out->writeText("    <yStrikeoutPosition value=\"");
-        out->writeScalarAsText(-fFontMetrics.fStrikeoutPosition);
-        out->writeText("\"/>\n");
-    out->writeText("    <sFamilyClass value=\"0\"/>\n");
-    out->writeText("    <panose>\n");
-    out->writeText("      <bFamilyType value=\"0\"/>\n");
-    out->writeText("      <bSerifStyle value=\"0\"/>\n");
-    out->writeText("      <bWeight value=\"0\"/>\n");
-    out->writeText("      <bProportion value=\"0\"/>\n");
-    out->writeText("      <bContrast value=\"0\"/>\n");
-    out->writeText("      <bStrokeVariation value=\"0\"/>\n");
-    out->writeText("      <bArmStyle value=\"0\"/>\n");
-    out->writeText("      <bLetterForm value=\"0\"/>\n");
-    out->writeText("      <bMidline value=\"0\"/>\n");
-    out->writeText("      <bXHeight value=\"0\"/>\n");
-    out->writeText("    </panose>\n");
-    out->writeText("    <ulUnicodeRange1 value=\"00000000 00000000 00000000 00000001\"/>\n");
-    out->writeText("    <ulUnicodeRange2 value=\"00010000 00000000 00000000 00000000\"/>\n");
-    out->writeText("    <ulUnicodeRange3 value=\"00000000 00000000 00000000 00000000\"/>\n");
-    out->writeText("    <ulUnicodeRange4 value=\"00000000 00000000 00000000 00000000\"/>\n");
-    out->writeText("    <achVendID value=\"Skia\"/>\n");
-    char fsSelection[16] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-    fsSelection[0xF - 0x7] = '1'; // Use typo metrics
-    if (this->fontStyle().weight() >= SkFontStyle::Bold().weight()) {
-        fsSelection[0xF - 0x5] = '1'; // Bold
-    }
-    switch (this->fontStyle().slant()) {
-        case SkFontStyle::kUpright_Slant:
-            if (this->fontStyle().weight() < SkFontStyle::Bold().weight()) {
-                fsSelection[0xF - 0x6] = '1'; // Not bold or italic, is regular
-            }
-            break;
-        case SkFontStyle::kItalic_Slant:
-            fsSelection[0xF - 0x0] = '1'; // Italic
-            break;
-        case SkFontStyle::kOblique_Slant:
-            fsSelection[0xF - 0x0] = '1'; // Italic
-            fsSelection[0xF - 0x9] = '1'; // Oblique
-            break;
-        default:
-            SK_ABORT("Unknown slant.");
-    }
-    out->writeText("    <fsSelection value=\"");
-        out->write(fsSelection, 8);
-        out->writeText(" ");
-        out->write(fsSelection + 8, 8);
-        out->writeText("\"/>\n");
-    out->writeText("    <usFirstCharIndex value=\"0\"/>\n");
-    out->writeText("    <usLastCharIndex value=\"0\"/>\n");
-    out->writeText("    <sTypoAscender value=\"");
-        out->writeScalarAsText(-fFontMetrics.fAscent);
-        out->writeText("\"/>\n");
-    out->writeText("    <sTypoDescender value=\"");
-        out->writeScalarAsText(-fFontMetrics.fDescent);
-        out->writeText("\"/>\n");
-    out->writeText("    <sTypoLineGap value=\"");
-        out->writeScalarAsText(fFontMetrics.fLeading);
-        out->writeText("\"/>\n");
-    out->writeText("    <usWinAscent value=\"");
-        out->writeScalarAsText(-fFontMetrics.fAscent);
-        out->writeText("\"/>\n");
-    out->writeText("    <usWinDescent value=\"");
-        out->writeScalarAsText(fFontMetrics.fDescent);
-        out->writeText("\"/>\n");
-    out->writeText("    <ulCodePageRange1 value=\"00000000 00000000 00000000 00000000\"/>\n");
-    out->writeText("    <ulCodePageRange2 value=\"00000000 00000000 00000000 00000000\"/>\n");
-    out->writeText("    <sxHeight value=\"");
-        out->writeScalarAsText(fFontMetrics.fXHeight);
-        out->writeText("\"/>\n");
-    out->writeText("    <sCapHeight value=\"");
-        out->writeScalarAsText(fFontMetrics.fCapHeight);
-        out->writeText("\"/>\n");
-    out->writeText("    <usDefaultChar value=\"0\"/>\n");
-    out->writeText("    <usBreakChar value=\"32\"/>\n");
-    out->writeText("    <usMaxContext value=\"0\"/>\n");
-    out->writeText("  </OS_2>\n");
-
-    out->writeText("  <hmtx>\n");
-    for (int i = 0; i < fGlyphs.count(); ++i) {
-        out->writeText("    <mtx name=\"glyf");
-        out->writeHexAsText(i, 4);
-        out->writeText("\" width=\"");
-        out->writeDecAsText(fGlyphs[i].fAdvance);
-        out->writeText("\" lsb=\"");
-        int lsb = fGlyphs[i].fOrigin.fX;
-        if (glyfInfo) {
-            lsb += (*glyfInfo)[i].fBounds.fLeft;
-        }
-        out->writeDecAsText(lsb);
-        out->writeText("\"/>\n");
-    }
-    if (glyfInfo) {
-        for (int i = 0; i < fGlyphs.count(); ++i) {
-            for (int j = 0; j < (*glyfInfo)[i].fLayers.count(); ++j) {
-                out->writeText("    <mtx name=\"glyf");
-                    out->writeHexAsText(i, 4);
-                    out->writeText("l");
-                    out->writeHexAsText(j, 4);
-                    out->writeText("\" width=\"");
-                    out->writeDecAsText(fGlyphs[i].fAdvance);
-                    out->writeText("\" lsb=\"");
-                    int32_t lsb = fGlyphs[i].fOrigin.fX + (*glyfInfo)[i].fLayers[j].fBounds.fLeft;
-                    out->writeDecAsText(lsb);
-                    out->writeText("\"/>\n");
-            }
-        }
-    }
-    out->writeText("  </hmtx>\n");
-
-    bool hasNonBMP = false;
-    out->writeText("  <cmap>\n");
-    out->writeText("    <tableVersion version=\"0\"/>\n");
-    out->writeText("    <cmap_format_4 platformID=\"3\" platEncID=\"1\" language=\"0\">\n");
-    fCMap.foreach([&out, &hasNonBMP](const SkUnichar& c, const SkGlyphID& g) {
-        if (0xFFFF < c) {
-            hasNonBMP = true;
-            return;
-        }
-        out->writeText("      <map code=\"0x");
-        out->writeHexAsText(c, 4);
-        out->writeText("\" name=\"glyf");
-        out->writeHexAsText(g, 4);
-        out->writeText("\"/>\n");
-    });
-    out->writeText("    </cmap_format_4>\n");
-    if (hasNonBMP) {
-        out->writeText("    <cmap_format_12 platformID=\"3\" platEncID=\"10\" format=\"12\" reserved=\"0\" length=\"1\" language=\"0\" nGroups=\"0\">\n");
-        fCMap.foreach([&out](const SkUnichar& c, const SkGlyphID& g) {
-            out->writeText("      <map code=\"0x");
-            out->writeHexAsText(c, 6);
-            out->writeText("\" name=\"glyf");
-            out->writeHexAsText(g, 4);
-            out->writeText("\"/>\n");
-        });
-        out->writeText("    </cmap_format_12>\n");
-    }
-    out->writeText("  </cmap>\n");
-
-    out->writeText("  <name>\n");
-    out->writeText("    <namerecord nameID=\"1\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
-    out->writeText("      ");
-      out->writeText(fName.c_str());
-      out->writeText(" ");
-      out->writeText(type);
-      out->writeText("\n");
-    out->writeText("    </namerecord>\n");
-    out->writeText("    <namerecord nameID=\"2\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
-    out->writeText("      Regular\n");
-    out->writeText("    </namerecord>\n");
-    out->writeText("  </name>\n");
-
-    out->writeText("  <post>\n");
-    out->writeText("    <formatType value=\"3.0\"/>\n");
-    out->writeText("    <italicAngle value=\"0.0\"/>\n");
-    out->writeText("    <underlinePosition value=\"");
-        out->writeScalarAsText(fFontMetrics.fUnderlinePosition);
-        out->writeText("\"/>\n");
-    out->writeText("    <underlineThickness value=\"");
-        out->writeScalarAsText(fFontMetrics.fUnderlineThickness);
-        out->writeText("\"/>\n");
-    out->writeText("    <isFixedPitch value=\"0\"/>\n");
-    out->writeText("    <minMemType42 value=\"0\"/>\n");
-    out->writeText("    <maxMemType42 value=\"0\"/>\n");
-    out->writeText("    <minMemType1 value=\"0\"/>\n");
-    out->writeText("    <maxMemType1 value=\"0\"/>\n");
-    out->writeText("  </post>\n");
-}
-
-void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
-    out->writeText("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-    out->writeText("<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
-    this->exportTtxCommon(out, "CBDT");
-
-    int strikeSizes[3] = { 16, 64, 128 };
-
-    SkPaint paint;
-    paint.setTypeface(sk_ref_sp(const_cast<SkTestSVGTypeface*>(this)));
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
-    out->writeText("  <CBDT>\n");
-    out->writeText("    <header version=\"2.0\"/>\n");
-    for (size_t strikeIndex = 0; strikeIndex < SK_ARRAY_COUNT(strikeSizes); ++strikeIndex) {
-        paint.setTextSize(strikeSizes[strikeIndex]);
-        out->writeText("    <strikedata index=\"");
-            out->writeDecAsText(strikeIndex);
-            out->writeText("\">\n");
-        for (int i = 0; i < fGlyphs.count(); ++i) {
-            SkGlyphID gid = i;
-            SkScalar advance;
-            SkRect bounds;
-            paint.getTextWidths(&gid, sizeof(gid), &advance, &bounds);
-            SkIRect ibounds = bounds.roundOut();
-            if (ibounds.isEmpty()) {
-                continue;
-            }
-            SkImageInfo image_info = SkImageInfo::MakeN32Premul(ibounds.width(), ibounds.height());
-            sk_sp<SkSurface> surface(SkSurface::MakeRaster(image_info));
-            SkASSERT(surface);
-            SkCanvas* canvas = surface->getCanvas();
-            canvas->clear(0);
-            SkPixmap pix;
-            surface->peekPixels(&pix);
-            canvas->drawText(&gid, sizeof(gid), -bounds.fLeft, -bounds.fTop, paint);
-            canvas->flush();
-            sk_sp<SkImage> image = surface->makeImageSnapshot();
-            sk_sp<SkData> data = image->encodeToData(SkEncodedImageFormat::kPNG, 100);
-
-            out->writeText("      <cbdt_bitmap_format_17 name=\"glyf");
-                out->writeHexAsText(i, 4);
-                out->writeText("\">\n");
-            out->writeText("        <SmallGlyphMetrics>\n");
-            out->writeText("          <height value=\"");
-                out->writeDecAsText(image->height());
-                out->writeText("\"/>\n");
-            out->writeText("          <width value=\"");
-                out->writeDecAsText(image->width());
-                out->writeText("\"/>\n");
-            out->writeText("          <BearingX value=\"");
-                out->writeDecAsText(bounds.fLeft);
-                out->writeText("\"/>\n");
-            out->writeText("          <BearingY value=\"");
-                out->writeScalarAsText(-bounds.fTop);
-                out->writeText("\"/>\n");
-            out->writeText("          <Advance value=\"");
-                out->writeScalarAsText(advance);
-                out->writeText("\"/>\n");
-            out->writeText("        </SmallGlyphMetrics>\n");
-            out->writeText("        <rawimagedata>");
-            uint8_t const * bytes = data->bytes();
-            for (size_t i = 0; i < data->size(); ++i) {
-                if ((i % 0x10) == 0x0) {
-                    out->writeText("\n          ");
-                } else if (((i - 1) % 0x4) == 0x3) {
-                    out->writeText(" ");
-                }
-                out->writeHexAsText(bytes[i], 2);
-            }
-            out->writeText("\n");
-            out->writeText("        </rawimagedata>\n");
-            out->writeText("      </cbdt_bitmap_format_17>\n");
-        }
-        out->writeText("    </strikedata>\n");
-    }
-    out->writeText("  </CBDT>\n");
-
-    SkPaint::FontMetrics fm;
-    out->writeText("  <CBLC>\n");
-    out->writeText("    <header version=\"2.0\"/>\n");
-    for (size_t strikeIndex = 0; strikeIndex < SK_ARRAY_COUNT(strikeSizes); ++strikeIndex) {
-        paint.setTextSize(strikeSizes[strikeIndex]);
-        paint.getFontMetrics(&fm);
-        out->writeText("    <strike index=\"");
-            out->writeDecAsText(strikeIndex);
-            out->writeText("\">\n");
-        out->writeText("      <bitmapSizeTable>\n");
-        out->writeText("        <sbitLineMetrics direction=\"hori\">\n");
-        out->writeText("          <ascender value=\"");
-            out->writeScalarAsText(-fm.fTop);
-            out->writeText("\"/>\n");
-        out->writeText("          <descender value=\"");
-            out->writeScalarAsText(-fm.fBottom);
-            out->writeText("\"/>\n");
-        out->writeText("          <widthMax value=\"");
-            out->writeScalarAsText(fm.fXMax - fm.fXMin);
-            out->writeText("\"/>\n");
-        out->writeText("          <caretSlopeNumerator value=\"0\"/>\n");
-        out->writeText("          <caretSlopeDenominator value=\"0\"/>\n");
-        out->writeText("          <caretOffset value=\"0\"/>\n");
-        out->writeText("          <minOriginSB value=\"0\"/>\n");
-        out->writeText("          <minAdvanceSB value=\"0\"/>\n");
-        out->writeText("          <maxBeforeBL value=\"0\"/>\n");
-        out->writeText("          <minAfterBL value=\"0\"/>\n");
-        out->writeText("          <pad1 value=\"0\"/>\n");
-        out->writeText("          <pad2 value=\"0\"/>\n");
-        out->writeText("        </sbitLineMetrics>\n");
-        out->writeText("        <sbitLineMetrics direction=\"vert\">\n");
-        out->writeText("          <ascender value=\"");
-            out->writeScalarAsText(-fm.fTop);
-            out->writeText("\"/>\n");
-        out->writeText("          <descender value=\"");
-            out->writeScalarAsText(-fm.fBottom);
-            out->writeText("\"/>\n");
-        out->writeText("          <widthMax value=\"");
-            out->writeScalarAsText(fm.fXMax - fm.fXMin);
-            out->writeText("\"/>\n");
-        out->writeText("          <caretSlopeNumerator value=\"0\"/>\n");
-        out->writeText("          <caretSlopeDenominator value=\"0\"/>\n");
-        out->writeText("          <caretOffset value=\"0\"/>\n");
-        out->writeText("          <minOriginSB value=\"0\"/>\n");
-        out->writeText("          <minAdvanceSB value=\"0\"/>\n");
-        out->writeText("          <maxBeforeBL value=\"0\"/>\n");
-        out->writeText("          <minAfterBL value=\"0\"/>\n");
-        out->writeText("          <pad1 value=\"0\"/>\n");
-        out->writeText("          <pad2 value=\"0\"/>\n");
-        out->writeText("        </sbitLineMetrics>\n");
-        out->writeText("        <colorRef value=\"0\"/>\n");
-        out->writeText("        <startGlyphIndex value=\"1\"/>\n");
-        out->writeText("        <endGlyphIndex value=\"1\"/>\n");
-        out->writeText("        <ppemX value=\"");
-            out->writeDecAsText(strikeSizes[strikeIndex]);
-            out->writeText("\"/>\n");
-        out->writeText("        <ppemY value=\"");
-            out->writeDecAsText(strikeSizes[strikeIndex]);
-            out->writeText("\"/>\n");
-        out->writeText("        <bitDepth value=\"32\"/>\n");
-        out->writeText("        <flags value=\"1\"/>\n");
-        out->writeText("      </bitmapSizeTable>\n");
-        out->writeText("      <eblc_index_sub_table_1 imageFormat=\"17\" firstGlyphIndex=\"1\" lastGlyphIndex=\"1\">\n");
-        for (int i = 0; i < fGlyphs.count(); ++i) {
-            SkGlyphID gid = i;
-            SkRect bounds;
-            paint.getTextWidths(&gid, sizeof(gid), nullptr, &bounds);
-            if (bounds.isEmpty()) {
-                continue;
-            }
-            out->writeText("        <glyphLoc name=\"glyf");
-                out->writeHexAsText(i, 4);
-                out->writeText("\"/>\n");
-        }
-        out->writeText("      </eblc_index_sub_table_1>\n");
-        out->writeText("    </strike>\n");
-    }
-    out->writeText("  </CBLC>\n");
-
-    out->writeText("</ttFont>\n");
-}
-
-/**
- * UnitsPerEm is generally 1000 here. Versions of macOS older than 10.13
- * have problems in CoreText determining the glyph bounds of bitmap glyphs
- * with unitsPerEm set to 1024 or numbers not divisible by 100 when the
- * contour is not closed. The bounds of sbix fonts on macOS appear to be those
- * of the outline in the 'glyf' table. If this countour is closed it will be
- * drawn, as the 'glyf' outline is to be drawn on top of any bitmap. (There is
- * a bit which is supposed to control this, but it cannot be relied on.) So
- * make the glyph contour ta degenerate line with points at the edge of the
- * bounding box of the glyph.
- */
-void SkTestSVGTypeface::exportTtxSbix(SkWStream* out) const {
-    out->writeText("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-    out->writeText("<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
-    this->exportTtxCommon(out, "sbix");
-
-    SkPaint paint;
-    paint.setTypeface(sk_ref_sp(const_cast<SkTestSVGTypeface*>(this)));
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
-    out->writeText("  <glyf>\n");
-    for (int i = 0; i < fGlyphs.count(); ++i) {
-        const SkTestSVGTypeface::Glyph& glyphData = this->fGlyphs[i];
-
-        SkSize containerSize = glyphData.fSvg ? glyphData.fSvg->containerSize()
-                                              : SkSize::MakeEmpty();
-        SkRect bounds = SkRect::MakeXYWH(glyphData.fOrigin.fX, -glyphData.fOrigin.fY,
-                                         containerSize.fWidth, containerSize.fHeight);
-        SkIRect ibounds = bounds.roundOut();
-        out->writeText("    <TTGlyph name=\"glyf");
-            out->writeHexAsText(i, 4);
-            out->writeText("\" xMin=\"");
-            out->writeDecAsText(ibounds.fLeft);
-            out->writeText("\" yMin=\"");
-            out->writeDecAsText(-ibounds.fBottom);
-            out->writeText("\" xMax=\"");
-            out->writeDecAsText(ibounds.fRight);
-            out->writeText("\" yMax=\"");
-            out->writeDecAsText(-ibounds.fTop);
-            out->writeText("\">\n");
-        out->writeText("      <contour>\n");
-        out->writeText("        <pt x=\"");
-            out->writeDecAsText(ibounds.fLeft);
-            out->writeText("\" y=\"");
-            out->writeDecAsText(-ibounds.fBottom);
-            out->writeText("\" on=\"1\"/>\n");
-        out->writeText("      </contour>\n");
-        out->writeText("      <contour>\n");
-        out->writeText("        <pt x=\"");
-            out->writeDecAsText(ibounds.fRight);
-            out->writeText("\" y=\"");
-            out->writeDecAsText(-ibounds.fTop);
-            out->writeText("\" on=\"1\"/>\n");
-        out->writeText("      </contour>\n");
-        out->writeText("      <instructions/>\n");
-        out->writeText("    </TTGlyph>\n");
-    }
-    out->writeText("  </glyf>\n");
-
-    // The loca table will be re-calculated, but if we don't write one we don't get one.
-    out->writeText("  <loca/>\n");
-
-    int strikeSizes[3] = { 16, 64, 128 };
-
-    out->writeText("  <sbix>\n");
-    out->writeText("    <version value=\"1\"/>\n");
-    out->writeText("    <flags value=\"00000000 00000001\"/>\n");
-    for (size_t strikeIndex = 0; strikeIndex < SK_ARRAY_COUNT(strikeSizes); ++strikeIndex) {
-        paint.setTextSize(strikeSizes[strikeIndex]);
-        out->writeText("    <strike>\n");
-        out->writeText("      <ppem value=\"");
-            out->writeDecAsText(strikeSizes[strikeIndex]);
-            out->writeText("\"/>\n");
-        out->writeText("      <resolution value=\"72\"/>\n");
-        for (int i = 0; i < fGlyphs.count(); ++i) {
-            SkGlyphID gid = i;
-            SkScalar advance;
-            SkRect bounds;
-            paint.getTextWidths(&gid, sizeof(gid), &advance, &bounds);
-            SkIRect ibounds = bounds.roundOut();
-            if (ibounds.isEmpty()) {
-                continue;
-            }
-            SkImageInfo image_info = SkImageInfo::MakeN32Premul(ibounds.width(), ibounds.height());
-            sk_sp<SkSurface> surface(SkSurface::MakeRaster(image_info));
-            SkASSERT(surface);
-            SkCanvas* canvas = surface->getCanvas();
-            canvas->clear(0);
-            SkPixmap pix;
-            surface->peekPixels(&pix);
-            canvas->drawText(&gid, sizeof(gid), -bounds.fLeft, -bounds.fTop, paint);
-            canvas->flush();
-            sk_sp<SkImage> image = surface->makeImageSnapshot();
-            sk_sp<SkData> data = image->encodeToData(SkEncodedImageFormat::kPNG, 100);
-
-            out->writeText("      <glyph name=\"glyf");
-                out->writeHexAsText(i, 4);
-                out->writeText("\" graphicType=\"png \" originOffsetX=\"");
-                out->writeDecAsText(bounds.fLeft);
-                out->writeText("\" originOffsetY=\"");
-                out->writeScalarAsText(bounds.fBottom);
-                out->writeText("\">\n");
-
-            out->writeText("        <hexdata>");
-            uint8_t const * bytes = data->bytes();
-            for (size_t i = 0; i < data->size(); ++i) {
-                if ((i % 0x10) == 0x0) {
-                    out->writeText("\n          ");
-                } else if (((i - 1) % 0x4) == 0x3) {
-                    out->writeText(" ");
-                }
-                out->writeHexAsText(bytes[i], 2);
-            }
-            out->writeText("\n");
-            out->writeText("        </hexdata>\n");
-            out->writeText("      </glyph>\n");
-        }
-        out->writeText("    </strike>\n");
-    }
-    out->writeText("  </sbix>\n");
-    out->writeText("</ttFont>\n");
-}
-
-namespace {
-
-void convert_noninflect_cubic_to_quads(const SkPoint p[4],
-                                       SkScalar toleranceSqd,
-                                       SkTArray<SkPoint, true>* quads,
-                                       int sublevel = 0)
-{
-    // Notation: Point a is always p[0]. Point b is p[1] unless p[1] == p[0], in which case it is
-    // p[2]. Point d is always p[3]. Point c is p[2] unless p[2] == p[3], in which case it is p[1].
-
-    SkVector ab = p[1] - p[0];
-    SkVector dc = p[2] - p[3];
-
-    if (SkPointPriv::LengthSqd(ab) < SK_ScalarNearlyZero) {
-        if (SkPointPriv::LengthSqd(dc) < SK_ScalarNearlyZero) {
-            SkPoint* degQuad = quads->push_back_n(3);
-            degQuad[0] = p[0];
-            degQuad[1] = p[0];
-            degQuad[2] = p[3];
-            return;
-        }
-        ab = p[2] - p[0];
-    }
-    if (SkPointPriv::LengthSqd(dc) < SK_ScalarNearlyZero) {
-        dc = p[1] - p[3];
-    }
-
-    static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2;
-    static const int kMaxSubdivs = 10;
-
-    ab.scale(kLengthScale);
-    dc.scale(kLengthScale);
-
-    // e0 and e1 are extrapolations along vectors ab and dc.
-    SkVector c0 = p[0];
-    c0 += ab;
-    SkVector c1 = p[3];
-    c1 += dc;
-
-    SkScalar dSqd = sublevel > kMaxSubdivs ? 0 : SkPointPriv::DistanceToSqd(c0, c1);
-    if (dSqd < toleranceSqd) {
-        SkPoint cAvg = c0;
-        cAvg += c1;
-        cAvg.scale(SK_ScalarHalf);
-
-        SkPoint* pts = quads->push_back_n(3);
-        pts[0] = p[0];
-        pts[1] = cAvg;
-        pts[2] = p[3];
-        return;
-    }
-    SkPoint choppedPts[7];
-    SkChopCubicAtHalf(p, choppedPts);
-    convert_noninflect_cubic_to_quads(choppedPts + 0, toleranceSqd, quads, sublevel + 1);
-    convert_noninflect_cubic_to_quads(choppedPts + 3, toleranceSqd, quads, sublevel + 1);
-}
-
-void convertCubicToQuads(const SkPoint p[4], SkScalar tolScale, SkTArray<SkPoint, true>* quads) {
-    if (!p[0].isFinite() || !p[1].isFinite() || !p[2].isFinite() || !p[3].isFinite()) {
-        return;
-    }
-    SkPoint chopped[10];
-    int count = SkChopCubicAtInflections(p, chopped);
-
-    const SkScalar tolSqd = SkScalarSquare(tolScale);
-
-    for (int i = 0; i < count; ++i) {
-        SkPoint* cubic = chopped + 3*i;
-        convert_noninflect_cubic_to_quads(cubic, tolSqd, quads);
-    }
-}
-
-void path_to_quads(const SkPath& path, SkPath* quadPath) {
-    quadPath->reset();
-    SkTArray<SkPoint, true> qPts;
-    SkAutoConicToQuads converter;
-    const SkPoint* quadPts;
-    SkPath::RawIter iter(path);
-    uint8_t verb;
-    SkPoint pts[4];
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                quadPath->moveTo(pts[0].fX, pts[0].fY);
-                break;
-            case SkPath::kLine_Verb:
-                quadPath->lineTo(pts[1].fX, pts[1].fY);
-                break;
-            case SkPath::kQuad_Verb:
-                quadPath->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
-                break;
-            case SkPath::kCubic_Verb:
-                qPts.reset();
-                convertCubicToQuads(pts, SK_Scalar1, &qPts);
-                for (int i = 0; i < qPts.count(); i += 3) {
-                    quadPath->quadTo(qPts[i+1].fX, qPts[i+1].fY, qPts[i+2].fX, qPts[i+2].fY);
-                }
-                break;
-            case SkPath::kConic_Verb:
-                quadPts = converter.computeQuads(pts, iter.conicWeight(), SK_Scalar1);
-                for (int i = 0; i < converter.countQuads(); ++i) {
-                    quadPath->quadTo(quadPts[i*2+1].fX, quadPts[i*2+1].fY,
-                                     quadPts[i*2+2].fX, quadPts[i*2+2].fY);
-                }
-                break;
-            case SkPath::kClose_Verb:
-                 quadPath->close();
-                break;
-            default:
-                SkDEBUGFAIL("bad verb");
-                return;
-        }
-    }
-}
-
-class SkCOLRCanvas : public SkNoDrawCanvas {
-public:
-    SkCOLRCanvas(SkRect glyphBounds, SkGlyphID glyphId,
-                 SkTestSVGTypeface::GlyfInfo* glyf, SkTHashMap<SkColor, int>* colors,
-                 SkWStream* out)
-        : SkNoDrawCanvas(glyphBounds.roundOut().width(), glyphBounds.roundOut().height())
-        , fOut(out)
-        , fGlyphId(glyphId)
-        , fBaselineOffset(glyphBounds.top())
-        , fLayerId(0)
-        , fGlyf(glyf)
-        , fColors(colors)
-    { }
-
-    void writePoint(SkScalar x, SkScalar y, bool on) {
-        fOut->writeText("        <pt x=\"");
-        fOut->writeDecAsText(SkScalarRoundToInt(x));
-        fOut->writeText("\" y=\"");
-        fOut->writeDecAsText(SkScalarRoundToInt(y));
-        fOut->writeText("\" on=\"");
-        fOut->write8(on ? '1' : '0');
-        fOut->writeText("\"/>\n");
-    }
-    SkIRect writePath(const SkPath& path, bool layer) {
-        // Convert to quads.
-        SkPath quads;
-        path_to_quads(path, &quads);
-
-        SkRect bounds = quads.computeTightBounds();
-        SkIRect ibounds = bounds.roundOut();
-        // The bounds will be re-calculated anyway.
-        fOut->writeText("    <TTGlyph name=\"glyf");
-            fOut->writeHexAsText(fGlyphId, 4);
-            if (layer) {
-                fOut->writeText("l");
-                fOut->writeHexAsText(fLayerId, 4);
-            }
-            fOut->writeText("\" xMin=\"");
-            fOut->writeDecAsText(ibounds.fLeft);
-            fOut->writeText("\" yMin=\"");
-            fOut->writeDecAsText(ibounds.fTop);
-            fOut->writeText("\" xMax=\"");
-            fOut->writeDecAsText(ibounds.fRight);
-            fOut->writeText("\" yMax=\"");
-            fOut->writeDecAsText(ibounds.fBottom);
-            fOut->writeText("\">\n");
-
-        SkPath::RawIter iter(quads);
-        uint8_t verb;
-        SkPoint pts[4];
-        bool contourOpen = false;
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            switch (verb) {
-                case SkPath::kMove_Verb:
-                    if (contourOpen) {
-                        fOut->writeText("      </contour>\n");
-                        contourOpen = false;
-                    }
-                    break;
-                case SkPath::kLine_Verb:
-                    if (!contourOpen) {
-                        fOut->writeText("      <contour>\n");
-                        this->writePoint(pts[0].fX, pts[0].fY, true);
-                        contourOpen = true;
-                    }
-                    this->writePoint(pts[1].fX, pts[1].fY, true);
-                    break;
-                case SkPath::kQuad_Verb:
-                    if (!contourOpen) {
-                        fOut->writeText("      <contour>\n");
-                        this->writePoint(pts[0].fX, pts[0].fY, true);
-                        contourOpen = true;
-                    }
-                    this->writePoint(pts[1].fX, pts[1].fY, false);
-                    this->writePoint(pts[2].fX, pts[2].fY, true);
-                    break;
-                case SkPath::kClose_Verb:
-                    if (contourOpen) {
-                        fOut->writeText("      </contour>\n");
-                        contourOpen = false;
-                    }
-                    break;
-                default:
-                    SkDEBUGFAIL("bad verb");
-                    return ibounds;
-            }
-        }
-        if (contourOpen) {
-            fOut->writeText("      </contour>\n");
-        }
-
-        // Required to write out an instructions tag.
-        fOut->writeText("      <instructions/>\n");
-        fOut->writeText("    </TTGlyph>\n");
-        return ibounds;
-    }
-
-    void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
-        SkPath path;
-        path.addRect(rect);
-        this->drawPath(path, paint);
-    }
-
-    void onDrawOval(const SkRect& oval, const SkPaint& paint) override {
-        SkPath path;
-        path.addOval(oval);
-        this->drawPath(path, paint);
-    }
-
-    void onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
-                   const SkPaint& paint) override
-    {
-        SkPath path;
-        bool fillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
-        SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
-                                    fillNoPathEffect);
-        this->drawPath(path, paint);
-    }
-
-    void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override {
-        SkPath path;
-        path.addRRect(rrect);
-        this->drawPath(path, paint);
-    }
-
-    void onDrawPath(const SkPath& platonicPath, const SkPaint& originalPaint) override {
-        SkPaint paint = originalPaint;
-        SkPath path = platonicPath;
-
-        // Apply the path effect.
-        if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
-            bool fill = paint.getFillPath(path, &path);
-
-            paint.setPathEffect(nullptr);
-            if (fill) {
-                paint.setStyle(SkPaint::kFill_Style);
-            } else {
-                paint.setStyle(SkPaint::kStroke_Style);
-                paint.setStrokeWidth(0);
-            }
-        }
-
-        // Apply the matrix.
-        SkMatrix m = this->getTotalMatrix();
-        // If done to the canvas then everything would get clipped out.
-        m.postTranslate(0, fBaselineOffset); // put the baseline at 0
-        m.postScale(1, -1); // and flip it since OpenType is y-up.
-        path.transform(m);
-
-        // While creating the default glyf, union with dark colors and intersect with bright colors.
-        SkColor color = paint.getColor();
-        if ((SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color)) / 3 > 0x20) {
-            fBasePath.add(path, SkPathOp::kDifference_SkPathOp);
-        } else {
-            fBasePath.add(path, SkPathOp::kUnion_SkPathOp);
-        }
-
-        SkIRect bounds = this->writePath(path, true);
-
-        // The CPAL table has the concept of a 'current color' which is index 0xFFFF.
-        // Mark any layer drawn in 'currentColor' as having this special index.
-        // The value of 'currentColor' here should a color which causes this layer to union into the
-        // default glyf.
-        constexpr SkColor currentColor = 0xFF2B0000;
-
-        int colorIndex;
-        if (color == currentColor) {
-            colorIndex = 0xFFFF;
-        } else {
-            int* colorIndexPtr = fColors->find(color);
-            if (colorIndexPtr) {
-                colorIndex = *colorIndexPtr;
-            } else {
-                colorIndex = fColors->count();
-                fColors->set(color, colorIndex);
-            }
-        }
-        fGlyf->fLayers.emplace_back(colorIndex, bounds);
-
-        ++fLayerId;
-    }
-
-    void finishGlyph() {
-        SkPath baseGlyph;
-        fBasePath.resolve(&baseGlyph);
-        fGlyf->fBounds = this->writePath(baseGlyph, false);
-    }
-
-private:
-    SkWStream * const fOut;
-    SkGlyphID fGlyphId;
-    SkScalar fBaselineOffset;
-    int fLayerId;
-    SkOpBuilder fBasePath;
-    SkTestSVGTypeface::GlyfInfo* fGlyf;
-    SkTHashMap<SkColor, int>* fColors;
-};
-
-} // namespace
-
-void SkTestSVGTypeface::exportTtxColr(SkWStream* out) const {
-    out->writeText("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-    out->writeText("<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
-
-    SkTHashMap<SkColor, int> colors;
-    SkTArray<GlyfInfo> glyfInfos(fGlyphs.count());
-
-    // Need to know all the glyphs up front for the common tables.
-    SkDynamicMemoryWStream glyfOut;
-    glyfOut.writeText("  <glyf>\n");
-    for (int i = 0; i < fGlyphs.count(); ++i) {
-        const SkTestSVGTypeface::Glyph& glyphData = this->fGlyphs[i];
-
-        SkSize containerSize = glyphData.fSvg ? glyphData.fSvg->containerSize()
-                                              : SkSize::MakeEmpty();
-        SkRect bounds = SkRect::MakeXYWH(glyphData.fOrigin.fX, -glyphData.fOrigin.fY,
-                                         containerSize.fWidth, containerSize.fHeight);
-        SkCOLRCanvas canvas(bounds, i, &glyfInfos.emplace_back(), &colors, &glyfOut);
-        if (glyphData.fSvg) {
-            glyphData.fSvg->render(&canvas);
-        }
-        canvas.finishGlyph();
-    }
-    glyfOut.writeText("  </glyf>\n");
-
-    this->exportTtxCommon(out, "COLR", &glyfInfos);
-
-    // The loca table will be re-calculated, but if we don't write one we don't get one.
-    out->writeText("  <loca/>\n");
-
-    std::unique_ptr<SkStreamAsset> glyfStream = glyfOut.detachAsStream();
-    out->writeStream(glyfStream.get(), glyfStream->getLength());
-
-    out->writeText("  <COLR>\n");
-    out->writeText("    <version value=\"0\"/>\n");
-    for (int i = 0; i < fGlyphs.count(); ++i) {
-        if (glyfInfos[i].fBounds.isEmpty() || glyfInfos[i].fLayers.empty()) {
-            continue;
-        }
-        out->writeText("    <ColorGlyph name=\"glyf");
-            out->writeHexAsText(i, 4);
-            out->writeText("\">\n");
-        for (int j = 0; j < glyfInfos[i].fLayers.count(); ++j) {
-            const int colorIndex = glyfInfos[i].fLayers[j].fLayerColorIndex;
-            out->writeText("      <layer colorID=\"");
-                out->writeDecAsText(colorIndex);
-                out->writeText("\" name=\"glyf");
-                out->writeHexAsText(i, 4);
-                out->writeText("l");
-                out->writeHexAsText(j, 4);
-                out->writeText("\"/>\n");
-        }
-        out->writeText("    </ColorGlyph>\n");
-    }
-    out->writeText("  </COLR>\n");
-
-    // The colors must be written in order, the 'index' is ignored by ttx.
-    SkAutoTMalloc<SkColor> colorsInOrder(colors.count());
-    colors.foreach([&colorsInOrder](const SkColor& c, const int* i) {
-        colorsInOrder[*i] = c;
-    });
-    out->writeText("  <CPAL>\n");
-    out->writeText("    <version value=\"0\"/>\n");
-    out->writeText("    <numPaletteEntries value=\"");
-        out->writeDecAsText(colors.count());
-        out->writeText("\"/>\n");
-    out->writeText("    <palette index=\"0\">\n");
-    for (int i = 0; i < colors.count(); ++i) {
-        SkColor c = colorsInOrder[i];
-        out->writeText("      <color index=\"");
-            out->writeDecAsText(i);
-            out->writeText("\" value=\"#");
-            out->writeHexAsText(SkColorGetR(c), 2);
-            out->writeHexAsText(SkColorGetG(c), 2);
-            out->writeHexAsText(SkColorGetB(c), 2);
-            out->writeHexAsText(SkColorGetA(c), 2);
-            out->writeText("\"/>\n");
-    }
-    out->writeText("    </palette>\n");
-    out->writeText("  </CPAL>\n");
-
-    out->writeText("</ttFont>\n");
-}
diff --git a/tools/fonts/SkTestSVGTypeface.h b/tools/fonts/SkTestSVGTypeface.h
deleted file mode 100644
index 86c8285..0000000
--- a/tools/fonts/SkTestSVGTypeface.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkTestSVGTypeface_DEFINED
-#define SkTestSVGTypeface_DEFINED
-
-#include "SkFontArguments.h"
-#include "SkPaint.h"
-#include "SkPoint.h"
-#include "SkRect.h"
-#include "SkRefCnt.h"
-#include "SkScalar.h"
-#include "SkString.h"
-#include "SkTArray.h"
-#include "SkTHash.h"
-#include "SkTypeface.h"
-#include "SkTypes.h"
-
-#include <memory>
-
-class SkDescriptor;
-class SkFontDescriptor;
-class SkFontStyle;
-class SkGlyph;
-class SkPath;
-class SkScalerContext;
-class SkStreamAsset;
-class SkSVGDOM;
-class SkWStream;
-struct SkAdvancedTypefaceMetrics;
-struct SkScalerContextEffects;
-struct SkScalerContextRec;
-
-struct SkSVGTestTypefaceGlyphData {
-    const char* fSvgResourcePath;
-    SkPoint fOrigin;
-    SkScalar fAdvance;
-    SkUnichar fUnicode; //TODO: this limits to 1:1
-};
-
-class SkTestSVGTypeface : public SkTypeface {
-public:
-    SkTestSVGTypeface(const char* name,
-                      int upem,
-                      const SkPaint::FontMetrics& metrics,
-                      const SkSVGTestTypefaceGlyphData* data, int dataCount,
-                      const SkFontStyle& style);
-    ~SkTestSVGTypeface() override;
-    void getAdvance(SkGlyph* glyph) const;
-    void getFontMetrics(SkPaint::FontMetrics* metrics) const;
-    void getPath(SkGlyphID glyph, SkPath* path) const;
-
-    static sk_sp<SkTestSVGTypeface> Default();
-    void exportTtxCbdt(SkWStream*) const;
-    void exportTtxSbix(SkWStream*) const;
-    void exportTtxColr(SkWStream*) const;
-
-    struct GlyfLayerInfo {
-        GlyfLayerInfo(int layerColorIndex, SkIRect bounds)
-            : fLayerColorIndex(layerColorIndex)
-            , fBounds(bounds) {}
-        int fLayerColorIndex;
-        SkIRect fBounds;
-    };
-    struct GlyfInfo {
-        GlyfInfo() : fBounds(SkIRect::MakeEmpty()) {}
-        SkIRect fBounds;
-        SkTArray<GlyfLayerInfo> fLayers;
-    };
-protected:
-    void exportTtxCommon(SkWStream*, const char* type, const SkTArray<GlyfInfo>* = nullptr) const;
-
-    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
-                                           const SkDescriptor* desc) const override;
-    void onFilterRec(SkScalerContextRec* rec) const override;
-    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
-
-    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
-        return nullptr;
-    }
-
-    void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
-
-    int onCharsToGlyphs(const void* chars, Encoding encoding,
-                        uint16_t glyphs[], int glyphCount) const override;
-
-    int onCountGlyphs() const override {
-        return fGlyphs.count();
-    }
-
-    int onGetUPEM() const override {
-        return fUpem;
-    }
-
-    void onGetFamilyName(SkString* familyName) const override;
-    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
-
-    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
-                                     int coordinateCount) const override
-    {
-        return 0;
-    }
-
-    int onGetTableTags(SkFontTableTag tags[]) const override {
-        return 0;
-    }
-
-    size_t onGetTableData(SkFontTableTag tag, size_t offset,
-                          size_t length, void* data) const override {
-        return 0;
-    }
-private:
-    struct Glyph {
-        Glyph(sk_sp<SkSVGDOM> svg, const SkSVGTestTypefaceGlyphData& data);
-        ~Glyph();
-        sk_sp<SkSVGDOM> fSvg;
-        SkPoint fOrigin;
-        SkScalar fAdvance;
-    };
-    SkString fName;
-    int fUpem;
-    const SkPaint::FontMetrics fFontMetrics;
-    SkTArray<Glyph> fGlyphs;
-    SkTHashMap<SkUnichar, SkGlyphID> fCMap;
-    friend class SkTestSVGScalerContext;
-};
-
-#endif
diff --git a/tools/fonts/SkTestTypeface.cpp b/tools/fonts/SkTestScalerContext.cpp
similarity index 97%
rename from tools/fonts/SkTestTypeface.cpp
rename to tools/fonts/SkTestScalerContext.cpp
index 52751c9..f74b1bd 100644
--- a/tools/fonts/SkTestTypeface.cpp
+++ b/tools/fonts/SkTestScalerContext.cpp
@@ -8,25 +8,18 @@
 #include "SkAdvancedTypefaceMetrics.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkDescriptor.h"
 #include "SkFontDescriptor.h"
 #include "SkGlyph.h"
-#include "SkImageInfo.h"
-#include "SkMatrix.h"
+#include "SkMakeUnique.h"
+#include "SkMask.h"
 #include "SkOTUtils.h"
 #include "SkPaintPriv.h"
-#include "SkPath.h"
-#include "SkPoint.h"
-#include "SkRect.h"
 #include "SkScalerContext.h"
-#include "SkString.h"
-#include "SkTestTypeface.h"
-#include "SkTDArray.h"
+#include "SkTestScalerContext.h"
+#include "SkTypefaceCache.h"
 #include "SkUtils.h"
 
-#include <utility>
-
-class SkDescriptor;
-
 SkTestFont::SkTestFont(const SkTestFontData& fontData)
     : INHERITED()
     , fCharCodes(fontData.fCharCodes)
diff --git a/tools/fonts/SkTestTypeface.h b/tools/fonts/SkTestScalerContext.h
similarity index 87%
rename from tools/fonts/SkTestTypeface.h
rename to tools/fonts/SkTestScalerContext.h
index b520fb6..e62210b 100644
--- a/tools/fonts/SkTestTypeface.h
+++ b/tools/fonts/SkTestScalerContext.h
@@ -5,31 +5,17 @@
  * found in the LICENSE file.
  */
 
-#ifndef SkTestTypeface_DEFINED
-#define SkTestTypeface_DEFINED
+#ifndef SkTestScalerContext_DEFINED
+#define SkTestScalerContext_DEFINED
 
 #include "SkFixed.h"
-#include "SkFontArguments.h"
-#include "SkFontStyle.h"
 #include "SkPaint.h"
+#include "SkPath.h"
 #include "SkRefCnt.h"
-#include "SkScalar.h"
+#include "SkTDArray.h"
 #include "SkTypeface.h"
-#include "SkTypes.h"
 
-#include <memory>
-
-class SkDescriptor;
-class SkFontDescriptor;
-class SkGlyph;
-class SkPath;
-class SkScalerContext;
-class SkStreamAsset;
-class SkString;
 class SkTestFont;
-struct SkAdvancedTypefaceMetrics;
-struct SkScalerContextEffects;
-struct SkScalerContextRec;
 
 struct SkTestFontData {
     const SkScalar* fPoints;
diff --git a/tools/fonts/create_test_font_color.cpp b/tools/fonts/create_test_font_color.cpp
deleted file mode 100644
index c3f2e08..0000000
--- a/tools/fonts/create_test_font_color.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-// running create_test_font_color generates ./<cbdt|sbix|cpal>.ttx
-// which are read by fonttools ttx to produce native fonts.
-
-#include "SkCommandLineFlags.h"
-#include "SkRefCnt.h"
-#include "SkStream.h"
-#include "SkTestSVGTypeface.h"
-
-int main(int argc, char** argv) {
-    SkCommandLineFlags::Parse(argc, argv);
-
-    sk_sp<SkTestSVGTypeface> typeface = SkTestSVGTypeface::Default();
-
-    SkFILEWStream cbdt("cbdt.ttx");
-    typeface->exportTtxCbdt(&cbdt);
-    cbdt.flush();
-    cbdt.fsync();
-
-    SkFILEWStream sbix("sbix.ttx");
-    typeface->exportTtxSbix(&sbix);
-    sbix.flush();
-    sbix.fsync();
-
-    SkFILEWStream colr("colr.ttx");
-    typeface->exportTtxColr(&colr);
-    colr.flush();
-    colr.fsync();
-
-    return 0;
-}
diff --git a/tools/fonts/sk_tool_utils_font.cpp b/tools/fonts/sk_tool_utils_font.cpp
index 4d5b86a..d2aac85 100644
--- a/tools/fonts/sk_tool_utils_font.cpp
+++ b/tools/fonts/sk_tool_utils_font.cpp
@@ -11,7 +11,7 @@
 #include "SkFontStyle.h"
 #include "SkMutex.h"
 #include "SkOSFile.h"
-#include "SkTestTypeface.h"
+#include "SkTestScalerContext.h"
 #include "SkUtils.h"
 #include "sk_tool_utils.h"
 
@@ -70,23 +70,42 @@
 }
 
 sk_sp<SkTypeface> emoji_typeface() {
-    const char* filename;
 #if defined(SK_BUILD_FOR_WIN)
-    filename = "fonts/colr.ttf";
-#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
-    filename = "fonts/sbix.ttf";
-#else
-    filename = "fonts/cbdt.ttf";
-#endif
-    sk_sp<SkTypeface> typeface = MakeResourceAsTypeface(filename);
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
+    const char *colorEmojiFontName = "Segoe UI Emoji";
+    sk_sp<SkTypeface> typeface(fm->matchFamilyStyle(colorEmojiFontName, SkFontStyle()));
     if (typeface) {
         return typeface;
     }
-    return SkTypeface::MakeFromName("Emoji", SkFontStyle());
+    sk_sp<SkTypeface> fallback(fm->matchFamilyStyleCharacter(
+        colorEmojiFontName, SkFontStyle(), nullptr /* bcp47 */, 0 /* bcp47Count */,
+        0x1f4b0 /* character: πŸ’° */));
+    if (fallback) {
+        return fallback;
+    }
+    // If we don't have Segoe UI Emoji and can't find a fallback, try Segoe UI Symbol.
+    // Windows 7 does not have Segoe UI Emoji; Segoe UI Symbol has the (non - color) emoji.
+    return SkTypeface::MakeFromName("Segoe UI Symbol", SkFontStyle());
+
+#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
+    return SkTypeface::MakeFromName("Apple Color Emoji", SkFontStyle());
+
+#else
+    return MakeResourceAsTypeface("fonts/Funkster.ttf");
+
+#endif
 }
 
 const char* emoji_sample_text() {
-    return "\xF0\x9F\x98\x80" " " "\xE2\x99\xA2"; // πŸ˜€ β™’
+#if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
+    return "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85"  // πŸ’°πŸ‘πŸŽ…
+           "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80"  // πŸͺπŸ•πŸš€
+           "\xF0\x9F\x9A\xBB" "\xF0\x9F\x92\xA9" "\xF0\x9F\x93\xB7"  // πŸš»πŸ’©πŸ“·
+           "\xF0\x9F\x93\xA6"                                        // πŸ“¦
+           "\xF0\x9F\x87\xBA" "\xF0\x9F\x87\xB8" "\xF0\x9F\x87\xA6"; // πŸ‡ΊπŸ‡ΈπŸ‡¦
+#else
+    return "Hamburgefons";
+#endif
 }
 
 static const char* platform_os_name() {
diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp
index 99b03a4..2eb8dba 100644
--- a/tools/sk_tool_utils.cpp
+++ b/tools/sk_tool_utils.cpp
@@ -5,29 +5,19 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmap.h"
-#include "SkBlendMode.h"
-#include "SkCanvas.h"
-#include "SkColorData.h"
-#include "SkColorPriv.h"
-#include "SkFloatingPoint.h"
-#include "SkImage.h"
-#include "SkMatrix.h"
-#include "SkPM4f.h"
-#include "SkPaint.h"
-#include "SkPath.h"
-#include "SkPixelRef.h"
-#include "SkPixmap.h"
-#include "SkPoint.h"
-#include "SkRRect.h"
-#include "SkShader.h"
-#include "SkSurface.h"
-#include "SkTextBlob.h"
 #include "sk_tool_utils.h"
 
-#include <cmath>
-#include <cstring>
-#include <memory>
+#include "Resources.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkImage.h"
+#include "SkPixelRef.h"
+#include "SkPM4f.h"
+#include "SkPoint3.h"
+#include "SkShader.h"
+#include "SkSurface.h"
+#include "SkTestScalerContext.h"
+#include "SkTextBlob.h"
 
 namespace sk_tool_utils {
 
@@ -169,7 +159,7 @@
     #pragma optimize("", off)
 #endif
 void make_big_path(SkPath& path) {
-    #include "BigPathBench.inc" // IWYU pragma: keep
+    #include "BigPathBench.inc"
 }
 
 static float gaussian2d_value(int x, int y, float sigma) {
diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h
index 30d195d..6c1adf8 100644
--- a/tools/sk_tool_utils.h
+++ b/tools/sk_tool_utils.h
@@ -9,33 +9,26 @@
 #define sk_tool_utils_DEFINED
 
 #include "SkColor.h"
-#include "SkData.h"
-#include "SkEncodedImageFormat.h"
-#include "SkFontStyle.h"
 #include "SkImageEncoder.h"
 #include "SkImageInfo.h"
 #include "SkRandom.h"
-#include "SkRect.h"
 #include "SkRefCnt.h"
-#include "SkScalar.h"
 #include "SkStream.h"
-#include "SkTArray.h"
 #include "SkTDArray.h"
-#include "SkTypes.h"
+#include "SkTypeface.h"
 
 class SkBitmap;
 class SkCanvas;
-class SkFontStyle;
+class SkColorFilter;
 class SkImage;
 class SkPaint;
 class SkPath;
-class SkPixmap;
 class SkRRect;
 class SkShader;
 class SkSurface;
 class SkSurfaceProps;
+class SkTestFont;
 class SkTextBlobBuilder;
-class SkTypeface;
 
 namespace sk_tool_utils {