1 // Copyright 2019 Google LLC. 2 #include "include/core/SkTypeface.h" 3 #include "modules/skparagraph/include/FontCollection.h" 4 #include "modules/skparagraph/include/Paragraph.h" 5 #include "modules/skparagraph/src/ParagraphImpl.h" 6 7 namespace skia { 8 namespace textlayout { 9 operator ==(const FontCollection::FamilyKey & other) const10 bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const { 11 return fFontFamily == other.fFontFamily && fLocale == other.fLocale && 12 fFontStyle == other.fFontStyle; 13 } 14 operator ()(const FontCollection::FamilyKey & key) const15 size_t FontCollection::FamilyKey::Hasher::operator()(const FontCollection::FamilyKey& key) const { 16 return std::hash<std::string>()(key.fFontFamily.c_str()) ^ 17 std::hash<std::string>()(key.fLocale.c_str()) ^ 18 std::hash<uint32_t>()(key.fFontStyle.weight()) ^ 19 std::hash<uint32_t>()(key.fFontStyle.slant()); 20 } 21 FontCollection()22 FontCollection::FontCollection() 23 : fEnableFontFallback(true) 24 , fDefaultFamilyName(DEFAULT_FONT_FAMILY) { } 25 getFontManagersCount() const26 size_t FontCollection::getFontManagersCount() const { return this->getFontManagerOrder().size(); } 27 setAssetFontManager(sk_sp<SkFontMgr> font_manager)28 void FontCollection::setAssetFontManager(sk_sp<SkFontMgr> font_manager) { 29 fAssetFontManager = font_manager; 30 } 31 setDynamicFontManager(sk_sp<SkFontMgr> font_manager)32 void FontCollection::setDynamicFontManager(sk_sp<SkFontMgr> font_manager) { 33 fDynamicFontManager = font_manager; 34 } 35 setTestFontManager(sk_sp<SkFontMgr> font_manager)36 void FontCollection::setTestFontManager(sk_sp<SkFontMgr> font_manager) { 37 fTestFontManager = font_manager; 38 } 39 setDefaultFontManager(sk_sp<SkFontMgr> fontManager,const char defaultFamilyName[])40 void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager, 41 const char defaultFamilyName[]) { 42 fDefaultFontManager = std::move(fontManager); 43 fDefaultFamilyName = defaultFamilyName; 44 } 45 setDefaultFontManager(sk_sp<SkFontMgr> fontManager)46 void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager) { 47 fDefaultFontManager = fontManager; 48 } 49 50 // Return the available font managers in the order they should be queried. getFontManagerOrder() const51 std::vector<sk_sp<SkFontMgr>> FontCollection::getFontManagerOrder() const { 52 std::vector<sk_sp<SkFontMgr>> order; 53 if (fDynamicFontManager) { 54 order.push_back(fDynamicFontManager); 55 } 56 if (fAssetFontManager) { 57 order.push_back(fAssetFontManager); 58 } 59 if (fTestFontManager) { 60 order.push_back(fTestFontManager); 61 } 62 if (fDefaultFontManager && fEnableFontFallback) { 63 order.push_back(fDefaultFontManager); 64 } 65 return order; 66 } 67 matchTypeface(const char familyName[],SkFontStyle fontStyle)68 sk_sp<SkTypeface> FontCollection::matchTypeface(const char familyName[], SkFontStyle fontStyle) { 69 // Look inside the font collections cache first 70 FamilyKey familyKey(familyName, "en", fontStyle); 71 auto found = fTypefaces.find(familyKey); 72 if (found) { 73 return *found; 74 } 75 76 sk_sp<SkTypeface> typeface = nullptr; 77 for (const auto& manager : this->getFontManagerOrder()) { 78 SkFontStyleSet* set = manager->matchFamily(familyName); 79 if (nullptr == set || set->count() == 0) { 80 continue; 81 } 82 83 for (int i = 0; i < set->count(); ++i) { 84 set->createTypeface(i); 85 } 86 87 sk_sp<SkTypeface> match(set->matchStyle(fontStyle)); 88 if (match) { 89 typeface = std::move(match); 90 return typeface; 91 } 92 } 93 94 return nullptr; 95 } 96 matchDefaultTypeface(SkFontStyle fontStyle)97 sk_sp<SkTypeface> FontCollection::matchDefaultTypeface(SkFontStyle fontStyle) { 98 // Look inside the font collections cache first 99 FamilyKey familyKey(fDefaultFamilyName, "en", fontStyle); 100 auto found = fTypefaces.find(familyKey); 101 if (found) { 102 return *found; 103 } 104 105 sk_sp<SkTypeface> typeface = nullptr; 106 for (const auto& manager : this->getFontManagerOrder()) { 107 SkFontStyleSet* set = manager->matchFamily(fDefaultFamilyName); 108 if (nullptr == set || set->count() == 0) { 109 continue; 110 } 111 112 for (int i = 0; i < set->count(); ++i) { 113 set->createTypeface(i); 114 } 115 116 sk_sp<SkTypeface> match(set->matchStyle(fontStyle)); 117 if (match) { 118 typeface = std::move(match); 119 return typeface; 120 } 121 } 122 123 return nullptr; 124 } 125 defaultFallback(SkUnichar unicode,SkFontStyle fontStyle,const SkString & locale)126 sk_sp<SkTypeface> FontCollection::defaultFallback(SkUnichar unicode, SkFontStyle fontStyle, const SkString& locale) { 127 128 for (const auto& manager : this->getFontManagerOrder()) { 129 std::vector<const char*> bcp47; 130 if (!locale.isEmpty()) { 131 bcp47.push_back(locale.c_str()); 132 } 133 sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter( 134 0, fontStyle, bcp47.data(), bcp47.size(), unicode)); 135 if (typeface != nullptr) { 136 return typeface; 137 } 138 } 139 140 if (fDefaultFontManager == nullptr) { 141 return nullptr; 142 } 143 auto result = fDefaultFontManager->matchFamilyStyle(fDefaultFamilyName, fontStyle); 144 return sk_ref_sp<SkTypeface>(result); 145 } 146 disableFontFallback()147 void FontCollection::disableFontFallback() { fEnableFontFallback = false; } 148 149 } // namespace textlayout 150 } // namespace skia 151