• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,const char path[],int index)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 
onOpenStream(int * ttcIndex) const96 std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
97     *ttcIndex = this->getIndex();
98     return SkStream::MakeFromFile(fPath.c_str());
99 }
100 
onMakeClone(const SkFontArguments & args) const101 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 
onMakeFontData() const117 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 
SkFontStyleSet_Custom(const SkString familyName)128 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
129 
appendTypeface(sk_sp<SkTypeface_Custom> typeface)130 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
131     fStyles.emplace_back(std::move(typeface));
132 }
133 
count()134 int SkFontStyleSet_Custom::count() {
135     return fStyles.count();
136 }
137 
getStyle(int index,SkFontStyle * style,SkString * name)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 
createTypeface(int index)148 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
149     SkASSERT(index < fStyles.count());
150     return SkRef(fStyles[index].get());
151 }
152 
matchStyle(const SkFontStyle & pattern)153 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
154     return this->matchStyleCSS3(pattern);
155 }
156 
getFamilyName()157 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
158 
159 
SkFontMgr_Custom(const SystemFontLoader & loader)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 
onCountFamilies() const188 int SkFontMgr_Custom::onCountFamilies() const {
189     return fFamilies.count();
190 }
191 
onGetFamilyName(int index,SkString * familyName) const192 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
193     SkASSERT(index < fFamilies.count());
194     familyName->set(fFamilies[index]->getFamilyName());
195 }
196 
onCreateStyleSet(int index) const197 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
198     SkASSERT(index < fFamilies.count());
199     return SkRef(fFamilies[index].get());
200 }
201 
onMatchFamily(const char familyName[]) const202 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 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const211 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 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar character) const218 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 
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const226 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
227     return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
228 }
229 
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const230 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
231                                                           int ttcIndex) const {
232     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
233 }
234 
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const235 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
236                                                          const SkFontArguments& args) const {
237     using Scanner = SkTypeface_FreeType::Scanner;
238     bool isFixedPitch;
239     SkFontStyle style;
240     SkString name;
241     Scanner::AxisDefinitions axisDefinitions;
242     if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
243                             &name, &style, &isFixedPitch, &axisDefinitions))
244     {
245         return nullptr;
246     }
247 
248     const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
249     SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
250     Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
251 
252     auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
253                                                axisValues.get(), axisDefinitions.count());
254     return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
255 }
256 
onMakeFromFile(const char path[],int ttcIndex) const257 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
258     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
259     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
260 }
261 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const262 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
263                                                          SkFontStyle style) const {
264     sk_sp<SkTypeface> tf;
265 
266     if (familyName) {
267         tf.reset(this->onMatchFamilyStyle(familyName, style));
268     }
269 
270     if (nullptr == tf) {
271         tf.reset(fDefaultFamily->matchStyle(style));
272     }
273 
274     return tf;
275 }
276