Reland "SkParagraph"

This is a reland of 10ad0b9b01e4b8a4721ae2ec1adee9ca7d0fe534

Original change's description:
> SkParagraph
>
> Change-Id: I0a4be75fd0c18021c201bcc1edfdfad8556edeff
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/192100
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>

Change-Id: I46cf43eae693edf68e45345acd0eb39e04e02bfc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/219863
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/src/FontCollection.cpp b/modules/skparagraph/src/FontCollection.cpp
new file mode 100644
index 0000000..c085b99
--- /dev/null
+++ b/modules/skparagraph/src/FontCollection.cpp
@@ -0,0 +1,141 @@
+// Copyright 2019 Google LLC.
+#include "modules/skparagraph/include/FontCollection.h"
+#include <string>
+
+namespace skia {
+namespace textlayout {
+
+bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const {
+    return fFontFamily == other.fFontFamily && fLocale == other.fLocale &&
+           fFontStyle == other.fFontStyle;
+}
+
+size_t FontCollection::FamilyKey::Hasher::operator()(const FontCollection::FamilyKey& key) const {
+    return std::hash<std::string>()(key.fFontFamily.c_str()) ^
+           std::hash<std::string>()(key.fLocale.c_str()) ^
+           std::hash<uint32_t>()(key.fFontStyle.weight()) ^
+           std::hash<uint32_t>()(key.fFontStyle.slant());
+}
+
+FontCollection::FontCollection()
+        : fEnableFontFallback(true)
+        , fDefaultFontManager(SkFontMgr::RefDefault())
+        , fDefaultFamilyName(DEFAULT_FONT_FAMILY) {}
+
+FontCollection::~FontCollection() = default;
+
+size_t FontCollection::getFontManagersCount() const { return this->getFontManagerOrder().size(); }
+
+void FontCollection::setAssetFontManager(sk_sp<SkFontMgr> font_manager) {
+    fAssetFontManager = font_manager;
+}
+
+void FontCollection::setDynamicFontManager(sk_sp<SkFontMgr> font_manager) {
+    fDynamicFontManager = font_manager;
+}
+
+void FontCollection::setTestFontManager(sk_sp<SkFontMgr> font_manager) {
+    fTestFontManager = font_manager;
+}
+
+void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager,
+                                           const char defaultFamilyName[]) {
+    fDefaultFontManager = fontManager;
+    fDefaultFamilyName = defaultFamilyName;
+}
+
+// Return the available font managers in the order they should be queried.
+std::vector<sk_sp<SkFontMgr>> FontCollection::getFontManagerOrder() const {
+    std::vector<sk_sp<SkFontMgr>> order;
+    if (fDynamicFontManager) {
+        order.push_back(fDynamicFontManager);
+    }
+    if (fAssetFontManager) {
+        order.push_back(fAssetFontManager);
+    }
+    if (fTestFontManager) {
+        order.push_back(fTestFontManager);
+    }
+    if (fDefaultFontManager && fEnableFontFallback) {
+        order.push_back(fDefaultFontManager);
+    }
+    return order;
+}
+
+sk_sp<SkTypeface> FontCollection::matchTypeface(const char familyName[], SkFontStyle fontStyle) {
+    // Look inside the font collections cache first
+    FamilyKey familyKey(familyName, "en", fontStyle);
+    auto found = fTypefaces.find(familyKey);
+    if (found) {
+        return *found;
+    }
+
+    sk_sp<SkTypeface> typeface = nullptr;
+    for (const auto& manager : this->getFontManagerOrder()) {
+        SkFontStyleSet* set = manager->matchFamily(familyName);
+        if (nullptr == set || set->count() == 0) {
+            continue;
+        }
+
+        for (int i = 0; i < set->count(); ++i) {
+            set->createTypeface(i);
+        }
+
+        sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
+        if (match) {
+            typeface = std::move(match);
+            return typeface;
+        }
+    }
+
+    return nullptr;
+}
+
+sk_sp<SkTypeface> FontCollection::matchDefaultTypeface(SkFontStyle fontStyle) {
+    // Look inside the font collections cache first
+    FamilyKey familyKey(fDefaultFamilyName.c_str(), "en", fontStyle);
+    auto found = fTypefaces.find(familyKey);
+    if (found) {
+        return *found;
+    }
+
+    sk_sp<SkTypeface> typeface = nullptr;
+    for (const auto& manager : this->getFontManagerOrder()) {
+        SkFontStyleSet* set = manager->matchFamily(fDefaultFamilyName.c_str());
+        if (nullptr == set || set->count() == 0) {
+            continue;
+        }
+
+        for (int i = 0; i < set->count(); ++i) {
+            set->createTypeface(i);
+        }
+
+        sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
+        if (match) {
+            typeface = std::move(match);
+            return typeface;
+        }
+    }
+
+    return nullptr;
+}
+
+sk_sp<SkTypeface> FontCollection::defaultFallback(SkUnichar unicode, SkFontStyle fontStyle) {
+
+    for (const auto& manager : this->getFontManagerOrder()) {
+        std::vector<const char*> bcp47;
+        sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter(
+                0, fontStyle, bcp47.data(), bcp47.size(), unicode));
+        if (typeface != nullptr) {
+            return typeface;
+        }
+    }
+
+    auto result = fDefaultFontManager->matchFamilyStyle(fDefaultFamilyName.c_str(), fontStyle);
+    return sk_ref_sp<SkTypeface>(result);
+}
+
+void FontCollection::disableFontFallback() { fEnableFontFallback = false; }
+
+}  // namespace textlayout
+}  // namespace skia