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/ports/SkFontScanner_FreeType.h"
17 #include "include/private/base/SkTArray.h"
18 #include "include/private/base/SkTemplates.h"
19 #include "src/core/SkFontDescriptor.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,SkString familyName,int index)29 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
30 bool sysFont, SkString familyName, int index)
31 : INHERITED(style, isFixedPitch)
32 , fIsSysFont(sysFont), fFamilyName(std::move(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,SkString familyName,const char path[],int index)61 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
62 SkString familyName, const char path[], int index)
63 : INHERITED(style, isFixedPitch, sysFont, std::move(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 SkFontStyle style = this->fontStyle();
74 std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
75 if (!data) {
76 return nullptr;
77 }
78
79 SkString familyName;
80 this->getFamilyName(&familyName);
81
82 return sk_make_sp<SkTypeface_FreeTypeStream>(
83 std::move(data), familyName, style, this->isFixedPitch());
84 }
85
onMakeFontData() const86 std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
87 int index;
88 std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
89 if (!stream) {
90 return nullptr;
91 }
92 return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
93 }
94
95 ///////////////////////////////////////////////////////////////////////////////
96
SkFontStyleSet_Custom(SkString familyName)97 SkFontStyleSet_Custom::SkFontStyleSet_Custom(SkString familyName)
98 : fFamilyName(std::move(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 sk_sp<SkTypeface> SkFontStyleSet_Custom::createTypeface(int index) {
119 SkASSERT(index < fStyles.size());
120 return fStyles[index];
121 }
122
matchStyle(const SkFontStyle & pattern)123 sk_sp<SkTypeface> SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
124 return this->matchStyleCSS3(pattern);
125 }
126
getFamilyName()127 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
128
SkFontMgr_Custom(const SystemFontLoader & loader)129 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader)
130 : fDefaultFamily(nullptr)
131 , fScanner(SkFontScanner_Make_FreeType()) {
132
133 loader.loadSystemFonts(fScanner.get(), &fFamilies);
134
135 // Try to pick a default font.
136 static const char* defaultNames[] = {
137 "Arial", "Verdana", "Times New Roman", "Droid Sans", "DejaVu Serif", nullptr
138 };
139 for (size_t i = 0; i < std::size(defaultNames); ++i) {
140 sk_sp<SkFontStyleSet> set(this->onMatchFamily(defaultNames[i]));
141 if (nullptr == set) {
142 continue;
143 }
144
145 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
146 SkFontStyle::kNormal_Width,
147 SkFontStyle::kUpright_Slant)));
148 if (nullptr == tf) {
149 continue;
150 }
151
152 fDefaultFamily = set;
153 break;
154 }
155 if (nullptr == fDefaultFamily) {
156 fDefaultFamily = fFamilies[0];
157 }
158 }
159
onCountFamilies() const160 int SkFontMgr_Custom::onCountFamilies() const {
161 return fFamilies.size();
162 }
163
onGetFamilyName(int index,SkString * familyName) const164 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
165 SkASSERT(index < fFamilies.size());
166 familyName->set(fFamilies[index]->getFamilyName());
167 }
168
onCreateStyleSet(int index) const169 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onCreateStyleSet(int index) const {
170 SkASSERT(index < fFamilies.size());
171 return fFamilies[index];
172 }
173
onMatchFamily(const char familyName[]) const174 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
175 for (int i = 0; i < fFamilies.size(); ++i) {
176 if (fFamilies[i]->getFamilyName().equals(familyName)) {
177 return fFamilies[i];
178 }
179 }
180 return nullptr;
181 }
182
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const183 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
184 const SkFontStyle& fontStyle) const
185 {
186 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
187 return sset->matchStyle(fontStyle);
188 }
189
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar) const190 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyleCharacter(
191 const char familyName[], const SkFontStyle&,
192 const char* bcp47[], int bcp47Count,
193 SkUnichar) const
194 {
195 return nullptr;
196 }
197
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const198 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
199 return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
200 }
201
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const202 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
203 int ttcIndex) const {
204 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
205 }
206
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const207 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
208 const SkFontArguments& args) const {
209 return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
210 }
211
onMakeFromFile(const char path[],int ttcIndex) const212 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
213 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
214 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
215 }
216
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const217 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
218 SkFontStyle style) const {
219 sk_sp<SkTypeface> tf;
220
221 if (familyName) {
222 tf = this->onMatchFamilyStyle(familyName, style);
223 }
224
225 if (!tf) {
226 tf = fDefaultFamily->matchStyle(style);
227 }
228
229 return tf;
230 }
231