• 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