Split custom font managers.

Some users would like to use the empty font manager, but the directory
gont manager brings in extra dependencies to work which would otherwise
be unneeded. Allow these users to build just the bits of code they
actually need.

Change-Id: Ib029ef2682883509bad5a2aa39f1ef55631f4d8a
Reviewed-on: https://skia-review.googlesource.com/8200
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index e389cd2..d0f415d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -344,7 +344,11 @@
   ]
   sources = [
     "src/ports/SkFontMgr_custom.cpp",
+    "src/ports/SkFontMgr_custom.h",
+    "src/ports/SkFontMgr_custom_directory.cpp",
     "src/ports/SkFontMgr_custom_directory_factory.cpp",
+    "src/ports/SkFontMgr_custom_embedded.cpp",
+    "src/ports/SkFontMgr_custom_empty.cpp",
   ]
 }
 
@@ -373,6 +377,7 @@
   ]
   sources = [
     "src/ports/SkFontMgr_custom.cpp",
+    "src/ports/SkFontMgr_custom_empty.cpp",
     "src/ports/SkFontMgr_custom_empty_factory.cpp",
   ]
 }
diff --git a/include/ports/SkFontMgr_custom.h b/include/ports/SkFontMgr_custom.h
deleted file mode 100644
index d918763..0000000
--- a/include/ports/SkFontMgr_custom.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkFontMgr_custom_DEFINED
-#define SkFontMgr_custom_DEFINED
-
-#include "SkTypes.h"
-
-class SkFontMgr;
-
-/** Create a custom font manager which scans a given directory for font files. */
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir);
-
-/** Create a custom font manager that contains no built-in fonts. */
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty();
-
-#endif // SkFontMgr_custom_DEFINED
diff --git a/include/ports/SkFontMgr_directory.h b/include/ports/SkFontMgr_directory.h
new file mode 100644
index 0000000..8f79a7f
--- /dev/null
+++ b/include/ports/SkFontMgr_directory.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_directory_DEFINED
+#define SkFontMgr_directory_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTypes.h"
+
+class SkFontMgr;
+
+/** Create a custom font manager which scans a given directory for font files.
+ *  This font manager uses FreeType for rendering.
+ */
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir);
+
+#endif // SkFontMgr_directory_DEFINED
diff --git a/include/ports/SkFontMgr_empty.h b/include/ports/SkFontMgr_empty.h
new file mode 100644
index 0000000..dbeef58
--- /dev/null
+++ b/include/ports/SkFontMgr_empty.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_empty_DEFINED
+#define SkFontMgr_empty_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTypes.h"
+
+class SkFontMgr;
+
+/** Create a custom font manager that contains no built-in fonts.
+ *  This font manager uses FreeType for rendering.
+ */
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty();
+
+#endif // SkFontMgr_empty_DEFINED
diff --git a/public.bzl b/public.bzl
index a808bb1..15709bf 100644
--- a/public.bzl
+++ b/public.bzl
@@ -280,6 +280,9 @@
         "src/ports/*nacl*",
         "src/ports/*win*",
         "src/ports/SkFontMgr_custom.cpp",
+        "src/ports/SkFontMgr_custom_directory.cpp",
+        "src/ports/SkFontMgr_custom_embedded.cpp",
+        "src/ports/SkFontMgr_custom_empty.cpp",
         "src/ports/SkFontMgr_custom_directory_factory.cpp",
         "src/ports/SkFontMgr_custom_embedded_factory.cpp",
         "src/ports/SkFontMgr_custom_empty_factory.cpp",
diff --git a/src/ports/SkFontMgr_custom.cpp b/src/ports/SkFontMgr_custom.cpp
index 1b6baa1..4e4887d 100644
--- a/src/ports/SkFontMgr_custom.cpp
+++ b/src/ports/SkFontMgr_custom.cpp
@@ -11,15 +11,12 @@
 #include "SkFontMgr_custom.h"
 #include "SkFontStyle.h"
 #include "SkMakeUnique.h"
-#include "SkOSFile.h"
-#include "SkOSPath.h"
 #include "SkRefCnt.h"
 #include "SkStream.h"
 #include "SkString.h"
 #include "SkTArray.h"
 #include "SkTemplates.h"
 #include "SkTypeface.h"
-#include "SkTypefaceCache.h"
 #include "SkTypes.h"
 
 #include <limits>
@@ -27,497 +24,235 @@
 
 class SkData;
 
-/** The base SkTypeface implementation for the custom font manager. */
-class SkTypeface_Custom : public SkTypeface_FreeType {
-public:
-    SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
-                      bool sysFont, const SkString familyName, int index)
-        : INHERITED(style, isFixedPitch)
-        , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
-    { }
+SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
+                                     bool sysFont, const SkString familyName, int index)
+    : INHERITED(style, isFixedPitch)
+    , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
+{ }
 
-    bool isSysFont() const { return fIsSysFont; }
+bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
 
-protected:
-    void onGetFamilyName(SkString* familyName) const override {
-        *familyName = fFamilyName;
-    }
+void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
+    *familyName = fFamilyName;
+}
 
-    void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override {
-        desc->setFamilyName(fFamilyName.c_str());
-        desc->setStyle(this->fontStyle());
-        *isLocal = !this->isSysFont();
-    }
+void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+    desc->setFamilyName(fFamilyName.c_str());
+    desc->setStyle(this->fontStyle());
+    *isLocal = !this->isSysFont();
+}
 
-    int getIndex() const { return fIndex; }
+int SkTypeface_Custom::getIndex() const { return fIndex; }
 
-private:
-    const bool fIsSysFont;
-    const SkString fFamilyName;
-    const int fIndex;
 
-    typedef SkTypeface_FreeType INHERITED;
-};
+SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
 
-/** The empty SkTypeface implementation for the custom font manager.
- *  Used as the last resort fallback typeface.
- */
-class SkTypeface_Empty : public SkTypeface_Custom {
-public:
-    SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
+SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
 
-protected:
-    SkStreamAsset* onOpenStream(int*) const override { return nullptr; }
 
-private:
-    typedef SkTypeface_Custom INHERITED;
-};
+SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
+                                     const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                                     const SkString familyName)
+    : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
+    , fData(std::move(fontData))
+{ }
 
-/** The stream SkTypeface implementation for the custom font manager. */
-class SkTypeface_Stream : public SkTypeface_Custom {
-public:
-    SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
-                      const SkFontStyle& style, bool isFixedPitch, bool sysFont,
-                      const SkString familyName)
-        : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
-        , fData(std::move(fontData))
-    { }
+SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
+    *ttcIndex = fData->getIndex();
+    return fData->getStream()->duplicate();
+}
 
-protected:
-    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
-        *ttcIndex = fData->getIndex();
-        return fData->getStream()->duplicate();
-    }
+std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
+    return skstd::make_unique<SkFontData>(*fData);
+}
 
-    std::unique_ptr<SkFontData> onMakeFontData() const override {
-        return skstd::make_unique<SkFontData>(*fData);
-    }
 
-private:
-    const std::unique_ptr<const SkFontData> fData;
+SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                                 const SkString familyName, const char path[], int index)
+    : INHERITED(style, isFixedPitch, sysFont, familyName, index)
+    , fPath(path)
+{ }
 
-    typedef SkTypeface_Custom INHERITED;
-};
-
-/** The file SkTypeface implementation for the custom font manager. */
-class SkTypeface_File : public SkTypeface_Custom {
-public:
-    SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
-                    const SkString familyName, const char path[], int index)
-        : INHERITED(style, isFixedPitch, sysFont, familyName, index)
-        , fPath(path)
-    { }
-
-protected:
-    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
-        *ttcIndex = this->getIndex();
-        return SkStream::MakeFromFile(fPath.c_str()).release();
-    }
-
-private:
-    SkString fPath;
-
-    typedef SkTypeface_Custom INHERITED;
-};
+SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
+    *ttcIndex = this->getIndex();
+    return SkStream::MakeFromFile(fPath.c_str()).release();
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
-/**
- *  SkFontStyleSet_Custom
- *
- *  This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families.
- */
-class SkFontStyleSet_Custom : public SkFontStyleSet {
-public:
-    explicit SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) { }
+SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
 
-    /** Should only be called during the inital build phase. */
-    void appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
-        fStyles.emplace_back(std::move(typeface));
+void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
+    fStyles.emplace_back(std::move(typeface));
+}
+
+int SkFontStyleSet_Custom::count() {
+    return fStyles.count();
+}
+
+void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
+    SkASSERT(index < fStyles.count());
+    if (style) {
+        *style = fStyles[index]->fontStyle();
     }
-
-    int count() override {
-        return fStyles.count();
+    if (name) {
+        name->reset();
     }
+}
 
-    void getStyle(int index, SkFontStyle* style, SkString* name) override {
-        SkASSERT(index < fStyles.count());
-        if (style) {
-            *style = fStyles[index]->fontStyle();
-        }
-        if (name) {
-            name->reset();
-        }
-    }
+SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
+    SkASSERT(index < fStyles.count());
+    return SkRef(fStyles[index].get());
+}
 
-    SkTypeface* createTypeface(int index) override {
-        SkASSERT(index < fStyles.count());
-        return SkRef(fStyles[index].get());
-    }
+SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
+    return this->matchStyleCSS3(pattern);
+}
 
-    SkTypeface* matchStyle(const SkFontStyle& pattern) override {
-        return this->matchStyleCSS3(pattern);
-    }
+SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
 
-    SkString getFamilyName() { return fFamilyName; }
 
-private:
-    SkTArray<sk_sp<SkTypeface_Custom>> fStyles;
-    SkString fFamilyName;
+SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
+    loader.loadSystemFonts(fScanner, &fFamilies);
 
-    friend class SkFontMgr_Custom;
-};
-
-/**
- *  SkFontMgr_Custom
- *
- *  This class is essentially a collection of SkFontStyleSet_Custom,
- *  one SkFontStyleSet_Custom for each family. This class may be modified
- *  to load fonts from any source by changing the initialization.
- */
-class SkFontMgr_Custom : public SkFontMgr {
-public:
-    typedef SkTArray<sk_sp<SkFontStyleSet_Custom>> Families;
-    class SystemFontLoader {
-    public:
-        virtual ~SystemFontLoader() { }
-        virtual void loadSystemFonts(const SkTypeface_FreeType::Scanner&, Families*) const = 0;
+    // Try to pick a default font.
+    static const char* defaultNames[] = {
+        "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
     };
-    explicit SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
-        loader.loadSystemFonts(fScanner, &fFamilies);
-
-        // Try to pick a default font.
-        static const char* defaultNames[] = {
-            "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
-        };
-        for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
-            sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
-            if (nullptr == set) {
-                continue;
-            }
-
-            sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
-                                                             SkFontStyle::kNormal_Width,
-                                                             SkFontStyle::kUpright_Slant)));
-            if (nullptr == tf) {
-                continue;
-            }
-
-            fDefaultFamily = set.get();
-            break;
-        }
-        if (nullptr == fDefaultFamily) {
-            fDefaultFamily = fFamilies[0].get();
-        }
-    }
-
-protected:
-    int onCountFamilies() const override {
-        return fFamilies.count();
-    }
-
-    void onGetFamilyName(int index, SkString* familyName) const override {
-        SkASSERT(index < fFamilies.count());
-        familyName->set(fFamilies[index]->getFamilyName());
-    }
-
-    SkFontStyleSet_Custom* onCreateStyleSet(int index) const override {
-        SkASSERT(index < fFamilies.count());
-        return SkRef(fFamilies[index].get());
-    }
-
-    SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override {
-        for (int i = 0; i < fFamilies.count(); ++i) {
-            if (fFamilies[i]->getFamilyName().equals(familyName)) {
-                return SkRef(fFamilies[i].get());
-            }
-        }
-        return nullptr;
-    }
-
-    SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                   const SkFontStyle& fontStyle) const override
-    {
-        sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
-        return sset->matchStyle(fontStyle);
-    }
-
-    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
-                                            const char* bcp47[], int bcp47Count,
-                                            SkUnichar character) const override
-    {
-        return nullptr;
-    }
-
-    SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                 const SkFontStyle& fontStyle) const override
-    {
-        for (int i = 0; i < fFamilies.count(); ++i) {
-            for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
-                if (fFamilies[i]->fStyles[j].get() == familyMember) {
-                    return fFamilies[i]->matchStyle(fontStyle);
-                }
-            }
-        }
-        return nullptr;
-    }
-
-    SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override {
-        return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
-    }
-
-    SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override {
-        return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
-    }
-
-    SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override {
-        using Scanner = SkTypeface_FreeType::Scanner;
-        std::unique_ptr<SkStreamAsset> stream(s);
-        bool isFixedPitch;
-        SkFontStyle style;
-        SkString name;
-        Scanner::AxisDefinitions axisDefinitions;
-        if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(),
-                               &name, &style, &isFixedPitch, &axisDefinitions))
-        {
-            return nullptr;
+    for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
+        sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
+        if (nullptr == set) {
+            continue;
         }
 
-        int paramAxisCount;
-        const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
-        SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
-        Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
-
-        auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(),
-                                                   axisValues.get(), axisDefinitions.count());
-        return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
-    }
-
-    SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> data) const override {
-        bool isFixedPitch;
-        SkFontStyle style;
-        SkString name;
-        if (!fScanner.scanFont(data->getStream(), data->getIndex(),
-                               &name, &style, &isFixedPitch, nullptr))
-        {
-            return nullptr;
-        }
-        return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
-    }
-
-    SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
-        std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
-        return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
-    }
-
-    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
-        SkTypeface* tf = nullptr;
-
-        if (familyName) {
-            tf = this->onMatchFamilyStyle(familyName, style);
-        }
-
+        sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
+                                                         SkFontStyle::kNormal_Width,
+                                                         SkFontStyle::kUpright_Slant)));
         if (nullptr == tf) {
-            tf = fDefaultFamily->matchStyle(style);
+            continue;
         }
 
-        return tf;
+        fDefaultFamily = set.get();
+        break;
     }
+    if (nullptr == fDefaultFamily) {
+        fDefaultFamily = fFamilies[0].get();
+    }
+}
 
-private:
-    Families fFamilies;
-    SkFontStyleSet_Custom* fDefaultFamily;
-    SkTypeface_FreeType::Scanner fScanner;
-};
+int SkFontMgr_Custom::onCountFamilies() const {
+    return fFamilies.count();
+}
 
-///////////////////////////////////////////////////////////////////////////////
+void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
+    SkASSERT(index < fFamilies.count());
+    familyName->set(fFamilies[index]->getFamilyName());
+}
 
-class DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
-    DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { }
+SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
+    SkASSERT(index < fFamilies.count());
+    return SkRef(fFamilies[index].get());
+}
 
-    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
-                         SkFontMgr_Custom::Families* families) const override
-    {
-        load_directory_fonts(scanner, fBaseDirectory, ".ttf", families);
-        load_directory_fonts(scanner, fBaseDirectory, ".ttc", families);
-        load_directory_fonts(scanner, fBaseDirectory, ".otf", families);
-        load_directory_fonts(scanner, fBaseDirectory, ".pfb", families);
-
-        if (families->empty()) {
-            SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
-            families->push_back().reset(family);
-            family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
+    for (int i = 0; i < fFamilies.count(); ++i) {
+        if (fFamilies[i]->getFamilyName().equals(familyName)) {
+            return SkRef(fFamilies[i].get());
         }
     }
+    return nullptr;
+}
 
-private:
-    static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
-                                              const char familyName[])
-    {
-       for (int i = 0; i < families.count(); ++i) {
-            if (families[i]->getFamilyName().equals(familyName)) {
-                return families[i].get();
+SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
+                                const SkFontStyle& fontStyle) const
+{
+    sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
+    return sset->matchStyle(fontStyle);
+}
+
+SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
+                                                          const SkFontStyle&,
+                                                          const char* bcp47[], int bcp47Count,
+                                                          SkUnichar character) const
+{
+    return nullptr;
+}
+
+SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
+                                               const SkFontStyle& fontStyle) const
+{
+    for (int i = 0; i < fFamilies.count(); ++i) {
+        for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
+            if (fFamilies[i]->fStyles[j].get() == familyMember) {
+                return fFamilies[i]->matchStyle(fontStyle);
             }
         }
+    }
+    return nullptr;
+}
+
+SkTypeface* SkFontMgr_Custom::onCreateFromData(SkData* data, int ttcIndex) const {
+    return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
+}
+
+SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const {
+    return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
+}
+
+SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s,
+                                                 const FontParameters& params) const
+{
+    using Scanner = SkTypeface_FreeType::Scanner;
+    std::unique_ptr<SkStreamAsset> stream(s);
+    bool isFixedPitch;
+    SkFontStyle style;
+    SkString name;
+    Scanner::AxisDefinitions axisDefinitions;
+    if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(),
+                            &name, &style, &isFixedPitch, &axisDefinitions))
+    {
         return nullptr;
     }
 
-    static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner,
-                                     const SkString& directory, const char* suffix,
-                                     SkFontMgr_Custom::Families* families)
-    {
-        SkOSFile::Iter iter(directory.c_str(), suffix);
-        SkString name;
+    int paramAxisCount;
+    const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
+    SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
+    Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
 
-        while (iter.next(&name, false)) {
-            SkString filename(SkOSPath::Join(directory.c_str(), name.c_str()));
-            std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(filename.c_str());
-            if (!stream) {
-                SkDebugf("---- failed to open <%s>\n", filename.c_str());
-                continue;
-            }
-
-            int numFaces;
-            if (!scanner.recognizedFont(stream.get(), &numFaces)) {
-                SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
-                continue;
-            }
-
-            for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
-                bool isFixedPitch;
-                SkString realname;
-                SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
-                if (!scanner.scanFont(stream.get(), faceIndex,
-                                      &realname, &style, &isFixedPitch, nullptr))
-                {
-                    SkDebugf("---- failed to open <%s> <%d> as a font\n",
-                             filename.c_str(), faceIndex);
-                    continue;
-                }
-
-                SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
-                if (nullptr == addTo) {
-                    addTo = new SkFontStyleSet_Custom(realname);
-                    families->push_back().reset(addTo);
-                }
-                addTo->appendTypeface(sk_make_sp<SkTypeface_File>(style, isFixedPitch, true,
-                                                                  realname, filename.c_str(),
-                                                                  faceIndex));
-            }
-        }
-
-        SkOSFile::Iter dirIter(directory.c_str());
-        while (dirIter.next(&name, true)) {
-            if (name.startsWith(".")) {
-                continue;
-            }
-            SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str()));
-            load_directory_fonts(scanner, dirname, suffix, families);
-        }
-    }
-
-    SkString fBaseDirectory;
-};
-
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir) {
-    return sk_make_sp<SkFontMgr_Custom>(DirectorySystemFontLoader(dir));
+    auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(),
+                                                axisValues.get(), axisDefinitions.count());
+    return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-struct SkEmbeddedResource { const uint8_t* data; size_t size; };
-struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
-
-class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
-    EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(header) { }
-
-    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
-                         SkFontMgr_Custom::Families* families) const override
+SkTypeface* SkFontMgr_Custom::onCreateFromFontData(std::unique_ptr<SkFontData> data) const {
+    bool isFixedPitch;
+    SkFontStyle style;
+    SkString name;
+    if (!fScanner.scanFont(data->getStream(), data->getIndex(),
+                            &name, &style, &isFixedPitch, nullptr))
     {
-        for (int i = 0; i < fHeader->count; ++i) {
-            const SkEmbeddedResource& fontEntry = fHeader->entries[i];
-            load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, families);
-        }
-
-        if (families->empty()) {
-            SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
-            families->push_back().reset(family);
-            family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
-        }
-    }
-
-private:
-    static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
-                                              const char familyName[])
-    {
-       for (int i = 0; i < families.count(); ++i) {
-            if (families[i]->getFamilyName().equals(familyName)) {
-                return families[i].get();
-            }
-        }
         return nullptr;
     }
-
-    static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner,
-                                   const uint8_t* data, size_t size, int index,
-                                   SkFontMgr_Custom::Families* families)
-    {
-        auto stream = skstd::make_unique<SkMemoryStream>(data, size, false);
-
-        int numFaces;
-        if (!scanner.recognizedFont(stream.get(), &numFaces)) {
-            SkDebugf("---- failed to open <%d> as a font\n", index);
-            return;
-        }
-
-        for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
-            bool isFixedPitch;
-            SkString realname;
-            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
-            if (!scanner.scanFont(stream.get(), faceIndex,
-                                  &realname, &style, &isFixedPitch, nullptr))
-            {
-                SkDebugf("---- failed to open <%d> <%d> as a font\n", index, faceIndex);
-                return;
-            }
-
-            SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
-            if (nullptr == addTo) {
-                addTo = new SkFontStyleSet_Custom(realname);
-                families->push_back().reset(addTo);
-            }
-            auto data = skstd::make_unique<SkFontData>(std::move(stream), faceIndex, nullptr, 0);
-            addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
-                                                                style, isFixedPitch,
-                                                                true, realname));
-        }
-    }
-
-    const SkEmbeddedResourceHeader* fHeader;
-};
-
-sk_sp<SkFontMgr> SkFontMgr_New_Custom_Embedded(const SkEmbeddedResourceHeader* header) {
-    return sk_make_sp<SkFontMgr_Custom>(EmbeddedSystemFontLoader(header));
+    return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
 }
 
-///////////////////////////////////////////////////////////////////////////////
+SkTypeface* SkFontMgr_Custom::onCreateFromFile(const char path[], int ttcIndex) const {
+    std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
+    return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
+}
 
-class EmptyFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
-    EmptyFontLoader() { }
+SkTypeface* SkFontMgr_Custom::onLegacyCreateTypeface(const char familyName[],
+                                                     SkFontStyle style) const
+{
+    SkTypeface* tf = nullptr;
 
-    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
-                         SkFontMgr_Custom::Families* families) const override
-    {
-        SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
-        families->push_back().reset(family);
-        family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+    if (familyName) {
+        tf = this->onMatchFamilyStyle(familyName, style);
     }
 
-};
+    if (nullptr == tf) {
+        tf = fDefaultFamily->matchStyle(style);
+    }
 
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty() {
-    return sk_make_sp<SkFontMgr_Custom>(EmptyFontLoader());
+    return tf;
 }
diff --git a/src/ports/SkFontMgr_custom.h b/src/ports/SkFontMgr_custom.h
new file mode 100644
index 0000000..9149378
--- /dev/null
+++ b/src/ports/SkFontMgr_custom.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_custom_DEFINED
+#define SkFontMgr_custom_DEFINED
+
+#include "SkFontHost_FreeType_common.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+#include "SkTArray.h"
+#include "SkTypes.h"
+
+class SkData;
+class SkFontDescriptor;
+class SkStreamAsset;
+class SkTypeface;
+
+/** The base SkTypeface implementation for the custom font manager. */
+class SkTypeface_Custom : public SkTypeface_FreeType {
+public:
+    SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
+                      bool sysFont, const SkString familyName, int index);
+    bool isSysFont() const;
+
+protected:
+    void onGetFamilyName(SkString* familyName) const override;
+    void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
+    int getIndex() const;
+
+private:
+    const bool fIsSysFont;
+    const SkString fFamilyName;
+    const int fIndex;
+
+    typedef SkTypeface_FreeType INHERITED;
+};
+
+/** The empty SkTypeface implementation for the custom font manager.
+ *  Used as the last resort fallback typeface.
+ */
+class SkTypeface_Empty : public SkTypeface_Custom {
+public:
+    SkTypeface_Empty() ;
+
+protected:
+    SkStreamAsset* onOpenStream(int*) const override;
+
+private:
+    typedef SkTypeface_Custom INHERITED;
+};
+
+/** The stream SkTypeface implementation for the custom font manager. */
+class SkTypeface_Stream : public SkTypeface_Custom {
+public:
+    SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
+                      const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                      const SkString familyName);
+
+protected:
+    SkStreamAsset* onOpenStream(int* ttcIndex) const override;
+    std::unique_ptr<SkFontData> onMakeFontData() const override;
+
+private:
+    const std::unique_ptr<const SkFontData> fData;
+
+    typedef SkTypeface_Custom INHERITED;
+};
+
+/** The file SkTypeface implementation for the custom font manager. */
+class SkTypeface_File : public SkTypeface_Custom {
+public:
+    SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                    const SkString familyName, const char path[], int index);
+
+protected:
+    SkStreamAsset* onOpenStream(int* ttcIndex) const override;
+
+private:
+    SkString fPath;
+
+    typedef SkTypeface_Custom INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  SkFontStyleSet_Custom
+ *
+ *  This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families.
+ */
+class SkFontStyleSet_Custom : public SkFontStyleSet {
+public:
+    explicit SkFontStyleSet_Custom(const SkString familyName);
+
+    /** Should only be called during the inital build phase. */
+    void appendTypeface(sk_sp<SkTypeface_Custom> typeface);
+    int count() override;
+    void getStyle(int index, SkFontStyle* style, SkString* name) override;
+    SkTypeface* createTypeface(int index) override;
+    SkTypeface* matchStyle(const SkFontStyle& pattern) override;
+    SkString getFamilyName();
+
+private:
+    SkTArray<sk_sp<SkTypeface_Custom>> fStyles;
+    SkString fFamilyName;
+
+    friend class SkFontMgr_Custom;
+};
+
+/**
+ *  SkFontMgr_Custom
+ *
+ *  This class is essentially a collection of SkFontStyleSet_Custom,
+ *  one SkFontStyleSet_Custom for each family. This class may be modified
+ *  to load fonts from any source by changing the initialization.
+ */
+class SkFontMgr_Custom : public SkFontMgr {
+public:
+    typedef SkTArray<sk_sp<SkFontStyleSet_Custom>> Families;
+    class SystemFontLoader {
+    public:
+        virtual ~SystemFontLoader() { }
+        virtual void loadSystemFonts(const SkTypeface_FreeType::Scanner&, Families*) const = 0;
+    };
+    explicit SkFontMgr_Custom(const SystemFontLoader& loader);
+
+protected:
+    int onCountFamilies() const override;
+    void onGetFamilyName(int index, SkString* familyName) const override;
+    SkFontStyleSet_Custom* onCreateStyleSet(int index) const override;
+    SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override;
+    SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                   const SkFontStyle& fontStyle) const override;
+    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+                                            const char* bcp47[], int bcp47Count,
+                                            SkUnichar character) const override;
+    SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+                                 const SkFontStyle& fontStyle) const override;
+    SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override;
+    SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override;
+    SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override;
+    SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> data) const override;
+    SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override;
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override;
+
+private:
+    Families fFamilies;
+    SkFontStyleSet_Custom* fDefaultFamily;
+    SkTypeface_FreeType::Scanner fScanner;
+};
+
+#endif
diff --git a/src/ports/SkFontMgr_custom_directory.cpp b/src/ports/SkFontMgr_custom_directory.cpp
new file mode 100644
index 0000000..af32287
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_directory.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontMgr_custom.h"
+#include "SkFontMgr_directory.h"
+#include "SkOSFile.h"
+#include "SkOSPath.h"
+#include "SkStream.h"
+
+class DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+    DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { }
+
+    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+                         SkFontMgr_Custom::Families* families) const override
+    {
+        load_directory_fonts(scanner, fBaseDirectory, ".ttf", families);
+        load_directory_fonts(scanner, fBaseDirectory, ".ttc", families);
+        load_directory_fonts(scanner, fBaseDirectory, ".otf", families);
+        load_directory_fonts(scanner, fBaseDirectory, ".pfb", families);
+
+        if (families->empty()) {
+            SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+            families->push_back().reset(family);
+            family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+        }
+    }
+
+private:
+    static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
+                                              const char familyName[])
+    {
+       for (int i = 0; i < families.count(); ++i) {
+            if (families[i]->getFamilyName().equals(familyName)) {
+                return families[i].get();
+            }
+        }
+        return nullptr;
+    }
+
+    static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner,
+                                     const SkString& directory, const char* suffix,
+                                     SkFontMgr_Custom::Families* families)
+    {
+        SkOSFile::Iter iter(directory.c_str(), suffix);
+        SkString name;
+
+        while (iter.next(&name, false)) {
+            SkString filename(SkOSPath::Join(directory.c_str(), name.c_str()));
+            std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(filename.c_str());
+            if (!stream) {
+                SkDebugf("---- failed to open <%s>\n", filename.c_str());
+                continue;
+            }
+
+            int numFaces;
+            if (!scanner.recognizedFont(stream.get(), &numFaces)) {
+                SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
+                continue;
+            }
+
+            for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
+                bool isFixedPitch;
+                SkString realname;
+                SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
+                if (!scanner.scanFont(stream.get(), faceIndex,
+                                      &realname, &style, &isFixedPitch, nullptr))
+                {
+                    SkDebugf("---- failed to open <%s> <%d> as a font\n",
+                             filename.c_str(), faceIndex);
+                    continue;
+                }
+
+                SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
+                if (nullptr == addTo) {
+                    addTo = new SkFontStyleSet_Custom(realname);
+                    families->push_back().reset(addTo);
+                }
+                addTo->appendTypeface(sk_make_sp<SkTypeface_File>(style, isFixedPitch, true,
+                                                                  realname, filename.c_str(),
+                                                                  faceIndex));
+            }
+        }
+
+        SkOSFile::Iter dirIter(directory.c_str());
+        while (dirIter.next(&name, true)) {
+            if (name.startsWith(".")) {
+                continue;
+            }
+            SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str()));
+            load_directory_fonts(scanner, dirname, suffix, families);
+        }
+    }
+
+    SkString fBaseDirectory;
+};
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir) {
+    return sk_make_sp<SkFontMgr_Custom>(DirectorySystemFontLoader(dir));
+}
diff --git a/src/ports/SkFontMgr_custom_directory_factory.cpp b/src/ports/SkFontMgr_custom_directory_factory.cpp
index 7ed4711..e8d4bb3 100644
--- a/src/ports/SkFontMgr_custom_directory_factory.cpp
+++ b/src/ports/SkFontMgr_custom_directory_factory.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "SkFontMgr.h"
-#include "SkFontMgr_custom.h"
+#include "SkFontMgr_directory.h"
 
 #ifndef SK_FONT_FILE_PREFIX
 #    define SK_FONT_FILE_PREFIX "/usr/share/fonts/"
diff --git a/src/ports/SkFontMgr_custom_embedded.cpp b/src/ports/SkFontMgr_custom_embedded.cpp
new file mode 100644
index 0000000..bb8d9f2
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_embedded.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontDescriptor.h"
+#include "SkFontMgr_custom.h"
+#include "SkMakeUnique.h"
+#include "SkStream.h"
+
+struct SkEmbeddedResource { const uint8_t* data; size_t size; };
+struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
+
+class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+    EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(header) { }
+
+    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+                         SkFontMgr_Custom::Families* families) const override
+    {
+        for (int i = 0; i < fHeader->count; ++i) {
+            const SkEmbeddedResource& fontEntry = fHeader->entries[i];
+            load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, families);
+        }
+
+        if (families->empty()) {
+            SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+            families->push_back().reset(family);
+            family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+        }
+    }
+
+private:
+    static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
+                                              const char familyName[])
+    {
+       for (int i = 0; i < families.count(); ++i) {
+            if (families[i]->getFamilyName().equals(familyName)) {
+                return families[i].get();
+            }
+        }
+        return nullptr;
+    }
+
+    static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner,
+                                   const uint8_t* data, size_t size, int index,
+                                   SkFontMgr_Custom::Families* families)
+    {
+        auto stream = skstd::make_unique<SkMemoryStream>(data, size, false);
+
+        int numFaces;
+        if (!scanner.recognizedFont(stream.get(), &numFaces)) {
+            SkDebugf("---- failed to open <%d> as a font\n", index);
+            return;
+        }
+
+        for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
+            bool isFixedPitch;
+            SkString realname;
+            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
+            if (!scanner.scanFont(stream.get(), faceIndex,
+                                  &realname, &style, &isFixedPitch, nullptr))
+            {
+                SkDebugf("---- failed to open <%d> <%d> as a font\n", index, faceIndex);
+                return;
+            }
+
+            SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
+            if (nullptr == addTo) {
+                addTo = new SkFontStyleSet_Custom(realname);
+                families->push_back().reset(addTo);
+            }
+            auto data = skstd::make_unique<SkFontData>(std::move(stream), faceIndex, nullptr, 0);
+            addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
+                                                                style, isFixedPitch,
+                                                                true, realname));
+        }
+    }
+
+    const SkEmbeddedResourceHeader* fHeader;
+};
+
+sk_sp<SkFontMgr> SkFontMgr_New_Custom_Embedded(const SkEmbeddedResourceHeader* header) {
+    return sk_make_sp<SkFontMgr_Custom>(EmbeddedSystemFontLoader(header));
+}
diff --git a/src/ports/SkFontMgr_custom_empty.cpp b/src/ports/SkFontMgr_custom_empty.cpp
new file mode 100644
index 0000000..8732bc3
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_empty.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontMgr_custom.h"
+#include "SkFontMgr_empty.h"
+
+class EmptyFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+    EmptyFontLoader() { }
+
+    void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+                         SkFontMgr_Custom::Families* families) const override
+    {
+        SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+        families->push_back().reset(family);
+        family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+    }
+
+};
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty() {
+    return sk_make_sp<SkFontMgr_Custom>(EmptyFontLoader());
+}