blob: c085b99cf35146de42cd05bb384dbb24d1d15153 [file] [log] [blame]
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001// Copyright 2019 Google LLC.
2#include "modules/skparagraph/include/FontCollection.h"
3#include <string>
4
5namespace skia {
6namespace textlayout {
7
8bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const {
9 return fFontFamily == other.fFontFamily && fLocale == other.fLocale &&
10 fFontStyle == other.fFontStyle;
11}
12
13size_t FontCollection::FamilyKey::Hasher::operator()(const FontCollection::FamilyKey& key) const {
14 return std::hash<std::string>()(key.fFontFamily.c_str()) ^
15 std::hash<std::string>()(key.fLocale.c_str()) ^
16 std::hash<uint32_t>()(key.fFontStyle.weight()) ^
17 std::hash<uint32_t>()(key.fFontStyle.slant());
18}
19
20FontCollection::FontCollection()
21 : fEnableFontFallback(true)
22 , fDefaultFontManager(SkFontMgr::RefDefault())
23 , fDefaultFamilyName(DEFAULT_FONT_FAMILY) {}
24
25FontCollection::~FontCollection() = default;
26
27size_t FontCollection::getFontManagersCount() const { return this->getFontManagerOrder().size(); }
28
29void FontCollection::setAssetFontManager(sk_sp<SkFontMgr> font_manager) {
30 fAssetFontManager = font_manager;
31}
32
33void FontCollection::setDynamicFontManager(sk_sp<SkFontMgr> font_manager) {
34 fDynamicFontManager = font_manager;
35}
36
37void FontCollection::setTestFontManager(sk_sp<SkFontMgr> font_manager) {
38 fTestFontManager = font_manager;
39}
40
41void FontCollection::setDefaultFontManager(sk_sp<SkFontMgr> fontManager,
42 const char defaultFamilyName[]) {
43 fDefaultFontManager = fontManager;
44 fDefaultFamilyName = defaultFamilyName;
45}
46
47// Return the available font managers in the order they should be queried.
48std::vector<sk_sp<SkFontMgr>> FontCollection::getFontManagerOrder() const {
49 std::vector<sk_sp<SkFontMgr>> order;
50 if (fDynamicFontManager) {
51 order.push_back(fDynamicFontManager);
52 }
53 if (fAssetFontManager) {
54 order.push_back(fAssetFontManager);
55 }
56 if (fTestFontManager) {
57 order.push_back(fTestFontManager);
58 }
59 if (fDefaultFontManager && fEnableFontFallback) {
60 order.push_back(fDefaultFontManager);
61 }
62 return order;
63}
64
65sk_sp<SkTypeface> FontCollection::matchTypeface(const char familyName[], SkFontStyle fontStyle) {
66 // Look inside the font collections cache first
67 FamilyKey familyKey(familyName, "en", fontStyle);
68 auto found = fTypefaces.find(familyKey);
69 if (found) {
70 return *found;
71 }
72
73 sk_sp<SkTypeface> typeface = nullptr;
74 for (const auto& manager : this->getFontManagerOrder()) {
75 SkFontStyleSet* set = manager->matchFamily(familyName);
76 if (nullptr == set || set->count() == 0) {
77 continue;
78 }
79
80 for (int i = 0; i < set->count(); ++i) {
81 set->createTypeface(i);
82 }
83
84 sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
85 if (match) {
86 typeface = std::move(match);
87 return typeface;
88 }
89 }
90
91 return nullptr;
92}
93
94sk_sp<SkTypeface> FontCollection::matchDefaultTypeface(SkFontStyle fontStyle) {
95 // Look inside the font collections cache first
96 FamilyKey familyKey(fDefaultFamilyName.c_str(), "en", fontStyle);
97 auto found = fTypefaces.find(familyKey);
98 if (found) {
99 return *found;
100 }
101
102 sk_sp<SkTypeface> typeface = nullptr;
103 for (const auto& manager : this->getFontManagerOrder()) {
104 SkFontStyleSet* set = manager->matchFamily(fDefaultFamilyName.c_str());
105 if (nullptr == set || set->count() == 0) {
106 continue;
107 }
108
109 for (int i = 0; i < set->count(); ++i) {
110 set->createTypeface(i);
111 }
112
113 sk_sp<SkTypeface> match(set->matchStyle(fontStyle));
114 if (match) {
115 typeface = std::move(match);
116 return typeface;
117 }
118 }
119
120 return nullptr;
121}
122
123sk_sp<SkTypeface> FontCollection::defaultFallback(SkUnichar unicode, SkFontStyle fontStyle) {
124
125 for (const auto& manager : this->getFontManagerOrder()) {
126 std::vector<const char*> bcp47;
127 sk_sp<SkTypeface> typeface(manager->matchFamilyStyleCharacter(
128 0, fontStyle, bcp47.data(), bcp47.size(), unicode));
129 if (typeface != nullptr) {
130 return typeface;
131 }
132 }
133
134 auto result = fDefaultFontManager->matchFamilyStyle(fDefaultFamilyName.c_str(), fontStyle);
135 return sk_ref_sp<SkTypeface>(result);
136}
137
138void FontCollection::disableFontFallback() { fEnableFontFallback = false; }
139
140} // namespace textlayout
141} // namespace skia