• 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 
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