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