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/base/SkTArray.h"
17 #include "include/private/base/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 using namespace skia_private;
26
27 class SkData;
28
SkTypeface_Custom(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,int index)29 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
30 bool sysFont, const SkString familyName, int index)
31 : INHERITED(style, isFixedPitch)
32 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
33 { }
34
isSysFont() const35 bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
36
onGetFamilyName(SkString * familyName) const37 void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
38 *familyName = fFamilyName;
39 }
40
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const41 void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
42 desc->setFamilyName(fFamilyName.c_str());
43 desc->setStyle(this->fontStyle());
44 desc->setFactoryId(SkTypeface_FreeType::FactoryId);
45 *isLocal = !this->isSysFont();
46 }
47
getIndex() const48 int SkTypeface_Custom::getIndex() const { return fIndex; }
49
50
SkTypeface_Empty()51 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
52
onOpenStream(int *) const53 std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
54
onMakeClone(const SkFontArguments & args) const55 sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
56 return sk_ref_sp(this);
57 }
58
onMakeFontData() const59 std::unique_ptr<SkFontData> SkTypeface_Empty::onMakeFontData() const { return nullptr; }
60
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,const char path[],int index)61 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
62 const SkString familyName, const char path[], int index)
63 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
64 , fPath(path)
65 { }
66
onOpenStream(int * ttcIndex) const67 std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
68 *ttcIndex = this->getIndex();
69 return SkStream::MakeFromFile(fPath.c_str());
70 }
71
onMakeClone(const SkFontArguments & args) const72 sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
73 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
74 if (!data) {
75 return nullptr;
76 }
77
78 SkString familyName;
79 this->getFamilyName(&familyName);
80
81 return sk_make_sp<SkTypeface_FreeTypeStream>(std::move(data),
82 familyName,
83 this->fontStyle(),
84 this->isFixedPitch());
85 }
86
onMakeFontData() const87 std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
88 int index;
89 std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
90 if (!stream) {
91 return nullptr;
92 }
93 return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
94 }
95
96 ///////////////////////////////////////////////////////////////////////////////
97
SkFontStyleSet_Custom(const SkString familyName)98 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
99
appendTypeface(sk_sp<SkTypeface> typeface)100 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface> typeface) {
101 fStyles.emplace_back(std::move(typeface));
102 }
103
count()104 int SkFontStyleSet_Custom::count() {
105 return fStyles.size();
106 }
107
getStyle(int index,SkFontStyle * style,SkString * name)108 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
109 SkASSERT(index < fStyles.size());
110 if (style) {
111 *style = fStyles[index]->fontStyle();
112 }
113 if (name) {
114 name->reset();
115 }
116 }
117
createTypeface(int index)118 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
119 SkASSERT(index < fStyles.size());
120 return SkRef(fStyles[index].get());
121 }
122
matchStyle(const SkFontStyle & pattern)123 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
124 return this->matchStyleCSS3(pattern);
125 }
126
getFamilyName()127 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
128
129
SkFontMgr_Custom(const SystemFontLoader & loader)130 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
131 loader.loadSystemFonts(fScanner, &fFamilies);
132
133 // Try to pick a default font.
134 static const char* defaultNames[] = {
135 "Arial", "Verdana", "Times New Roman", "Droid Sans", "DejaVu Serif", nullptr
136 };
137 for (size_t i = 0; i < std::size(defaultNames); ++i) {
138 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
139 if (nullptr == set) {
140 continue;
141 }
142
143 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
144 SkFontStyle::kNormal_Width,
145 SkFontStyle::kUpright_Slant)));
146 if (nullptr == tf) {
147 continue;
148 }
149
150 fDefaultFamily = set.get();
151 break;
152 }
153 if (nullptr == fDefaultFamily) {
154 fDefaultFamily = fFamilies[0].get();
155 }
156 }
157
onCountFamilies() const158 int SkFontMgr_Custom::onCountFamilies() const {
159 return fFamilies.size();
160 }
161
onGetFamilyName(int index,SkString * familyName) const162 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
163 SkASSERT(index < fFamilies.size());
164 familyName->set(fFamilies[index]->getFamilyName());
165 }
166
onCreateStyleSet(int index) const167 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
168 SkASSERT(index < fFamilies.size());
169 return SkRef(fFamilies[index].get());
170 }
171
onMatchFamily(const char familyName[]) const172 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
173 for (int i = 0; i < fFamilies.size(); ++i) {
174 if (fFamilies[i]->getFamilyName().equals(familyName)) {
175 return SkRef(fFamilies[i].get());
176 }
177 }
178 return nullptr;
179 }
180
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const181 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
182 const SkFontStyle& fontStyle) const
183 {
184 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
185 return sset->matchStyle(fontStyle);
186 }
187
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar character) const188 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
189 const SkFontStyle&,
190 const char* bcp47[], int bcp47Count,
191 SkUnichar character) const
192 {
193 return nullptr;
194 }
195
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const196 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
197 return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
198 }
199
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const200 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
201 int ttcIndex) const {
202 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
203 }
204
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const205 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
206 const SkFontArguments& args) const {
207 return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
208 }
209
onMakeFromFile(const char path[],int ttcIndex) const210 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
211 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
212 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
213 }
214
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const215 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
216 SkFontStyle style) const {
217 sk_sp<SkTypeface> tf;
218
219 if (familyName) {
220 tf.reset(this->onMatchFamilyStyle(familyName, style));
221 }
222
223 if (nullptr == tf) {
224 tf.reset(fDefaultFamily->matchStyle(style));
225 }
226
227 return tf;
228 }
229