• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "modules/skshaper/include/SkShaper.h"
7 
8 namespace skia {
9 namespace textlayout {
10 
operator ==(const FontCollection::FamilyKey & other) const11 bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const {
12     return fFamilyNames == other.fFamilyNames &&
13            fFontStyle == other.fFontStyle &&
14            fFontArguments == other.fFontArguments;
15 }
16 
operator ()(const FontCollection::FamilyKey & key) const17 size_t FontCollection::FamilyKey::Hasher::operator()(const FontCollection::FamilyKey& key) const {
18     size_t hash = 0;
19     for (const SkString& family : key.fFamilyNames) {
20         hash ^= std::hash<std::string>()(family.c_str());
21     }
22     return hash ^
23            std::hash<uint32_t>()(key.fFontStyle.weight()) ^
24            std::hash<uint32_t>()(key.fFontStyle.slant()) ^
25            std::hash<std::optional<FontArguments>>()(key.fFontArguments);
26 }
27 
FontCollection()28 FontCollection::FontCollection()
29         : fEnableFontFallback(true)
30         , fDefaultFamilyNames({SkString(DEFAULT_FONT_FAMILY)}) { }
31 
getFontManagersCount() const32 size_t FontCollection::getFontManagersCount() const { return this->getFontManagerOrder().size(); }
33 
setAssetFontManager(sk_sp<SkFontMgr> font_manager)34 void FontCollection::setAssetFontManager(sk_sp<SkFontMgr> font_manager) {
35     fAssetFontManager = font_manager;
36 }
37 
setDynamicFontManager(sk_sp<SkFontMgr> font_manager)38 void FontCollection::setDynamicFontManager(sk_sp<SkFontMgr> font_manager) {
39     fDynamicFontManager = font_manager;
40 }
41 
setTestFontManager(sk_sp<SkFontMgr> font_manager)42 void FontCollection::setTestFontManager(sk_sp<SkFontMgr> font_manager) {
43     fTestFontManager = font_manager;
44 }
45 
setDefaultFontManager(sk_sp<SkFontMgr> fontManager,const char defaultFamilyName[])46 void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager,
47                                            const char defaultFamilyName[]) {
48     fDefaultFontManager = std::move(fontManager);
49     fDefaultFamilyNames.emplace_back(defaultFamilyName);
50 }
51 
setDefaultFontManager(sk_sp<SkFontMgr> fontManager,const std::vector<SkString> & defaultFamilyNames)52 void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager,
53                                            const std::vector<SkString>& defaultFamilyNames) {
54     fDefaultFontManager = std::move(fontManager);
55     fDefaultFamilyNames = defaultFamilyNames;
56 }
57 
setDefaultFontManager(sk_sp<SkFontMgr> fontManager)58 void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager) {
59     fDefaultFontManager = fontManager;
60 }
61 
62 // Return the available font managers in the order they should be queried.
getFontManagerOrder() const63 std::vector<sk_sp<SkFontMgr>> FontCollection::getFontManagerOrder() const {
64     std::vector<sk_sp<SkFontMgr>> order;
65     if (fDynamicFontManager) {
66         order.push_back(fDynamicFontManager);
67     }
68     if (fAssetFontManager) {
69         order.push_back(fAssetFontManager);
70     }
71     if (fTestFontManager) {
72         order.push_back(fTestFontManager);
73     }
74     if (fDefaultFontManager && fEnableFontFallback) {
75         order.push_back(fDefaultFontManager);
76     }
77     return order;
78 }
79 
findTypefaces(const std::vector<SkString> & familyNames,SkFontStyle fontStyle)80 std::vector<sk_sp<SkTypeface>> FontCollection::findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle) {
81     return findTypefaces(familyNames, fontStyle, std::nullopt);
82 }
83 
findTypefaces(const std::vector<SkString> & familyNames,SkFontStyle fontStyle,const std::optional<FontArguments> & fontArgs)84 std::vector<sk_sp<SkTypeface>> FontCollection::findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle, const std::optional<FontArguments>& fontArgs) {
85     // Look inside the font collections cache first
86     FamilyKey familyKey(familyNames, fontStyle, fontArgs);
87     auto found = fTypefaces.find(familyKey);
88     if (found) {
89         return *found;
90     }
91 
92     std::vector<sk_sp<SkTypeface>> typefaces;
93     for (const SkString& familyName : familyNames) {
94         sk_sp<SkTypeface> match = matchTypeface(familyName, fontStyle);
95         if (match && fontArgs) {
96             match = fontArgs->CloneTypeface(match);
97         }
98         if (match) {
99             typefaces.emplace_back(std::move(match));
100         }
101     }
102 
103     if (typefaces.empty()) {
104         sk_sp<SkTypeface> match;
105         for (const SkString& familyName : fDefaultFamilyNames) {
106             match = matchTypeface(familyName, fontStyle);
107             if (match) {
108                 break;
109             }
110         }
111         if (!match) {
112             for (const auto& manager : this->getFontManagerOrder()) {
113                 match = manager->legacyMakeTypeface(nullptr, fontStyle);
114                 if (match) {
115                     break;
116                 }
117             }
118         }
119         if (match) {
120             typefaces.emplace_back(std::move(match));
121         }
122     }
123 
124     fTypefaces.set(familyKey, typefaces);
125     return typefaces;
126 }
127 
matchTypeface(const SkString & familyName,SkFontStyle fontStyle)128 sk_sp<SkTypeface> FontCollection::matchTypeface(const SkString& familyName, SkFontStyle fontStyle) {
129     for (const auto& manager : this->getFontManagerOrder()) {
130         sk_sp<SkFontStyleSet> set(manager->matchFamily(familyName.c_str()));
131         if (!set || set->count() == 0) {
132             continue;
133         }
134 
135         sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
136         if (match) {
137             return match;
138         }
139     }
140 
141     return nullptr;
142 }
143 
144 // Find ANY font in available font managers that resolves the unicode codepoint
defaultFallback(SkUnichar unicode,SkFontStyle fontStyle,const SkString & locale)145 sk_sp<SkTypeface> FontCollection::defaultFallback(SkUnichar unicode, SkFontStyle fontStyle, const SkString& locale) {
146 
147     for (const auto& manager : this->getFontManagerOrder()) {
148         std::vector<const char*> bcp47;
149         if (!locale.isEmpty()) {
150             bcp47.push_back(locale.c_str());
151         }
152         sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter(
153                 nullptr, fontStyle, bcp47.data(), bcp47.size(), unicode));
154         if (typeface != nullptr) {
155             return typeface;
156         }
157     }
158     return nullptr;
159 }
160 
defaultFallback()161 sk_sp<SkTypeface> FontCollection::defaultFallback() {
162     if (fDefaultFontManager == nullptr) {
163         return nullptr;
164     }
165     for (const SkString& familyName : fDefaultFamilyNames) {
166         SkTypeface* match = fDefaultFontManager->matchFamilyStyle(familyName.c_str(),
167                                                                   SkFontStyle());
168         if (match) {
169             return sk_sp<SkTypeface>(match);
170         }
171     }
172     return nullptr;
173 }
174 
175 
disableFontFallback()176 void FontCollection::disableFontFallback() { fEnableFontFallback = false; }
enableFontFallback()177 void FontCollection::enableFontFallback() { fEnableFontFallback = true; }
178 
clearCaches()179 void FontCollection::clearCaches() {
180     fParagraphCache.reset();
181     fTypefaces.reset();
182     SkShaper::PurgeCaches();
183 }
184 
185 }  // namespace textlayout
186 }  // namespace skia
187