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
SkTypeface_Custom(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,int index)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
isSysFont() const33 bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
34
onGetFamilyName(SkString * familyName) const35 void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
36 *familyName = fFamilyName;
37 }
38
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const39 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
getIndex() const45 int SkTypeface_Custom::getIndex() const { return fIndex; }
46
47
SkTypeface_Empty()48 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
49
onOpenStream(int *) const50 std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
51
onMakeClone(const SkFontArguments & args) const52 sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
53 return sk_ref_sp(this);
54 }
55
onMakeFontData() const56 std::unique_ptr<SkFontData> SkTypeface_Empty::onMakeFontData() const { return nullptr; }
57
SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName)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
onOpenStream(int * ttcIndex) const65 std::unique_ptr<SkStreamAsset> SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
66 *ttcIndex = fData->getIndex();
67 return fData->getStream()->duplicate();
68 }
69
onMakeFontData() const70 std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
71 return std::make_unique<SkFontData>(*fData);
72 }
73
onMakeClone(const SkFontArguments & args) const74 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
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const90 void SkTypeface_Stream::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
91 this->SkTypeface_Custom::onGetFontDescriptor(desc, isLocal);
92 SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fData, desc);
93 }
94
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,const char path[],int index)95 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
96 const SkString familyName, const char path[], int index)
97 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
98 , fPath(path)
99 { }
100
onOpenStream(int * ttcIndex) const101 std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
102 *ttcIndex = this->getIndex();
103 return SkStream::MakeFromFile(fPath.c_str());
104 }
105
onMakeClone(const SkFontArguments & args) const106 sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
107 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
108 if (!data) {
109 return nullptr;
110 }
111
112 SkString familyName;
113 this->getFamilyName(&familyName);
114
115 return sk_make_sp<SkTypeface_Stream>(std::move(data),
116 this->fontStyle(),
117 this->isFixedPitch(),
118 this->isSysFont(),
119 familyName);
120 }
121
onMakeFontData() const122 std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
123 int index;
124 std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
125 if (!stream) {
126 return nullptr;
127 }
128 return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
129 }
130
131 ///////////////////////////////////////////////////////////////////////////////
132
SkFontStyleSet_Custom(const SkString familyName)133 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
134
appendTypeface(sk_sp<SkTypeface_Custom> typeface)135 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
136 fStyles.emplace_back(std::move(typeface));
137 }
138
count()139 int SkFontStyleSet_Custom::count() {
140 return fStyles.count();
141 }
142
getStyle(int index,SkFontStyle * style,SkString * name)143 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
144 SkASSERT(index < fStyles.count());
145 if (style) {
146 *style = fStyles[index]->fontStyle();
147 }
148 if (name) {
149 name->reset();
150 }
151 }
152
createTypeface(int index)153 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
154 SkASSERT(index < fStyles.count());
155 return SkRef(fStyles[index].get());
156 }
157
matchStyle(const SkFontStyle & pattern)158 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
159 return this->matchStyleCSS3(pattern);
160 }
161
getFamilyName()162 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
163
164
SkFontMgr_Custom(const SystemFontLoader & loader)165 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
166 loader.loadSystemFonts(fScanner, &fFamilies);
167
168 // Try to pick a default font.
169 static const char* defaultNames[] = {
170 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
171 };
172 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
173 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
174 if (nullptr == set) {
175 continue;
176 }
177
178 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
179 SkFontStyle::kNormal_Width,
180 SkFontStyle::kUpright_Slant)));
181 if (nullptr == tf) {
182 continue;
183 }
184
185 fDefaultFamily = set.get();
186 break;
187 }
188 if (nullptr == fDefaultFamily) {
189 fDefaultFamily = fFamilies[0].get();
190 }
191 }
192
onCountFamilies() const193 int SkFontMgr_Custom::onCountFamilies() const {
194 return fFamilies.count();
195 }
196
onGetFamilyName(int index,SkString * familyName) const197 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
198 SkASSERT(index < fFamilies.count());
199 familyName->set(fFamilies[index]->getFamilyName());
200 }
201
onCreateStyleSet(int index) const202 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
203 SkASSERT(index < fFamilies.count());
204 return SkRef(fFamilies[index].get());
205 }
206
onMatchFamily(const char familyName[]) const207 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
208 for (int i = 0; i < fFamilies.count(); ++i) {
209 if (fFamilies[i]->getFamilyName().equals(familyName)) {
210 return SkRef(fFamilies[i].get());
211 }
212 }
213 return nullptr;
214 }
215
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const216 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
217 const SkFontStyle& fontStyle) const
218 {
219 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
220 return sset->matchStyle(fontStyle);
221 }
222
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar character) const223 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
224 const SkFontStyle&,
225 const char* bcp47[], int bcp47Count,
226 SkUnichar character) const
227 {
228 return nullptr;
229 }
230
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const231 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
232 return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
233 }
234
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const235 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
236 int ttcIndex) const {
237 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
238 }
239
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const240 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
241 const SkFontArguments& args) const {
242 using Scanner = SkTypeface_FreeType::Scanner;
243 bool isFixedPitch;
244 SkFontStyle style;
245 SkString name;
246 Scanner::AxisDefinitions axisDefinitions;
247 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
248 &name, &style, &isFixedPitch, &axisDefinitions)) {
249 return nullptr;
250 }
251
252 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
253 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
254 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
255
256 auto data = std::make_unique<SkFontData>(
257 std::move(stream), args.getCollectionIndex(), args.getPalette().index,
258 axisValues.get(), axisDefinitions.count(),
259 args.getPalette().overrides, args.getPalette().overrideCount);
260 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
261 }
262
onMakeFromFile(const char path[],int ttcIndex) const263 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
264 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
265 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
266 }
267
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const268 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
269 SkFontStyle style) const {
270 sk_sp<SkTypeface> tf;
271
272 if (familyName) {
273 tf.reset(this->onMatchFamilyStyle(familyName, style));
274 }
275
276 if (nullptr == tf) {
277 tf.reset(fDefaultFamily->matchStyle(style));
278 }
279
280 return tf;
281 }
282