• 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/core/SkMakeUnique.h"
20 #include "src/ports/SkFontHost_FreeType_common.h"
21 #include "src/ports/SkFontMgr_custom.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 std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
52 
onMakeClone(const SkFontArguments & args) const53 sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
54     return sk_ref_sp(this);
55 }
56 
SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName)57 SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
58                                      const SkFontStyle& style, bool isFixedPitch, bool sysFont,
59                                      const SkString familyName)
60     : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
61     , fData(std::move(fontData))
62 { }
63 
onOpenStream(int * ttcIndex) const64 std::unique_ptr<SkStreamAsset> SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
65     *ttcIndex = fData->getIndex();
66     return fData->getStream()->duplicate();
67 }
68 
onMakeFontData() const69 std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
70     return skstd::make_unique<SkFontData>(*fData);
71 }
72 
onMakeClone(const SkFontArguments & args) const73 sk_sp<SkTypeface> SkTypeface_Stream::onMakeClone(const SkFontArguments& args) const {
74     std::unique_ptr<SkFontData> data = this->cloneFontData(args);
75     if (!data) {
76         return nullptr;
77     }
78 
79     SkString familyName;
80     this->getFamilyName(&familyName);
81 
82     return sk_make_sp<SkTypeface_Stream>(std::move(data),
83                                          this->fontStyle(),
84                                          this->isFixedPitch(),
85                                          this->isSysFont(),
86                                          familyName);
87 }
88 
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,const SkString familyName,const char path[],int index)89 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
90                                  const SkString familyName, const char path[], int index)
91     : INHERITED(style, isFixedPitch, sysFont, familyName, index)
92     , fPath(path)
93 { }
94 
onOpenStream(int * ttcIndex) const95 std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
96     *ttcIndex = this->getIndex();
97     return SkStream::MakeFromFile(fPath.c_str());
98 }
99 
onMakeClone(const SkFontArguments & args) const100 sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
101     std::unique_ptr<SkFontData> data = this->cloneFontData(args);
102     if (!data) {
103         return nullptr;
104     }
105 
106     SkString familyName;
107     this->getFamilyName(&familyName);
108 
109     return sk_make_sp<SkTypeface_Stream>(std::move(data),
110                                          this->fontStyle(),
111                                          this->isFixedPitch(),
112                                          this->isSysFont(),
113                                          familyName);
114 }
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 
SkFontStyleSet_Custom(const SkString familyName)118 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
119 
appendTypeface(sk_sp<SkTypeface_Custom> typeface)120 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
121     fStyles.emplace_back(std::move(typeface));
122 }
123 
count()124 int SkFontStyleSet_Custom::count() {
125     return fStyles.count();
126 }
127 
getStyle(int index,SkFontStyle * style,SkString * name)128 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
129     SkASSERT(index < fStyles.count());
130     if (style) {
131         *style = fStyles[index]->fontStyle();
132     }
133     if (name) {
134         name->reset();
135     }
136 }
137 
createTypeface(int index)138 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
139     SkASSERT(index < fStyles.count());
140     return SkRef(fStyles[index].get());
141 }
142 
matchStyle(const SkFontStyle & pattern)143 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
144     return this->matchStyleCSS3(pattern);
145 }
146 
getFamilyName()147 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
148 
149 
SkFontMgr_Custom(const SystemFontLoader & loader)150 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
151     loader.loadSystemFonts(fScanner, &fFamilies);
152 
153     // Try to pick a default font.
154     static const char* defaultNames[] = {
155         "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
156     };
157     for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
158         sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
159         if (nullptr == set) {
160             continue;
161         }
162 
163         sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
164                                                          SkFontStyle::kNormal_Width,
165                                                          SkFontStyle::kUpright_Slant)));
166         if (nullptr == tf) {
167             continue;
168         }
169 
170         fDefaultFamily = set.get();
171         break;
172     }
173     if (nullptr == fDefaultFamily) {
174         fDefaultFamily = fFamilies[0].get();
175     }
176 }
177 
onCountFamilies() const178 int SkFontMgr_Custom::onCountFamilies() const {
179     return fFamilies.count();
180 }
181 
onGetFamilyName(int index,SkString * familyName) const182 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
183     SkASSERT(index < fFamilies.count());
184     familyName->set(fFamilies[index]->getFamilyName());
185 }
186 
onCreateStyleSet(int index) const187 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
188     SkASSERT(index < fFamilies.count());
189     return SkRef(fFamilies[index].get());
190 }
191 
onMatchFamily(const char familyName[]) const192 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
193     for (int i = 0; i < fFamilies.count(); ++i) {
194         if (fFamilies[i]->getFamilyName().equals(familyName)) {
195             return SkRef(fFamilies[i].get());
196         }
197     }
198     return nullptr;
199 }
200 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const201 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
202                                 const SkFontStyle& fontStyle) const
203 {
204     sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
205     return sset->matchStyle(fontStyle);
206 }
207 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar character) const208 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
209                                                           const SkFontStyle&,
210                                                           const char* bcp47[], int bcp47Count,
211                                                           SkUnichar character) const
212 {
213     return nullptr;
214 }
215 
onMatchFaceStyle(const SkTypeface * familyMember,const SkFontStyle & fontStyle) const216 SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
217                                                const SkFontStyle& fontStyle) const
218 {
219     for (int i = 0; i < fFamilies.count(); ++i) {
220         for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
221             if (fFamilies[i]->fStyles[j].get() == familyMember) {
222                 return fFamilies[i]->matchStyle(fontStyle);
223             }
224         }
225     }
226     return nullptr;
227 }
228 
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const229 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
230     return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
231 }
232 
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const233 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
234                                                           int ttcIndex) const {
235     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
236 }
237 
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const238 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
239                                                          const SkFontArguments& args) const {
240     using Scanner = SkTypeface_FreeType::Scanner;
241     bool isFixedPitch;
242     SkFontStyle style;
243     SkString name;
244     Scanner::AxisDefinitions axisDefinitions;
245     if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
246                             &name, &style, &isFixedPitch, &axisDefinitions))
247     {
248         return nullptr;
249     }
250 
251     const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
252     SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
253     Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
254 
255     auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
256                                                axisValues.get(), axisDefinitions.count());
257     return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
258 }
259 
onMakeFromFontData(std::unique_ptr<SkFontData> data) const260 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const {
261     bool isFixedPitch;
262     SkFontStyle style;
263     SkString name;
264     if (!fScanner.scanFont(data->getStream(), data->getIndex(),
265                             &name, &style, &isFixedPitch, nullptr)) {
266         return nullptr;
267     }
268     return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
269 }
270 
onMakeFromFile(const char path[],int ttcIndex) const271 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
272     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
273     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
274 }
275 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const276 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
277                                                          SkFontStyle style) const {
278     sk_sp<SkTypeface> tf;
279 
280     if (familyName) {
281         tf.reset(this->onMatchFamilyStyle(familyName, style));
282     }
283 
284     if (nullptr == tf) {
285         tf.reset(fDefaultFamily->matchStyle(style));
286     }
287 
288     return tf;
289 }
290