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