Flutter Engine
The Flutter Engine
FontCollection.cpp
Go to the documentation of this file.
1// Copyright 2019 Google LLC.
3
8
9namespace {
10#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
11 const char* kColorEmojiFontMac = "Apple Color Emoji";
12#else
13 const char* kColorEmojiLocale = "und-Zsye";
14#endif
15}
16namespace skia {
17namespace textlayout {
18
19bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const {
20 return fFamilyNames == other.fFamilyNames &&
21 fFontStyle == other.fFontStyle &&
22 fFontArguments == other.fFontArguments;
23}
24
25size_t FontCollection::FamilyKey::Hasher::operator()(const FontCollection::FamilyKey& key) const {
26 size_t hash = 0;
27 for (const SkString& family : key.fFamilyNames) {
28 hash ^= std::hash<std::string>()(family.c_str());
29 }
30 return hash ^
31 std::hash<uint32_t>()(key.fFontStyle.weight()) ^
32 std::hash<uint32_t>()(key.fFontStyle.slant()) ^
33 std::hash<std::optional<FontArguments>>()(key.fFontArguments);
34}
35
37 : fEnableFontFallback(true)
38 , fDefaultFamilyNames({SkString(DEFAULT_FONT_FAMILY)}) { }
39
40size_t FontCollection::getFontManagersCount() const { return this->getFontManagerOrder().size(); }
41
43 fAssetFontManager = std::move(font_manager);
44}
45
47 fDynamicFontManager = std::move(font_manager);
48}
49
51 fTestFontManager = std::move(font_manager);
52}
53
55 const char defaultFamilyName[]) {
56 fDefaultFontManager = std::move(fontManager);
57 fDefaultFamilyNames.emplace_back(defaultFamilyName);
58}
59
61 const std::vector<SkString>& defaultFamilyNames) {
62 fDefaultFontManager = std::move(fontManager);
63 fDefaultFamilyNames = defaultFamilyNames;
64}
65
67 fDefaultFontManager = std::move(fontManager);
68}
69
70// Return the available font managers in the order they should be queried.
71std::vector<sk_sp<SkFontMgr>> FontCollection::getFontManagerOrder() const {
72 std::vector<sk_sp<SkFontMgr>> order;
73 if (fDynamicFontManager) {
74 order.push_back(fDynamicFontManager);
75 }
76 if (fAssetFontManager) {
77 order.push_back(fAssetFontManager);
78 }
79 if (fTestFontManager) {
80 order.push_back(fTestFontManager);
81 }
82 if (fDefaultFontManager && fEnableFontFallback) {
83 order.push_back(fDefaultFontManager);
84 }
85 return order;
86}
87
88std::vector<sk_sp<SkTypeface>> FontCollection::findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle) {
89 return findTypefaces(familyNames, fontStyle, std::nullopt);
90}
91
92std::vector<sk_sp<SkTypeface>> FontCollection::findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle, const std::optional<FontArguments>& fontArgs) {
93 // Look inside the font collections cache first
94 FamilyKey familyKey(familyNames, fontStyle, fontArgs);
95 auto found = fTypefaces.find(familyKey);
96 if (found) {
97 return *found;
98 }
99
100 std::vector<sk_sp<SkTypeface>> typefaces;
101 for (const SkString& familyName : familyNames) {
102 sk_sp<SkTypeface> match = matchTypeface(familyName, fontStyle);
103 if (match && fontArgs) {
104 match = fontArgs->CloneTypeface(match);
105 }
106 if (match) {
107 typefaces.emplace_back(std::move(match));
108 }
109 }
110
111 if (typefaces.empty()) {
113 for (const SkString& familyName : fDefaultFamilyNames) {
114 match = matchTypeface(familyName, fontStyle);
115 if (match) {
116 break;
117 }
118 }
119 if (!match) {
120 for (const auto& manager : this->getFontManagerOrder()) {
121 match = manager->legacyMakeTypeface(nullptr, fontStyle);
122 if (match) {
123 break;
124 }
125 }
126 }
127 if (match) {
128 typefaces.emplace_back(std::move(match));
129 }
130 }
131
132 fTypefaces.set(familyKey, typefaces);
133 return typefaces;
134}
135
136sk_sp<SkTypeface> FontCollection::matchTypeface(const SkString& familyName, SkFontStyle fontStyle) {
137 for (const auto& manager : this->getFontManagerOrder()) {
138 sk_sp<SkFontStyleSet> set(manager->matchFamily(familyName.c_str()));
139 if (!set || set->count() == 0) {
140 continue;
141 }
142
143 sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
144 if (match) {
145 return match;
146 }
147 }
148
149 return nullptr;
150}
151
152// Find ANY font in available font managers that resolves the unicode codepoint
154 SkFontStyle fontStyle,
155 const SkString& locale) {
156
157 for (const auto& manager : this->getFontManagerOrder()) {
158 std::vector<const char*> bcp47;
159 if (!locale.isEmpty()) {
160 bcp47.push_back(locale.c_str());
161 }
162 sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter(
163 nullptr, fontStyle, bcp47.data(), bcp47.size(), unicode));
164
165 if (typeface != nullptr) {
166 return typeface;
167 }
168 }
169 return nullptr;
170}
171
172// Find ANY font in available font managers that resolves this emojiStart
174 SkFontStyle fontStyle,
175 const SkString& locale) {
176
177 for (const auto& manager : this->getFontManagerOrder()) {
178 std::vector<const char*> bcp47;
179#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
180 sk_sp<SkTypeface> emojiTypeface =
181 fDefaultFontManager->matchFamilyStyle(kColorEmojiFontMac, SkFontStyle());
182 if (emojiTypeface != nullptr) {
183 return emojiTypeface;
184 }
185#else
186 bcp47.push_back(kColorEmojiLocale);
187#endif
188 if (!locale.isEmpty()) {
189 bcp47.push_back(locale.c_str());
190 }
191
192 // Not really ideal since the first codepoint may not be the best one
193 // but we start from a good colored emoji at least
194 sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter(
195 nullptr, fontStyle, bcp47.data(), bcp47.size(), emojiStart));
196 if (typeface != nullptr) {
197 // ... and stop as soon as we find something in hope it will work for all of them
198 return typeface;
199 }
200 }
201 return nullptr;
202}
203
205 if (fDefaultFontManager == nullptr) {
206 return nullptr;
207 }
208 for (const SkString& familyName : fDefaultFamilyNames) {
209 sk_sp<SkTypeface> match = fDefaultFontManager->matchFamilyStyle(familyName.c_str(),
210 SkFontStyle());
211 if (match) {
212 return match;
213 }
214 }
215 return nullptr;
216}
217
218void FontCollection::disableFontFallback() { fEnableFontFallback = false; }
219void FontCollection::enableFontFallback() { fEnableFontFallback = true; }
220
222 fParagraphCache.reset();
223 fTypefaces.reset();
225}
226
227} // namespace textlayout
228} // namespace skia
static uint32_t hash(const SkShaderBase::GradientInfo &v)
int32_t SkUnichar
Definition: SkTypes.h:175
#define DEFAULT_FONT_FAMILY
Definition: TextStyle.h:19
sk_sp< SkTypeface > matchFamilyStyle(const char familyName[], const SkFontStyle &) const
Definition: SkFontMgr.cpp:109
bool isEmpty() const
Definition: SkString.h:130
const char * c_str() const
Definition: SkString.h:133
sk_sp< SkTypeface > defaultEmojiFallback(SkUnichar emojiStart, SkFontStyle fontStyle, const SkString &locale)
std::vector< sk_sp< SkTypeface > > findTypefaces(const std::vector< SkString > &familyNames, SkFontStyle fontStyle)
void setDefaultFontManager(sk_sp< SkFontMgr > fontManager)
void setAssetFontManager(sk_sp< SkFontMgr > fontManager)
void setDynamicFontManager(sk_sp< SkFontMgr > fontManager)
void setTestFontManager(sk_sp< SkFontMgr > fontManager)
sk_sp< SkTypeface > defaultFallback()
SKSHAPER_API void PurgeCaches()
def match(bench, filt)
Definition: benchmark.py:23
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
Definition: switches.h:218
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
bool operator==(C p1, const scoped_nsprotocol< C > &p2)
Definition: DartTypes.h:13
size_t operator()(const FamilyKey &key) const