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