• 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 "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