1 // Copyright 2019 Google LLC.
2 #include "modules/skparagraph/include/TypefaceFontProvider.h"
3 #include <algorithm>
4 #include "include/core/SkFontMgr.h"
5 #include "include/core/SkString.h"
6 #include "include/core/SkTypeface.h"
7 #include "src/core/SkFontDescriptor.h"
8
9 namespace skia {
10 namespace textlayout {
11
onCountFamilies() const12 int TypefaceFontProvider::onCountFamilies() const { return fRegisteredFamilies.count(); }
13
onGetFamilyName(int index,SkString * familyName) const14 void TypefaceFontProvider::onGetFamilyName(int index, SkString* familyName) const {
15 SkASSERT(index < fRegisteredFamilies.count());
16 familyName->set(fFamilyNames[index]);
17 }
18
onMatchFamily(const char familyName[]) const19 sk_sp<SkFontStyleSet> TypefaceFontProvider::onMatchFamily(const char familyName[]) const {
20 auto found = fRegisteredFamilies.find(SkString(familyName));
21 return found ? *found : nullptr;
22 }
23
onCreateStyleSet(int index) const24 sk_sp<SkFontStyleSet> TypefaceFontProvider::onCreateStyleSet(int index) const {
25 SkASSERT(index < fRegisteredFamilies.count());
26 auto found = fRegisteredFamilies.find(fFamilyNames[index]);
27 return found ? *found : nullptr;
28 }
29
onMatchFamilyStyle(const char familyName[],const SkFontStyle & pattern) const30 sk_sp<SkTypeface> TypefaceFontProvider::onMatchFamilyStyle(const char familyName[], const SkFontStyle& pattern) const {
31 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
32 if (sset) {
33 return sset->matchStyle(pattern);
34 }
35
36 return nullptr;
37 }
38
registerTypeface(sk_sp<SkTypeface> typeface)39 size_t TypefaceFontProvider::registerTypeface(sk_sp<SkTypeface> typeface) {
40 if (typeface == nullptr) {
41 return 0;
42 }
43
44 SkString familyName;
45 typeface->getFamilyName(&familyName);
46
47 return registerTypeface(std::move(typeface), std::move(familyName));
48 }
49
registerTypeface(sk_sp<SkTypeface> typeface,const SkString & familyName)50 size_t TypefaceFontProvider::registerTypeface(sk_sp<SkTypeface> typeface, const SkString& familyName) {
51 if (familyName.size() == 0) {
52 return 0;
53 }
54
55 auto found = fRegisteredFamilies.find(familyName);
56 if (found == nullptr) {
57 found = fRegisteredFamilies.set(familyName, sk_make_sp<TypefaceFontStyleSet>(familyName));
58 fFamilyNames.emplace_back(familyName);
59 }
60
61 (*found)->appendTypeface(std::move(typeface));
62
63 return 1;
64 }
65
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const66 sk_sp<SkTypeface> TypefaceFontProvider::onLegacyMakeTypeface(const char familyName[],
67 SkFontStyle style) const {
68 if (familyName) {
69 sk_sp<SkTypeface> matchedByFamily = this->matchFamilyStyle(familyName, style);
70 if (matchedByFamily) {
71 return matchedByFamily;
72 }
73 }
74 if (this->countFamilies() == 0) {
75 return nullptr;
76 }
77 sk_sp<SkFontStyleSet> defaultFamily = this->createStyleSet(0);
78 if (!defaultFamily) {
79 return nullptr;
80 }
81 return defaultFamily->matchStyle(style);
82 }
83
TypefaceFontStyleSet(const SkString & familyName)84 TypefaceFontStyleSet::TypefaceFontStyleSet(const SkString& familyName)
85 : fFamilyName(familyName) {}
86
count()87 int TypefaceFontStyleSet::count() { return fStyles.size(); }
88
getStyle(int index,SkFontStyle * style,SkString * name)89 void TypefaceFontStyleSet::getStyle(int index, SkFontStyle* style, SkString* name) {
90 SkASSERT(index < fStyles.size());
91 if (style) {
92 *style = fStyles[index]->fontStyle();
93 }
94 if (name) {
95 *name = fFamilyName;
96 }
97 }
98
createTypeface(int index)99 sk_sp<SkTypeface> TypefaceFontStyleSet::createTypeface(int index) {
100 SkASSERT(index < fStyles.size());
101 return fStyles[index];
102 }
103
matchStyle(const SkFontStyle & pattern)104 sk_sp<SkTypeface> TypefaceFontStyleSet::matchStyle(const SkFontStyle& pattern) {
105 return this->matchStyleCSS3(pattern);
106 }
107
appendTypeface(sk_sp<SkTypeface> typeface)108 void TypefaceFontStyleSet::appendTypeface(sk_sp<SkTypeface> typeface) {
109 if (typeface.get() != nullptr) {
110 fStyles.emplace_back(std::move(typeface));
111 }
112 }
113
114 } // namespace textlayout
115 } // namespace skia
116