1 | /* |
2 | * Copyright 2006 The Android Open Source Project |
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 | |
8 | #include "include/core/SkFontArguments.h" |
9 | #include "include/core/SkFontMgr.h" |
10 | #include "include/core/SkFontStyle.h" |
11 | #include "include/core/SkRefCnt.h" |
12 | #include "include/core/SkStream.h" |
13 | #include "include/core/SkString.h" |
14 | #include "include/core/SkTypeface.h" |
15 | #include "include/core/SkTypes.h" |
16 | #include "include/private/SkTArray.h" |
17 | #include "include/private/SkTemplates.h" |
18 | #include "src/core/SkFontDescriptor.h" |
19 | #include "src/ports/SkFontHost_FreeType_common.h" |
20 | #include "src/ports/SkFontMgr_custom.h" |
21 | |
22 | #include <limits> |
23 | #include <memory> |
24 | |
25 | class SkData; |
26 | |
27 | SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch, |
28 | bool sysFont, const SkString familyName, int index) |
29 | : INHERITED(style, isFixedPitch) |
30 | , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index) |
31 | { } |
32 | |
33 | bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; } |
34 | |
35 | void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const { |
36 | *familyName = fFamilyName; |
37 | } |
38 | |
39 | void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const { |
40 | desc->setFamilyName(fFamilyName.c_str()); |
41 | desc->setStyle(this->fontStyle()); |
42 | *isLocal = !this->isSysFont(); |
43 | } |
44 | |
45 | int SkTypeface_Custom::getIndex() const { return fIndex; } |
46 | |
47 | |
48 | SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {} |
49 | |
50 | std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; } |
51 | |
52 | sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const { |
53 | return sk_ref_sp(this); |
54 | } |
55 | |
56 | std::unique_ptr<SkFontData> SkTypeface_Empty::onMakeFontData() const { return nullptr; } |
57 | |
58 | SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData, |
59 | const SkFontStyle& style, bool isFixedPitch, bool sysFont, |
60 | const SkString familyName) |
61 | : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex()) |
62 | , fData(std::move(fontData)) |
63 | { } |
64 | |
65 | std::unique_ptr<SkStreamAsset> SkTypeface_Stream::onOpenStream(int* ttcIndex) const { |
66 | *ttcIndex = fData->getIndex(); |
67 | return fData->getStream()->duplicate(); |
68 | } |
69 | |
70 | std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const { |
71 | return std::make_unique<SkFontData>(*fData); |
72 | } |
73 | |
74 | sk_sp<SkTypeface> SkTypeface_Stream::onMakeClone(const SkFontArguments& args) const { |
75 | std::unique_ptr<SkFontData> data = this->cloneFontData(args); |
76 | if (!data) { |
77 | return nullptr; |
78 | } |
79 | |
80 | SkString familyName; |
81 | this->getFamilyName(&familyName); |
82 | |
83 | return sk_make_sp<SkTypeface_Stream>(std::move(data), |
84 | this->fontStyle(), |
85 | this->isFixedPitch(), |
86 | this->isSysFont(), |
87 | familyName); |
88 | } |
89 | |
90 | SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont, |
91 | const SkString familyName, const char path[], int index) |
92 | : INHERITED(style, isFixedPitch, sysFont, familyName, index) |
93 | , fPath(path) |
94 | { } |
95 | |
96 | std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const { |
97 | *ttcIndex = this->getIndex(); |
98 | return SkStream::MakeFromFile(fPath.c_str()); |
99 | } |
100 | |
101 | sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const { |
102 | std::unique_ptr<SkFontData> data = this->cloneFontData(args); |
103 | if (!data) { |
104 | return nullptr; |
105 | } |
106 | |
107 | SkString familyName; |
108 | this->getFamilyName(&familyName); |
109 | |
110 | return sk_make_sp<SkTypeface_Stream>(std::move(data), |
111 | this->fontStyle(), |
112 | this->isFixedPitch(), |
113 | this->isSysFont(), |
114 | familyName); |
115 | } |
116 | |
117 | std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const { |
118 | int index; |
119 | std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index)); |
120 | if (!stream) { |
121 | return nullptr; |
122 | } |
123 | return std::make_unique<SkFontData>(std::move(stream), index, nullptr, 0); |
124 | } |
125 | |
126 | /////////////////////////////////////////////////////////////////////////////// |
127 | |
128 | SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {} |
129 | |
130 | void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) { |
131 | fStyles.emplace_back(std::move(typeface)); |
132 | } |
133 | |
134 | int SkFontStyleSet_Custom::count() { |
135 | return fStyles.count(); |
136 | } |
137 | |
138 | void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) { |
139 | SkASSERT(index < fStyles.count()); |
140 | if (style) { |
141 | *style = fStyles[index]->fontStyle(); |
142 | } |
143 | if (name) { |
144 | name->reset(); |
145 | } |
146 | } |
147 | |
148 | SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) { |
149 | SkASSERT(index < fStyles.count()); |
150 | return SkRef(fStyles[index].get()); |
151 | } |
152 | |
153 | SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) { |
154 | return this->matchStyleCSS3(pattern); |
155 | } |
156 | |
157 | SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; } |
158 | |
159 | |
160 | SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) { |
161 | loader.loadSystemFonts(fScanner, &fFamilies); |
162 | |
163 | // Try to pick a default font. |
164 | static const char* defaultNames[] = { |
165 | "Arial" , "Verdana" , "Times New Roman" , "Droid Sans" , nullptr |
166 | }; |
167 | for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) { |
168 | sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i])); |
169 | if (nullptr == set) { |
170 | continue; |
171 | } |
172 | |
173 | sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight, |
174 | SkFontStyle::kNormal_Width, |
175 | SkFontStyle::kUpright_Slant))); |
176 | if (nullptr == tf) { |
177 | continue; |
178 | } |
179 | |
180 | fDefaultFamily = set.get(); |
181 | break; |
182 | } |
183 | if (nullptr == fDefaultFamily) { |
184 | fDefaultFamily = fFamilies[0].get(); |
185 | } |
186 | } |
187 | |
188 | int SkFontMgr_Custom::onCountFamilies() const { |
189 | return fFamilies.count(); |
190 | } |
191 | |
192 | void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const { |
193 | SkASSERT(index < fFamilies.count()); |
194 | familyName->set(fFamilies[index]->getFamilyName()); |
195 | } |
196 | |
197 | SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const { |
198 | SkASSERT(index < fFamilies.count()); |
199 | return SkRef(fFamilies[index].get()); |
200 | } |
201 | |
202 | SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const { |
203 | for (int i = 0; i < fFamilies.count(); ++i) { |
204 | if (fFamilies[i]->getFamilyName().equals(familyName)) { |
205 | return SkRef(fFamilies[i].get()); |
206 | } |
207 | } |
208 | return nullptr; |
209 | } |
210 | |
211 | SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[], |
212 | const SkFontStyle& fontStyle) const |
213 | { |
214 | sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName)); |
215 | return sset->matchStyle(fontStyle); |
216 | } |
217 | |
218 | SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[], |
219 | const SkFontStyle&, |
220 | const char* bcp47[], int bcp47Count, |
221 | SkUnichar character) const |
222 | { |
223 | return nullptr; |
224 | } |
225 | |
226 | SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember, |
227 | const SkFontStyle& fontStyle) const |
228 | { |
229 | for (int i = 0; i < fFamilies.count(); ++i) { |
230 | for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) { |
231 | if (fFamilies[i]->fStyles[j].get() == familyMember) { |
232 | return fFamilies[i]->matchStyle(fontStyle); |
233 | } |
234 | } |
235 | } |
236 | return nullptr; |
237 | } |
238 | |
239 | sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const { |
240 | return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex); |
241 | } |
242 | |
243 | sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, |
244 | int ttcIndex) const { |
245 | return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex)); |
246 | } |
247 | |
248 | sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, |
249 | const SkFontArguments& args) const { |
250 | using Scanner = SkTypeface_FreeType::Scanner; |
251 | bool isFixedPitch; |
252 | SkFontStyle style; |
253 | SkString name; |
254 | Scanner::AxisDefinitions axisDefinitions; |
255 | if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), |
256 | &name, &style, &isFixedPitch, &axisDefinitions)) |
257 | { |
258 | return nullptr; |
259 | } |
260 | |
261 | const SkFontArguments::VariationPosition position = args.getVariationDesignPosition(); |
262 | SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); |
263 | Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); |
264 | |
265 | auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), |
266 | axisValues.get(), axisDefinitions.count()); |
267 | return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name)); |
268 | } |
269 | |
270 | sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const { |
271 | bool isFixedPitch; |
272 | SkFontStyle style; |
273 | SkString name; |
274 | if (!fScanner.scanFont(data->getStream(), data->getIndex(), |
275 | &name, &style, &isFixedPitch, nullptr)) { |
276 | return nullptr; |
277 | } |
278 | return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name)); |
279 | } |
280 | |
281 | sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const { |
282 | std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path); |
283 | return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr; |
284 | } |
285 | |
286 | sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[], |
287 | SkFontStyle style) const { |
288 | sk_sp<SkTypeface> tf; |
289 | |
290 | if (familyName) { |
291 | tf.reset(this->onMatchFamilyStyle(familyName, style)); |
292 | } |
293 | |
294 | if (nullptr == tf) { |
295 | tf.reset(fDefaultFamily->matchStyle(style)); |
296 | } |
297 | |
298 | return tf; |
299 | } |
300 | |