• 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/SkFontMgr_custom.h"
20 
21 #include <limits>
22 #include <memory>
23 
24 using namespace skia_private;
25 
26 class SkData;
27 
SkTypeface_Custom(const SkFontStyle & style,bool isFixedPitch,bool sysFont,SkString familyName,int index)28 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
29                                      bool sysFont, SkString familyName, int index)
30     : INHERITED(style, isFixedPitch)
31     , fIsSysFont(sysFont), fFamilyName(std::move(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     desc->setFactoryId(SkTypeface_FreeType::FactoryId);
44     *isLocal = !this->isSysFont();
45 }
46 
getIndex() const47 int SkTypeface_Custom::getIndex() const { return fIndex; }
48 
49 
SkTypeface_Empty()50 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
51 
onOpenStream(int *) const52 std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
53 
onMakeClone(const SkFontArguments & args) const54 sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
55     return sk_ref_sp(this);
56 }
57 
onMakeFontData() const58 std::unique_ptr<SkFontData> SkTypeface_Empty::onMakeFontData() const { return nullptr; }
59 
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,SkString familyName,const char path[],int index)60 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
61                                  SkString familyName, const char path[], int index)
62     : INHERITED(style, isFixedPitch, sysFont, std::move(familyName), index)
63     , fPath(path)
64 { }
65 
onOpenStream(int * ttcIndex) const66 std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
67     *ttcIndex = this->getIndex();
68     return SkStream::MakeFromFile(fPath.c_str());
69 }
70 
onMakeClone(const SkFontArguments & args) const71 sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
72     SkFontStyle style = this->fontStyle();
73     std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
74     if (!data) {
75         return nullptr;
76     }
77 
78     SkString familyName;
79     this->getFamilyName(&familyName);
80 
81     return sk_make_sp<SkTypeface_FreeTypeStream>(
82         std::move(data), familyName, style, this->isFixedPitch());
83 }
84 
onMakeFontData() const85 std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
86     int index;
87     std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
88     if (!stream) {
89         return nullptr;
90     }
91     return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
92 }
93 
94 ///////////////////////////////////////////////////////////////////////////////
95 
SkFontStyleSet_Custom(SkString familyName)96 SkFontStyleSet_Custom::SkFontStyleSet_Custom(SkString familyName)
97         : fFamilyName(std::move(familyName)) {}
98 
appendTypeface(sk_sp<SkTypeface> typeface)99 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface> typeface) {
100     fStyles.emplace_back(std::move(typeface));
101 }
102 
count()103 int SkFontStyleSet_Custom::count() {
104     return fStyles.size();
105 }
106 
getStyle(int index,SkFontStyle * style,SkString * name)107 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
108     SkASSERT(index < fStyles.size());
109     if (style) {
110         *style = fStyles[index]->fontStyle();
111     }
112     if (name) {
113         name->reset();
114     }
115 }
116 
createTypeface(int index)117 sk_sp<SkTypeface> SkFontStyleSet_Custom::createTypeface(int index) {
118     SkASSERT(index < fStyles.size());
119     return fStyles[index];
120 }
121 
matchStyle(const SkFontStyle & pattern)122 sk_sp<SkTypeface> SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
123     return this->matchStyleCSS3(pattern);
124 }
125 
getFamilyName()126 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
127 
SkFontMgr_Custom(const SystemFontLoader & loader)128 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader)
129         : fDefaultFamily(nullptr)
130         , fScanner(std::make_unique<SkFontScanner_FreeType>()) {
131 
132     loader.loadSystemFonts(fScanner.get(), &fFamilies);
133 
134     // Try to pick a default font.
135     static const char* defaultNames[] = {
136         "Arial", "Verdana", "Times New Roman", "Droid Sans", "DejaVu Serif", nullptr
137     };
138     for (size_t i = 0; i < std::size(defaultNames); ++i) {
139         sk_sp<SkFontStyleSet> set(this->onMatchFamily(defaultNames[i]));
140         if (nullptr == set) {
141             continue;
142         }
143 
144         sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
145                                                          SkFontStyle::kNormal_Width,
146                                                          SkFontStyle::kUpright_Slant)));
147         if (nullptr == tf) {
148             continue;
149         }
150 
151         fDefaultFamily = set;
152         break;
153     }
154     if (nullptr == fDefaultFamily) {
155         fDefaultFamily = fFamilies[0];
156     }
157 }
158 
onCountFamilies() const159 int SkFontMgr_Custom::onCountFamilies() const {
160     return fFamilies.size();
161 }
162 
onGetFamilyName(int index,SkString * familyName) const163 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
164     SkASSERT(index < fFamilies.size());
165     familyName->set(fFamilies[index]->getFamilyName());
166 }
167 
onCreateStyleSet(int index) const168 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onCreateStyleSet(int index) const {
169     SkASSERT(index < fFamilies.size());
170     return fFamilies[index];
171 }
172 
onMatchFamily(const char familyName[]) const173 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
174     for (int i = 0; i < fFamilies.size(); ++i) {
175         if (fFamilies[i]->getFamilyName().equals(familyName)) {
176             return fFamilies[i];
177         }
178     }
179     return nullptr;
180 }
181 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const182 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
183                                                        const SkFontStyle& fontStyle) const
184 {
185     sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
186     return sset->matchStyle(fontStyle);
187 }
188 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar) const189 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyleCharacter(
190     const char familyName[], const SkFontStyle&,
191     const char* bcp47[], int bcp47Count,
192     SkUnichar) const
193 {
194     return nullptr;
195 }
196 
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const197 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
198     return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
199 }
200 
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const201 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
202                                                           int ttcIndex) const {
203     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
204 }
205 
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const206 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
207                                                          const SkFontArguments& args) const {
208     return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
209 }
210 
onMakeFromFile(const char path[],int ttcIndex) const211 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
212     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
213     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
214 }
215 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const216 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
217                                                          SkFontStyle style) const {
218     sk_sp<SkTypeface> tf;
219 
220     if (familyName) {
221         tf = this->onMatchFamilyStyle(familyName, style);
222     }
223 
224     if (!tf) {
225         tf = fDefaultFamily->matchStyle(style);
226     }
227 
228     return tf;
229 }
230