Add nativeFonts flag to Viewer.

This moves DMFontMgr and several related files which are tightly related
to fonts into tools/fonts, moves some flags around to prevent
duplication, and adds the nativeFonts handling to Viewer.

Change-Id: Id1bdad708a6b74319ac5ac9adfe21025db4ca0b2
Reviewed-on: https://skia-review.googlesource.com/108904
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 240ba78..30af600 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1236,6 +1236,7 @@
     public_include_dirs = [
       "tools",
       "tools/debugger",
+      "tools/fonts",
       "tools/timer",
       "tools/trace",
     ]
@@ -1245,8 +1246,6 @@
       "tools/LsanSuppressions.cpp",
       "tools/ProcStats.cpp",
       "tools/Resources.cpp",
-      "tools/SkRandomScalerContext.cpp",
-      "tools/SkTestScalerContext.cpp",
       "tools/UrlDataManager.cpp",
       "tools/debugger/SkDebugCanvas.cpp",
       "tools/debugger/SkDrawCommand.cpp",
@@ -1255,7 +1254,10 @@
       "tools/picture_utils.cpp",
       "tools/random_parse_path.cpp",
       "tools/sk_tool_utils.cpp",
-      "tools/sk_tool_utils_font.cpp",
+      "tools/fonts/sk_tool_utils_font.cpp",
+      "tools/fonts/SkRandomScalerContext.cpp",
+      "tools/fonts/SkTestScalerContext.cpp",
+      "tools/fonts/SkTestFontMgr.cpp",
       "tools/timer/Timer.cpp",
       "tools/trace/SkChromeTracingTracer.cpp",
       "tools/trace/SkChromeTracingTracer.h",
@@ -1511,7 +1513,6 @@
     test_app("dm") {
       sources = [
         "dm/DM.cpp",
-        "dm/DMFontMgr.cpp",
         "dm/DMGpuTestProcs.cpp",
         "dm/DMJsonWriter.cpp",
         "dm/DMSrcSink.cpp",
@@ -1629,7 +1630,7 @@
 
   test_app("create_test_font") {
     sources = [
-      "tools/create_test_font.cpp",
+      "tools/fonts/create_test_font.cpp",
     ]
     deps = [
       ":skia",
@@ -1789,7 +1790,6 @@
         defines += [ "SK_SKQP_ENABLE_DRIVER_CORRECTNESS_WORKAROUNDS" ]
       }
       sources = [
-        "dm/DMFontMgr.cpp",
         "dm/DMGpuTestProcs.cpp",
         "tools/skqp/gm_knowledge.cpp",
         "tools/skqp/gm_runner.cpp",
diff --git a/dm/DM.cpp b/dm/DM.cpp
index f1c4a4c..ef35e2c 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "DMFontMgr.h"
 #include "DMJsonWriter.h"
 #include "DMSrcSink.h"
 #include "ProcStats.h"
@@ -37,6 +36,7 @@
 #include "SkPngEncoder.h"
 #include "SkScan.h"
 #include "SkSpinlock.h"
+#include "SkTestFontMgr.h"
 #include "SkTHash.h"
 #include "SkTaskGroup.h"
 #include "SkTypeface_win.h"
@@ -103,8 +103,6 @@
 
 DEFINE_string(dont_write, "", "File extensions to skip writing to --writePath.");  // See skia:6821
 
-DEFINE_bool(nativeFonts, true, "If true, use native font manager and rendering. "
-                               "If false, fonts will draw as portably as possible.");
 DEFINE_bool(gdi, false, "On Windows, use GDI instead of DirectWrite for font rendering.");
 
 using namespace DM;
@@ -1323,7 +1321,7 @@
     SkCommandLineFlags::Parse(argc, argv);
 
     if (!FLAGS_nativeFonts) {
-        gSkFontMgr_DefaultFactory = &DM::MakeFontMgr;
+        gSkFontMgr_DefaultFactory = &sk_tool_utils::MakePortableFontMgr;
     }
 
 #if defined(SK_BUILD_FOR_WIN)
diff --git a/dm/DMFontMgr.h b/dm/DMFontMgr.h
deleted file mode 100644
index dbbe61c..0000000
--- a/dm/DMFontMgr.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef DMFontMgr_DEFINED
-#define DMFontMgr_DEFINED
-
-#include "SkFontMgr.h"
-
-// An SkFontMgr that always uses sk_tool_utils::create_portable_typeface().
-
-namespace DM {
-    sk_sp<SkFontMgr> MakeFontMgr();
-}  // namespace DM
-
-#endif//DMFontMgr_DEFINED
diff --git a/public.bzl b/public.bzl
index 0880254..41ecb2d 100644
--- a/public.bzl
+++ b/public.bzl
@@ -438,16 +438,23 @@
         "tools/Resources.cpp",
         "tools/Resources.h",
         "tools/SkJSONCPP.h",
-        "tools/SkRandomScalerContext.cpp",
-        "tools/SkRandomScalerContext.h",
-        "tools/SkTestScalerContext.cpp",
-        "tools/SkTestScalerContext.h",
         "tools/UrlDataManager.cpp",
         "tools/UrlDataManager.h",
         "tools/debugger/*.cpp",
         "tools/debugger/*.h",
         "tools/flags/*.cpp",
         "tools/flags/*.h",
+        "tools/fonts/SkRandomScalerContext.cpp",
+        "tools/fonts/SkRandomScalerContext.h",
+        "tools/fonts/SkTestFontMgr.cpp",
+        "tools/fonts/SkTestFontMgr.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",
+        "tools/fonts/test_font_serif.inc",
+        "tools/fonts/test_font_index.inc",
         "tools/gpu/**/*.cpp",
         "tools/gpu/**/*.h",
         "tools/picture_utils.cpp",
@@ -456,11 +463,6 @@
         "tools/random_parse_path.h",
         "tools/sk_tool_utils.cpp",
         "tools/sk_tool_utils.h",
-        "tools/sk_tool_utils_font.cpp",
-        "tools/test_font_monospace.inc",
-        "tools/test_font_sans_serif.inc",
-        "tools/test_font_serif.inc",
-        "tools/test_font_index.inc",
         "tools/timer/*.cpp",
         "tools/timer/*.h",
         "tools/trace/*.cpp",
@@ -520,6 +522,7 @@
     "tools",
     "tools/debugger",
     "tools/flags",
+    "tools/fonts",
     "tools/gpu",
     "tools/timer",
     "tools/trace",
diff --git a/tools/flags/SkCommonFlags.cpp b/tools/flags/SkCommonFlags.cpp
index 27b8c2d..ed7f9da 100644
--- a/tools/flags/SkCommonFlags.cpp
+++ b/tools/flags/SkCommonFlags.cpp
@@ -31,13 +31,13 @@
                                 "For nanobench, this means always N32, Premul or Opaque.");
 
 DEFINE_string2(match, m, nullptr,
-               "[~][^]substring[$] [...] of GM name to run.\n"
+               "[~][^]substring[$] [...] of name to run.\n"
                "Multiple matches may be separated by spaces.\n"
-               "~ causes a matching GM to always be skipped\n"
-               "^ requires the start of the GM to match\n"
-               "$ requires the end of the GM to match\n"
+               "~ causes a matching name to always be skipped\n"
+               "^ requires the start of the name to match\n"
+               "$ requires the end of the name to match\n"
                "^ and $ requires an exact match\n"
-               "If a GM does not match any list entry,\n"
+               "If a name does not match any list entry,\n"
                "it is skipped unless some list entry starts with ~");
 
 DEFINE_bool2(quiet, q, false, "if true, don't print status updates.");
@@ -53,9 +53,18 @@
 DEFINE_bool(disableDriverCorrectnessWorkarounds, false, "Disables all GPU driver correctness "
             "workarounds");
 
+#ifdef SK_BUILD_FOR_ANDROID
+DEFINE_string(skps, "/data/local/tmp/skps", "Directory to read skps from.");
+DEFINE_string(jpgs, "/data/local/tmp/resources", "Directory to read jpgs from.");
+DEFINE_string(jsons, "/data/local/tmp/jsons", "Directory to read (Bodymovin) jsons from.");
+#else
 DEFINE_string(skps, "skps", "Directory to read skps from.");
+DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from.");
+DEFINE_string(jsons, "jsons", "Directory to read (Bodymovin) jsons from.");
+#endif
 
-DEFINE_string(jsons, "", "Directory to read Bodymovin JSONs from, or a single JSON file.");
+DEFINE_bool(nativeFonts, true, "If true, use native font manager and rendering. "
+                               "If false, fonts will draw as portably as possible.");
 
 DEFINE_string(svgs, "", "Directory to read SVGs from, or a single SVG file.");
 
diff --git a/tools/flags/SkCommonFlags.h b/tools/flags/SkCommonFlags.h
index a3eb001..96bd6f3 100644
--- a/tools/flags/SkCommonFlags.h
+++ b/tools/flags/SkCommonFlags.h
@@ -25,8 +25,10 @@
 DECLARE_bool(releaseAndAbandonGpuContext);
 DECLARE_string(skps);
 DECLARE_bool(ddl);
+DECLARE_string(jpgs);
 DECLARE_string(jsons);
 DECLARE_string(svgs);
+DECLARE_bool(nativeFonts);
 DECLARE_int32(threads);
 DECLARE_string(resourcePath);
 DECLARE_bool(verbose);
diff --git a/tools/SkRandomScalerContext.cpp b/tools/fonts/SkRandomScalerContext.cpp
similarity index 100%
rename from tools/SkRandomScalerContext.cpp
rename to tools/fonts/SkRandomScalerContext.cpp
diff --git a/tools/SkRandomScalerContext.h b/tools/fonts/SkRandomScalerContext.h
similarity index 100%
rename from tools/SkRandomScalerContext.h
rename to tools/fonts/SkRandomScalerContext.h
diff --git a/dm/DMFontMgr.cpp b/tools/fonts/SkTestFontMgr.cpp
similarity index 96%
rename from dm/DMFontMgr.cpp
rename to tools/fonts/SkTestFontMgr.cpp
index d591572..3b5d158 100644
--- a/dm/DMFontMgr.cpp
+++ b/tools/fonts/SkTestFontMgr.cpp
@@ -5,8 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "DMFontMgr.h"
 #include "SkFontDescriptor.h"
+#include "SkTestFontMgr.h"
 #include "sk_tool_utils.h"
 
 namespace {
@@ -142,6 +142,6 @@
 };
 }
 
-namespace DM {
-sk_sp<SkFontMgr> MakeFontMgr() { return sk_make_sp<FontMgr>(); }
-} // namespace DM
+namespace sk_tool_utils {
+sk_sp<SkFontMgr> MakePortableFontMgr() { return sk_make_sp<FontMgr>(); }
+} // namespace sk_tool_utils
diff --git a/tools/fonts/SkTestFontMgr.h b/tools/fonts/SkTestFontMgr.h
new file mode 100644
index 0000000..6f4bb9c
--- /dev/null
+++ b/tools/fonts/SkTestFontMgr.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTestFontMgr_DEFINED
+#define SkTestFontMgr_DEFINED
+
+#include "SkFontMgr.h"
+
+// An SkFontMgr that always uses sk_tool_utils::create_portable_typeface().
+
+namespace sk_tool_utils {
+    sk_sp<SkFontMgr> MakePortableFontMgr();
+}  // namespace sk_tool_utils
+
+#endif  //SkTestFontMgr_DEFINED
diff --git a/tools/SkTestScalerContext.cpp b/tools/fonts/SkTestScalerContext.cpp
similarity index 100%
rename from tools/SkTestScalerContext.cpp
rename to tools/fonts/SkTestScalerContext.cpp
diff --git a/tools/SkTestScalerContext.h b/tools/fonts/SkTestScalerContext.h
similarity index 100%
rename from tools/SkTestScalerContext.h
rename to tools/fonts/SkTestScalerContext.h
diff --git a/tools/create_test_font.cpp b/tools/fonts/create_test_font.cpp
similarity index 98%
rename from tools/create_test_font.cpp
rename to tools/fonts/create_test_font.cpp
index 7b8fd43..51c56ea 100644
--- a/tools/create_test_font.cpp
+++ b/tools/fonts/create_test_font.cpp
@@ -5,10 +5,10 @@
  * found in the LICENSE file.
  */
 
-// running create_test_font generates ./tools/test_font_index.inc
-// and ./tools/test_font_<generic name>.inc which are read by ./tools/sk_tool_utils_font.cpp
+// Running create_test_font generates ./tools/fonts/test_font_index.inc
+// and ./tools/fonts/test_font_<generic name>.inc which are read by
+// ./tools/fonts/sk_tool_utils_font.cpp
 
-#include "Resources.h"
 #include "SkFontStyle.h"
 #include "SkOSFile.h"
 #include "SkOSPath.h"
@@ -72,6 +72,7 @@
 
 static FILE* font_header(const char* family) {
     SkString outPath(SkOSPath::Join(".", "tools"));
+    outPath = SkOSPath::Join(outPath.c_str(), "fonts");
     outPath = SkOSPath::Join(outPath.c_str(), "test_font_");
     SkString fam(family);
     do {
diff --git a/tools/generate_fir_coeff.py b/tools/fonts/generate_fir_coeff.py
similarity index 67%
rename from tools/generate_fir_coeff.py
rename to tools/fonts/generate_fir_coeff.py
index 70f521f..f5cc5e5 100644
--- a/tools/generate_fir_coeff.py
+++ b/tools/fonts/generate_fir_coeff.py
@@ -28,18 +28,26 @@
     return (withinStdDev(b) - withinStdDev(a)) / 2;
 
 
-#We have a bunch of smudged samples which represent the average coverage of a range.
-#We have a 'center' which may not line up with those samples.
-#From the 'center' we want to make a normal approximation where '5' sample width out we're at '3' std deviations.
-#The first and last samples may not be fully covered.
+# We have some smudged samples which represent the average coverage of a range.
+# We have a 'center' which may not line up with those samples.
+# From center make a normal where 5 sample widths out is at 3 std deviations.
+# The first and last samples may not be fully covered.
 
-#This is the sub-sample shift for each set of FIR coefficients (the centers of the lcds in the samples)
-#Each subpxl takes up 1/3 of a pixel, so they are centered at x=(i/n+1/2n), or 1/6, 3/6, 5/6 of a pixel.
-#Each sample takes up 1/4 of a pixel, so the results fall at (x*4)%1, or 2/3, 0, 1/3 of a sample.
+# This is the sub-sample shift for each set of FIR coefficients
+#   (the centers of the lcds in the samples)
+# Each subpxl takes up 1/3 of a pixel,
+#   so they are centered at x=(i/n+1/2n), or 1/6, 3/6, 5/6 of a pixel.
+# Each sample takes up 1/4 of a pixel,
+#   so the results fall at (x*4)%1, or 2/3, 0, 1/3 of a sample.
 samples_per_pixel = 4
 subpxls_per_pixel = 3
 #sample_offsets is (frac, int) in sample units.
-sample_offsets = [math.modf((float(subpxl_index)/subpxls_per_pixel + 1.0/(2.0*subpxls_per_pixel))*samples_per_pixel) for subpxl_index in range(subpxls_per_pixel)]
+sample_offsets = [
+  math.modf(
+    (float(subpxl_index)/subpxls_per_pixel + 1.0/(2.0*subpxls_per_pixel))
+    * samples_per_pixel
+  ) for subpxl_index in range(subpxls_per_pixel)
+]
 
 #How many samples to consider to the left and right of the subpxl center.
 sample_units_width = 5
@@ -65,7 +73,9 @@
     if current_sample_right > sample_offset + sample_units_width:
       done = True
       current_sample_right = sample_offset + sample_units_width
-    current_std_dev_right = current_std_dev_left + ((current_sample_right - current_sample_left) / sample_units_width) * std_dev_max
+    current_std_dev_right = current_std_dev_left + (
+      (current_sample_right - current_sample_left) / sample_units_width
+    ) * std_dev_max
 
     coverage = withinStdDevRange(current_std_dev_left, current_std_dev_right)
     coeffs.append(coverage * target_sum)
@@ -74,15 +84,17 @@
     current_sample_left = current_sample_right
     current_std_dev_left = current_std_dev_right
 
-  # Now we have the numbers we want, but our rounding needs to add up to target_sum.
+  # Have the numbers, but rounding needs to add up to target_sum.
   delta = 0
   coeffs_rounded_sum = sum(coeffs_rounded)
   if coeffs_rounded_sum > target_sum:
-    # The coeffs add up to too much. Subtract 1 from the ones which were rounded up the most.
+    # The coeffs add up to too much.
+    # Subtract 1 from the ones which were rounded up the most.
     delta = -1
 
   if coeffs_rounded_sum < target_sum:
-    # The coeffs add up to too little. Add 1 to the ones which were rounded down the most.
+    # The coeffs add up to too little.
+    # Add 1 to the ones which were rounded down the most.
     delta = 1
 
   if delta:
@@ -102,18 +114,20 @@
     coeff_pkg = [IndexTracker(i, diff) for i, diff in enumerate(coeff_diff)]
     coeff_pkg.sort()
 
-    # num_elements_to_force_round had better be < (2 * sample_units_width + 1) or
+    # num_elements_to_force_round better be < (2 * sample_units_width + 1) or
     # * our math was wildy wrong
     # * an awful lot of the curve is out side our sample
     # either is pretty bad, and probably means the results will not be useful.
     num_elements_to_force_round = abs(coeffs_rounded_sum - target_sum)
     for i in xrange(num_elements_to_force_round):
-      print "Adding %d to index %d to force round %f." % (delta, coeff_pkg[i].index, coeffs[coeff_pkg[i].index])
+      print "Adding %d to index %d to force round %f." % (
+          delta, coeff_pkg[i].index, coeffs[coeff_pkg[i].index])
       coeffs_rounded[coeff_pkg[i].index] += delta
 
   print "Prepending %d 0x00 for allignment." % (sample_align,)
   coeffs_rounded_aligned = ([0] * int(sample_align)) + coeffs_rounded
 
-  print ', '.join(["0x%0.2X" % coeff_rounded for coeff_rounded in coeffs_rounded_aligned])
+  print ', '.join(["0x%0.2X" % coeff_rounded
+                   for coeff_rounded in coeffs_rounded_aligned])
   print sum(coeffs), hex(sum(coeffs_rounded))
   print
diff --git a/tools/fonts/sk_tool_utils_font.cpp b/tools/fonts/sk_tool_utils_font.cpp
new file mode 100644
index 0000000..d2aac85
--- /dev/null
+++ b/tools/fonts/sk_tool_utils_font.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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 "SkCommonFlags.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkMutex.h"
+#include "SkOSFile.h"
+#include "SkTestScalerContext.h"
+#include "SkUtils.h"
+#include "sk_tool_utils.h"
+
+namespace sk_tool_utils {
+
+#include "test_font_monospace.inc"
+#include "test_font_sans_serif.inc"
+#include "test_font_serif.inc"
+#include "test_font_index.inc"
+
+void release_portable_typefaces() {
+    for (int index = 0; index < gTestFontsCount; ++index) {
+        SkTestFontData& fontData = gTestFonts[index];
+        fontData.fCachedFont.reset();
+    }
+}
+
+SK_DECLARE_STATIC_MUTEX(gTestFontMutex);
+
+sk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) {
+    SkTestFontData* fontData = nullptr;
+    const SubFont* sub;
+    if (name) {
+        for (int index = 0; index < gSubFontsCount; ++index) {
+            sub = &gSubFonts[index];
+            if (!strcmp(name, sub->fName) && sub->fStyle == style) {
+                fontData = &sub->fFont;
+                break;
+            }
+        }
+        if (!fontData) {
+            // Once all legacy callers to portable fonts are converted, replace this with
+            // SK_ABORT();
+            SkDebugf("missing %s weight %d, width %d, slant %d\n",
+                     name, style.weight(), style.width(), style.slant());
+            // If we called SkTypeface::CreateFromName() here we'd recurse infinitely,
+            // so we reimplement its core logic here inline without the recursive aspect.
+            sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
+            return fm->legacyMakeTypeface(name, style);
+        }
+    } else {
+        sub = &gSubFonts[gDefaultFontIndex];
+        fontData = &sub->fFont;
+    }
+    sk_sp<SkTestFont> font;
+    {
+        SkAutoMutexAcquire ac(gTestFontMutex);
+        if (fontData->fCachedFont) {
+            font = fontData->fCachedFont;
+        } else {
+            font = sk_make_sp<SkTestFont>(*fontData);
+            fontData->fCachedFont = font;
+        }
+    }
+    return sk_make_sp<SkTestTypeface>(std::move(font), style);
+}
+
+sk_sp<SkTypeface> emoji_typeface() {
+#if defined(SK_BUILD_FOR_WIN)
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
+    const char *colorEmojiFontName = "Segoe UI Emoji";
+    sk_sp<SkTypeface> typeface(fm->matchFamilyStyle(colorEmojiFontName, SkFontStyle()));
+    if (typeface) {
+        return typeface;
+    }
+    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() {
+#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() {
+    for (int index = 0; index < FLAGS_key.count(); index += 2) {
+        if (!strcmp("os", FLAGS_key[index])) {
+            return FLAGS_key[index + 1];
+        }
+    }
+    return "";
+}
+
+static bool extra_config_contains(const char* substring) {
+    for (int index = 0; index < FLAGS_key.count(); index += 2) {
+        if (0 == strcmp("extra_config", FLAGS_key[index])
+                && strstr(FLAGS_key[index + 1], substring)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+const char* platform_font_manager() {
+    if (extra_config_contains("GDI")) {
+        return "GDI";
+    }
+    if (extra_config_contains("NativeFonts")){
+        return platform_os_name();
+    }
+    return "";
+}
+
+sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style) {
+    return create_font(name, style);
+}
+
+void set_portable_typeface(SkPaint* paint, const char* name, SkFontStyle style) {
+    paint->setTypeface(create_font(name, style));
+}
+
+}
diff --git a/tools/test_font_index.inc b/tools/fonts/test_font_index.inc
similarity index 100%
rename from tools/test_font_index.inc
rename to tools/fonts/test_font_index.inc
diff --git a/tools/test_font_monospace.inc b/tools/fonts/test_font_monospace.inc
similarity index 100%
rename from tools/test_font_monospace.inc
rename to tools/fonts/test_font_monospace.inc
diff --git a/tools/test_font_sans_serif.inc b/tools/fonts/test_font_sans_serif.inc
similarity index 100%
rename from tools/test_font_sans_serif.inc
rename to tools/fonts/test_font_sans_serif.inc
diff --git a/tools/test_font_serif.inc b/tools/fonts/test_font_serif.inc
similarity index 100%
rename from tools/test_font_serif.inc
rename to tools/fonts/test_font_serif.inc
diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp
index f067207..2eb8dba 100644
--- a/tools/sk_tool_utils.cpp
+++ b/tools/sk_tool_utils.cpp
@@ -10,9 +10,6 @@
 #include "Resources.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
-#include "SkCommonFlags.h"
-#include "SkFontMgr.h"
-#include "SkFontStyle.h"
 #include "SkImage.h"
 #include "SkPixelRef.h"
 #include "SkPM4f.h"
@@ -24,75 +21,6 @@
 
 namespace sk_tool_utils {
 
-static const char* platform_os_name() {
-    for (int index = 0; index < FLAGS_key.count(); index += 2) {
-        if (!strcmp("os", FLAGS_key[index])) {
-            return FLAGS_key[index + 1];
-        }
-    }
-    return "";
-}
-
-sk_sp<SkTypeface> emoji_typeface() {
-#if defined(SK_BUILD_FOR_WIN)
-    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
-    const char *colorEmojiFontName = "Segoe UI Emoji";
-    sk_sp<SkTypeface> typeface(fm->matchFamilyStyle(colorEmojiFontName, SkFontStyle()));
-    if (typeface) {
-        return typeface;
-    }
-    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() {
-#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 bool extra_config_contains(const char* substring) {
-    for (int index = 0; index < FLAGS_key.count(); index += 2) {
-        if (0 == strcmp("extra_config", FLAGS_key[index])
-                && strstr(FLAGS_key[index + 1], substring)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-const char* platform_font_manager() {
-    if (extra_config_contains("GDI")) {
-        return "GDI";
-    }
-    if (extra_config_contains("NativeFonts")){
-        return platform_os_name();
-    }
-    return "";
-}
-
-
 const char* alphatype_name(SkAlphaType at) {
     switch (at) {
         case kUnknown_SkAlphaType:  return "Unknown";
@@ -128,14 +56,6 @@
     return SkPixel16ToColor(color16);
 }
 
-sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style) {
-    return create_font(name, style);
-}
-
-void set_portable_typeface(SkPaint* paint, const char* name, SkFontStyle style) {
-    paint->setTypeface(create_font(name, style));
-}
-
 void write_pixels(SkCanvas* canvas, const SkBitmap& bitmap, int x, int y,
                   SkColorType colorType, SkAlphaType alphaType) {
     SkBitmap tmp(bitmap);
diff --git a/tools/sk_tool_utils_font.cpp b/tools/sk_tool_utils_font.cpp
deleted file mode 100644
index 8b2041a..0000000
--- a/tools/sk_tool_utils_font.cpp
+++ /dev/null
@@ -1,70 +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 "SkFontMgr.h"
-#include "SkMutex.h"
-#include "SkOSFile.h"
-#include "SkTestScalerContext.h"
-#include "SkUtils.h"
-#include "sk_tool_utils.h"
-
-namespace sk_tool_utils {
-
-#include "test_font_monospace.inc"
-#include "test_font_sans_serif.inc"
-#include "test_font_serif.inc"
-#include "test_font_index.inc"
-
-void release_portable_typefaces() {
-    for (int index = 0; index < gTestFontsCount; ++index) {
-        SkTestFontData& fontData = gTestFonts[index];
-        fontData.fCachedFont.reset();
-    }
-}
-
-SK_DECLARE_STATIC_MUTEX(gTestFontMutex);
-
-sk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) {
-    SkTestFontData* fontData = nullptr;
-    const SubFont* sub;
-    if (name) {
-        for (int index = 0; index < gSubFontsCount; ++index) {
-            sub = &gSubFonts[index];
-            if (!strcmp(name, sub->fName) && sub->fStyle == style) {
-                fontData = &sub->fFont;
-                break;
-            }
-        }
-        if (!fontData) {
-            // Once all legacy callers to portable fonts are converted, replace this with
-            // SK_ABORT();
-            SkDebugf("missing %s weight %d, width %d, slant %d\n",
-                     name, style.weight(), style.width(), style.slant());
-            // If we called SkTypeface::CreateFromName() here we'd recurse infinitely,
-            // so we reimplement its core logic here inline without the recursive aspect.
-            sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
-            return fm->legacyMakeTypeface(name, style);
-        }
-    } else {
-        sub = &gSubFonts[gDefaultFontIndex];
-        fontData = &sub->fFont;
-    }
-    sk_sp<SkTestFont> font;
-    {
-        SkAutoMutexAcquire ac(gTestFontMutex);
-        if (fontData->fCachedFont) {
-            font = fontData->fCachedFont;
-        } else {
-            font = sk_make_sp<SkTestFont>(*fontData);
-            fontData->fCachedFont = font;
-        }
-    }
-    return sk_make_sp<SkTestTypeface>(std::move(font), style);
-}
-
-}
diff --git a/tools/skqp/gm_runner.cpp b/tools/skqp/gm_runner.cpp
index 942c577..778c2bc 100644
--- a/tools/skqp/gm_runner.cpp
+++ b/tools/skqp/gm_runner.cpp
@@ -9,7 +9,7 @@
 
 #include <algorithm>
 
-#include "../dm/DMFontMgr.h"
+#include "../tools/fonts/SkTestFontMgr.h"
 #include "GrContext.h"
 #include "GrContextOptions.h"
 #include "SkFontMgrPriv.h"
@@ -243,7 +243,7 @@
 
 void InitSkia(Mode mode, skqp::AssetManager* mgr) {
     SkGraphics::Init();
-    gSkFontMgr_DefaultFactory = &DM::MakeFontMgr;
+    gSkFontMgr_DefaultFactory = &sk_tool_utils::MakePortableFontMgr;
 
     gMode = mode;
     readlist(mgr, "skqp/DoNotScoreInCompatibilityTestMode.txt",
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 6582490..8aff1ce 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -20,9 +20,11 @@
 #include "SkCanvas.h"
 #include "SkColorSpacePriv.h"
 #include "SkColorSpaceXformCanvas.h"
+#include "SkCommonFlags.h"
 #include "SkCommandLineFlags.h"
 #include "SkCommonFlagsGpu.h"
 #include "SkEventTracingPriv.h"
+#include "SkFontMgrPriv.h"
 #include "SkGraphics.h"
 #include "SkImagePriv.h"
 #include "SkOSFile.h"
@@ -33,6 +35,7 @@
 #include "SkStream.h"
 #include "SkSurface.h"
 #include "SkTaskGroup.h"
+#include "SkTestFontMgr.h"
 #include "SkThreadedBMPDevice.h"
 
 #include "imgui.h"
@@ -50,16 +53,6 @@
     return new Viewer(argc, argv, platformData);
 }
 
-static DEFINE_string2(match, m, nullptr,
-               "[~][^]substring[$] [...] of bench name to run.\n"
-               "Multiple matches may be separated by spaces.\n"
-               "~ causes a matching bench to always be skipped\n"
-               "^ requires the start of the bench to match\n"
-               "$ requires the end of the bench to match\n"
-               "^ and $ requires an exact match\n"
-               "If a bench does not match any list entry,\n"
-               "it is skipped unless some list entry starts with ~");
-
 static DEFINE_string(slide, "", "Start on this sample.");
 static DEFINE_bool(list, false, "List samples?");
 
@@ -69,16 +62,6 @@
 #    define BACKENDS_STR "\"sw\" and \"gl\""
 #endif
 
-#ifdef SK_BUILD_FOR_ANDROID
-static DEFINE_string(skps, "/data/local/tmp/skps", "Directory to read skps from.");
-static DEFINE_string(jpgs, "/data/local/tmp/resources", "Directory to read jpgs from.");
-static DEFINE_string(jsons, "/data/local/tmp/jsons", "Directory to read (Bodymovin) jsons from.");
-#else
-static DEFINE_string(skps, "skps", "Directory to read skps from.");
-static DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from.");
-static DEFINE_string(jsons, "jsons", "Directory to read (Bodymovin) jsons from.");
-#endif
-
 static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BACKENDS_STR ".");
 
 static DEFINE_int32(msaa, 1, "Number of subpixel samples. 0 for no HW antialiasing.");
@@ -219,6 +202,10 @@
     SetResourcePath("/data/local/tmp/resources");
 #endif
 
+    if (!FLAGS_nativeFonts) {
+        gSkFontMgr_DefaultFactory = &sk_tool_utils::MakePortableFontMgr;
+    }
+
     initializeEventTracingForTools();
     static SkTaskGroup::Enabler kTaskGroupEnabler(FLAGS_threads);