Flutter Engine
The Flutter Engine
SkFontMgr.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
10#include "include/core/SkData.h"
15
16#include <utility>
17
18struct SkFontArguments;
19
21public:
22 int count() override { return 0; }
23 void getStyle(int, SkFontStyle*, SkString*) override {
24 SkDEBUGFAIL("SkFontStyleSet::getStyle called on empty set");
25 }
26 sk_sp<SkTypeface> createTypeface(int index) override {
27 SkDEBUGFAIL("SkFontStyleSet::createTypeface called on empty set");
28 return nullptr;
29 }
31 return nullptr;
32 }
33};
34
37}
38
39///////////////////////////////////////////////////////////////////////////////
40
41class SkEmptyFontMgr : public SkFontMgr {
42protected:
43 int onCountFamilies() const override {
44 return 0;
45 }
46 void onGetFamilyName(int index, SkString* familyName) const override {
47 SkDEBUGFAIL("onGetFamilyName called with bad index");
48 }
49 sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override {
50 SkDEBUGFAIL("onCreateStyleSet called with bad index");
51 return nullptr;
52 }
53 sk_sp<SkFontStyleSet> onMatchFamily(const char[]) const override {
55 }
56
57 sk_sp<SkTypeface> onMatchFamilyStyle(const char[], const SkFontStyle&) const override {
58 return nullptr;
59 }
61 const SkFontStyle& style,
62 const char* bcp47[],
63 int bcp47Count,
64 SkUnichar character) const override {
65 return nullptr;
66 }
67
69 return nullptr;
70 }
71 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>, int) const override {
72 return nullptr;
73 }
74 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
75 const SkFontArguments&) const override {
76 return nullptr;
77 }
78 sk_sp<SkTypeface> onMakeFromFile(const char[], int) const override {
79 return nullptr;
80 }
81 sk_sp<SkTypeface> onLegacyMakeTypeface(const char [], SkFontStyle) const override {
82 return nullptr;
83 }
84};
85
87 if (!fsset) {
89 }
90 return std::move(fsset);
91}
92
94 return this->onCountFamilies();
95}
96
97void SkFontMgr::getFamilyName(int index, SkString* familyName) const {
98 this->onGetFamilyName(index, familyName);
99}
100
102 return emptyOnNull(this->onCreateStyleSet(index));
103}
104
105sk_sp<SkFontStyleSet> SkFontMgr::matchFamily(const char familyName[]) const {
106 return emptyOnNull(this->onMatchFamily(familyName));
107}
108
110 const SkFontStyle& fs) const {
111 return this->onMatchFamilyStyle(familyName, fs);
112}
113
115 const char* bcp47[], int bcp47Count,
116 SkUnichar character) const {
117 return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, character);
118}
119
121 if (nullptr == data) {
122 return nullptr;
123 }
124 return this->onMakeFromData(std::move(data), ttcIndex);
125}
126
128 int ttcIndex) const {
129 if (nullptr == stream) {
130 return nullptr;
131 }
132 return this->onMakeFromStreamIndex(std::move(stream), ttcIndex);
133}
134
136 const SkFontArguments& args) const {
137 if (nullptr == stream) {
138 return nullptr;
139 }
140 return this->onMakeFromStreamArgs(std::move(stream), args);
141}
142
143sk_sp<SkTypeface> SkFontMgr::makeFromFile(const char path[], int ttcIndex) const {
144 if (nullptr == path) {
145 return nullptr;
146 }
147 return this->onMakeFromFile(path, ttcIndex);
148}
149
150sk_sp<SkTypeface> SkFontMgr::legacyMakeTypeface(const char familyName[], SkFontStyle style) const {
151 return this->onLegacyMakeTypeface(familyName, style);
152}
153
155 static sk_sp<SkFontMgr> singleton(new SkEmptyFontMgr);
156 return singleton;
157}
158
159/**
160* Width has the greatest priority.
161* If the value of pattern.width is 5 (normal) or less,
162* narrower width values are checked first, then wider values.
163* If the value of pattern.width is greater than 5 (normal),
164* wider values are checked first, followed by narrower values.
165*
166* Italic/Oblique has the next highest priority.
167* If italic requested and there is some italic font, use it.
168* If oblique requested and there is some oblique font, use it.
169* If italic requested and there is some oblique font, use it.
170* If oblique requested and there is some italic font, use it.
171*
172* Exact match.
173* If pattern.weight < 400, weights below pattern.weight are checked
174* in descending order followed by weights above pattern.weight
175* in ascending order until a match is found.
176* If pattern.weight > 500, weights above pattern.weight are checked
177* in ascending order followed by weights below pattern.weight
178* in descending order until a match is found.
179* If pattern.weight is 400, 500 is checked first
180* and then the rule for pattern.weight < 400 is used.
181* If pattern.weight is 500, 400 is checked first
182* and then the rule for pattern.weight < 400 is used.
183*/
185 int count = this->count();
186 if (0 == count) {
187 return nullptr;
188 }
189
190 struct Score {
191 int score;
192 int index;
193 Score& operator +=(int rhs) { this->score += rhs; return *this; }
194 Score& operator <<=(int rhs) { this->score <<= rhs; return *this; }
195 bool operator <(const Score& that) { return this->score < that.score; }
196 };
197
198 Score maxScore = { 0, 0 };
199 for (int i = 0; i < count; ++i) {
200 SkFontStyle current;
201 this->getStyle(i, &current, nullptr);
202 Score currentScore = { 0, i };
203
204 // CSS stretch / SkFontStyle::Width
205 // Takes priority over everything else.
206 if (pattern.width() <= SkFontStyle::kNormal_Width) {
207 if (current.width() <= pattern.width()) {
208 currentScore += 10 - pattern.width() + current.width();
209 } else {
210 currentScore += 10 - current.width();
211 }
212 } else {
213 if (current.width() > pattern.width()) {
214 currentScore += 10 + pattern.width() - current.width();
215 } else {
216 currentScore += current.width();
217 }
218 }
219 currentScore <<= 8;
220
221 // CSS style (normal, italic, oblique) / SkFontStyle::Slant (upright, italic, oblique)
222 // Takes priority over all valid weights.
223 static_assert(SkFontStyle::kUpright_Slant == 0 &&
226 "SkFontStyle::Slant values not as required.");
227 SkASSERT(0 <= pattern.slant() && pattern.slant() <= 2 &&
228 0 <= current.slant() && current.slant() <= 2);
229 static const int score[3][3] = {
230 /* Upright Italic Oblique [current]*/
231 /* Upright */ { 3 , 1 , 2 },
232 /* Italic */ { 1 , 3 , 2 },
233 /* Oblique */ { 1 , 2 , 3 },
234 /* [pattern] */
235 };
236 currentScore += score[pattern.slant()][current.slant()];
237 currentScore <<= 8;
238
239 // Synthetics (weight, style) [no stretch synthetic?]
240
241 // CSS weight / SkFontStyle::Weight
242 // The 'closer' to the target weight, the higher the score.
243 // 1000 is the 'heaviest' recognized weight
244 if (pattern.weight() == current.weight()) {
245 currentScore += 1000;
246 // less than 400 prefer lighter weights
247 } else if (pattern.weight() < 400) {
248 if (current.weight() <= pattern.weight()) {
249 currentScore += 1000 - pattern.weight() + current.weight();
250 } else {
251 currentScore += 1000 - current.weight();
252 }
253 // between 400 and 500 prefer heavier up to 500, then lighter weights
254 } else if (pattern.weight() <= 500) {
255 if (current.weight() >= pattern.weight() && current.weight() <= 500) {
256 currentScore += 1000 + pattern.weight() - current.weight();
257 } else if (current.weight() <= pattern.weight()) {
258 currentScore += 500 + current.weight();
259 } else {
260 currentScore += 1000 - current.weight();
261 }
262 // greater than 500 prefer heavier weights
263 } else if (pattern.weight() > 500) {
264 if (current.weight() > pattern.weight()) {
265 currentScore += 1000 + pattern.weight() - current.weight();
266 } else {
267 currentScore += current.weight();
268 }
269 }
270
271 if (maxScore < currentScore) {
272 maxScore = currentScore;
273 }
274 }
275
276 return this->createTypeface(maxScore.index);
277}
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
#define SkASSERT(cond)
Definition: SkAssert.h:116
static sk_sp< SkFontStyleSet > emptyOnNull(sk_sp< SkFontStyleSet > &&fsset)
Definition: SkFontMgr.cpp:86
int32_t SkUnichar
Definition: SkTypes.h:175
sk_sp< SkTypeface > onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &style, const char *bcp47[], int bcp47Count, SkUnichar character) const override
Definition: SkFontMgr.cpp:60
sk_sp< SkTypeface > onMakeFromData(sk_sp< SkData >, int) const override
Definition: SkFontMgr.cpp:68
sk_sp< SkTypeface > onMakeFromStreamIndex(std::unique_ptr< SkStreamAsset >, int) const override
Definition: SkFontMgr.cpp:71
sk_sp< SkTypeface > onMakeFromFile(const char[], int) const override
Definition: SkFontMgr.cpp:78
sk_sp< SkTypeface > onMatchFamilyStyle(const char[], const SkFontStyle &) const override
Definition: SkFontMgr.cpp:57
void onGetFamilyName(int index, SkString *familyName) const override
Definition: SkFontMgr.cpp:46
sk_sp< SkFontStyleSet > onCreateStyleSet(int index) const override
Definition: SkFontMgr.cpp:49
sk_sp< SkFontStyleSet > onMatchFamily(const char[]) const override
Definition: SkFontMgr.cpp:53
int onCountFamilies() const override
Definition: SkFontMgr.cpp:43
sk_sp< SkTypeface > onLegacyMakeTypeface(const char[], SkFontStyle) const override
Definition: SkFontMgr.cpp:81
sk_sp< SkTypeface > onMakeFromStreamArgs(std::unique_ptr< SkStreamAsset >, const SkFontArguments &) const override
Definition: SkFontMgr.cpp:74
sk_sp< SkTypeface > matchStyle(const SkFontStyle &) override
Definition: SkFontMgr.cpp:30
void getStyle(int, SkFontStyle *, SkString *) override
Definition: SkFontMgr.cpp:23
int count() override
Definition: SkFontMgr.cpp:22
sk_sp< SkTypeface > createTypeface(int index) override
Definition: SkFontMgr.cpp:26
sk_sp< SkFontStyleSet > createStyleSet(int index) const
Definition: SkFontMgr.cpp:101
sk_sp< SkTypeface > matchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, const char *bcp47[], int bcp47Count, SkUnichar character) const
Definition: SkFontMgr.cpp:114
static sk_sp< SkFontMgr > RefEmpty()
Definition: SkFontMgr.cpp:154
sk_sp< SkTypeface > makeFromFile(const char path[], int ttcIndex=0) const
Definition: SkFontMgr.cpp:143
virtual void onGetFamilyName(int index, SkString *familyName) const =0
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:127
void getFamilyName(int index, SkString *familyName) const
Definition: SkFontMgr.cpp:97
sk_sp< SkTypeface > makeFromData(sk_sp< SkData >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:120
sk_sp< SkFontStyleSet > matchFamily(const char familyName[]) const
Definition: SkFontMgr.cpp:105
virtual sk_sp< SkTypeface > onMakeFromData(sk_sp< SkData >, int ttcIndex) const =0
virtual sk_sp< SkFontStyleSet > onCreateStyleSet(int index) const =0
int countFamilies() const
Definition: SkFontMgr.cpp:93
virtual sk_sp< SkTypeface > onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, const char *bcp47[], int bcp47Count, SkUnichar character) const =0
virtual sk_sp< SkFontStyleSet > onMatchFamily(const char familyName[]) const =0
virtual sk_sp< SkTypeface > onMakeFromStreamIndex(std::unique_ptr< SkStreamAsset >, int ttcIndex) const =0
sk_sp< SkTypeface > legacyMakeTypeface(const char familyName[], SkFontStyle style) const
Definition: SkFontMgr.cpp:150
virtual sk_sp< SkTypeface > onMakeFromStreamArgs(std::unique_ptr< SkStreamAsset >, const SkFontArguments &) const =0
sk_sp< SkTypeface > matchFamilyStyle(const char familyName[], const SkFontStyle &) const
Definition: SkFontMgr.cpp:109
virtual sk_sp< SkTypeface > onMatchFamilyStyle(const char familyName[], const SkFontStyle &) const =0
virtual sk_sp< SkTypeface > onLegacyMakeTypeface(const char familyName[], SkFontStyle) const =0
virtual sk_sp< SkTypeface > onMakeFromFile(const char path[], int ttcIndex) const =0
virtual int onCountFamilies() const =0
static sk_sp< SkFontStyleSet > CreateEmpty()
Definition: SkFontMgr.cpp:35
sk_sp< SkTypeface > matchStyleCSS3(const SkFontStyle &pattern)
Definition: SkFontMgr.cpp:184
virtual sk_sp< SkTypeface > createTypeface(int index)=0
virtual int count()=0
virtual void getStyle(int index, SkFontStyle *, SkString *style)=0
Slant slant() const
Definition: SkFontStyle.h:64
int width() const
Definition: SkFontStyle.h:63
int weight() const
Definition: SkFontStyle.h:62
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
constexpr bool operator<(const EnumType &lhs, const Mask< EnumType > &rhs)
Definition: mask.h:188
SINT Vec< N, T > & operator+=(Vec< N, T > &x, const Vec< N, T > &y)
Definition: SkVx.h:450
SINT Vec< N, T > & operator<<=(Vec< N, T > &x, int bits)
Definition: SkVx.h:466
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63