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 "SkFontArguments.h"
9 #include "SkFontDescriptor.h"
10 #include "SkFontHost_FreeType_common.h"
11 #include "SkFontMgr.h"
12 #include "SkFontMgr_custom.h"
13 #include "SkFontStyle.h"
14 #include "SkMakeUnique.h"
15 #include "SkRefCnt.h"
16 #include "SkStream.h"
17 #include "SkString.h"
18 #include "SkTArray.h"
19 #include "SkTemplates.h"
20 #include "SkTypeface.h"
21 #include "SkTypes.h"
22
23 #include <limits>
24 #include <memory>
25
26 class SkData;
27
SkTypeface_Custom(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,int index)28 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
29 bool sysFont, const SkString familyName, int index)
30 : INHERITED(style, isFixedPitch)
31 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
32 { }
33
isSysFont() const34 bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
35
onGetFamilyName(SkString * familyName) const36 void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
37 *familyName = fFamilyName;
38 }
39
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const40 void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
41 desc->setFamilyName(fFamilyName.c_str());
42 desc->setStyle(this->fontStyle());
43 *isLocal = !this->isSysFont();
44 }
45
getIndex() const46 int SkTypeface_Custom::getIndex() const { return fIndex; }
47
48
SkTypeface_Empty()49 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
50
onOpenStream(int *) const51 SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
52
53
SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName)54 SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
55 const SkFontStyle& style, bool isFixedPitch, bool sysFont,
56 const SkString familyName)
57 : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
58 , fData(std::move(fontData))
59 { }
60
onOpenStream(int * ttcIndex) const61 SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
62 *ttcIndex = fData->getIndex();
63 return fData->getStream()->duplicate();
64 }
65
onMakeFontData() const66 std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
67 return skstd::make_unique<SkFontData>(*fData);
68 }
69
70
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,const char path[],int index)71 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
72 const SkString familyName, const char path[], int index)
73 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
74 , fPath(path)
75 { }
76
onOpenStream(int * ttcIndex) const77 SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
78 *ttcIndex = this->getIndex();
79 return SkStream::MakeFromFile(fPath.c_str()).release();
80 }
81
82 ///////////////////////////////////////////////////////////////////////////////
83
SkFontStyleSet_Custom(const SkString familyName)84 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
85
appendTypeface(sk_sp<SkTypeface_Custom> typeface)86 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
87 fStyles.emplace_back(std::move(typeface));
88 }
89
count()90 int SkFontStyleSet_Custom::count() {
91 return fStyles.count();
92 }
93
getStyle(int index,SkFontStyle * style,SkString * name)94 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
95 SkASSERT(index < fStyles.count());
96 if (style) {
97 *style = fStyles[index]->fontStyle();
98 }
99 if (name) {
100 name->reset();
101 }
102 }
103
createTypeface(int index)104 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
105 SkASSERT(index < fStyles.count());
106 return SkRef(fStyles[index].get());
107 }
108
matchStyle(const SkFontStyle & pattern)109 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
110 return this->matchStyleCSS3(pattern);
111 }
112
getFamilyName()113 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
114
115
SkFontMgr_Custom(const SystemFontLoader & loader)116 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
117 loader.loadSystemFonts(fScanner, &fFamilies);
118
119 // Try to pick a default font.
120 static const char* defaultNames[] = {
121 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
122 };
123 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
124 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
125 if (nullptr == set) {
126 continue;
127 }
128
129 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
130 SkFontStyle::kNormal_Width,
131 SkFontStyle::kUpright_Slant)));
132 if (nullptr == tf) {
133 continue;
134 }
135
136 fDefaultFamily = set.get();
137 break;
138 }
139 if (nullptr == fDefaultFamily) {
140 fDefaultFamily = fFamilies[0].get();
141 }
142 }
143
onCountFamilies() const144 int SkFontMgr_Custom::onCountFamilies() const {
145 return fFamilies.count();
146 }
147
onGetFamilyName(int index,SkString * familyName) const148 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
149 SkASSERT(index < fFamilies.count());
150 familyName->set(fFamilies[index]->getFamilyName());
151 }
152
onCreateStyleSet(int index) const153 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
154 SkASSERT(index < fFamilies.count());
155 return SkRef(fFamilies[index].get());
156 }
157
onMatchFamily(const char familyName[]) const158 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
159 for (int i = 0; i < fFamilies.count(); ++i) {
160 if (fFamilies[i]->getFamilyName().equals(familyName)) {
161 return SkRef(fFamilies[i].get());
162 }
163 }
164 return nullptr;
165 }
166
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const167 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
168 const SkFontStyle& fontStyle) const
169 {
170 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
171 return sset->matchStyle(fontStyle);
172 }
173
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar character) const174 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
175 const SkFontStyle&,
176 const char* bcp47[], int bcp47Count,
177 SkUnichar character) const
178 {
179 return nullptr;
180 }
181
onMatchFaceStyle(const SkTypeface * familyMember,const SkFontStyle & fontStyle) const182 SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
183 const SkFontStyle& fontStyle) const
184 {
185 for (int i = 0; i < fFamilies.count(); ++i) {
186 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
187 if (fFamilies[i]->fStyles[j].get() == familyMember) {
188 return fFamilies[i]->matchStyle(fontStyle);
189 }
190 }
191 }
192 return nullptr;
193 }
194
onCreateFromData(SkData * data,int ttcIndex) const195 SkTypeface* SkFontMgr_Custom::onCreateFromData(SkData* data, int ttcIndex) const {
196 return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
197 }
198
onCreateFromStream(SkStreamAsset * bareStream,int ttcIndex) const199 SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const {
200 return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
201 }
202
onCreateFromStream(SkStreamAsset * s,const SkFontArguments & args) const203 SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s,
204 const SkFontArguments& args) const
205 {
206 using Scanner = SkTypeface_FreeType::Scanner;
207 std::unique_ptr<SkStreamAsset> stream(s);
208 bool isFixedPitch;
209 SkFontStyle style;
210 SkString name;
211 Scanner::AxisDefinitions axisDefinitions;
212 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
213 &name, &style, &isFixedPitch, &axisDefinitions))
214 {
215 return nullptr;
216 }
217
218 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
219 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
220 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
221
222 auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
223 axisValues.get(), axisDefinitions.count());
224 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
225 }
226
onCreateFromFontData(std::unique_ptr<SkFontData> data) const227 SkTypeface* SkFontMgr_Custom::onCreateFromFontData(std::unique_ptr<SkFontData> data) const {
228 bool isFixedPitch;
229 SkFontStyle style;
230 SkString name;
231 if (!fScanner.scanFont(data->getStream(), data->getIndex(),
232 &name, &style, &isFixedPitch, nullptr))
233 {
234 return nullptr;
235 }
236 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
237 }
238
onCreateFromFile(const char path[],int ttcIndex) const239 SkTypeface* SkFontMgr_Custom::onCreateFromFile(const char path[], int ttcIndex) const {
240 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
241 return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
242 }
243
onLegacyCreateTypeface(const char familyName[],SkFontStyle style) const244 SkTypeface* SkFontMgr_Custom::onLegacyCreateTypeface(const char familyName[],
245 SkFontStyle style) const
246 {
247 SkTypeface* tf = nullptr;
248
249 if (familyName) {
250 tf = this->onMatchFamilyStyle(familyName, style);
251 }
252
253 if (nullptr == tf) {
254 tf = fDefaultFamily->matchStyle(style);
255 }
256
257 return tf;
258 }
259