xref: /aosp_15_r20/external/skia/src/ports/SkFontMgr_custom.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/ports/SkFontScanner_FreeType.h"
17 #include "include/private/base/SkTArray.h"
18 #include "include/private/base/SkTemplates.h"
19 #include "src/core/SkFontDescriptor.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,SkString familyName,int index)29 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
30                                      bool sysFont, SkString familyName, int index)
31     : INHERITED(style, isFixedPitch)
32     , fIsSysFont(sysFont), fFamilyName(std::move(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,SkString familyName,const char path[],int index)61 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
62                                  SkString familyName, const char path[], int index)
63     : INHERITED(style, isFixedPitch, sysFont, std::move(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     SkFontStyle style = this->fontStyle();
74     std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
75     if (!data) {
76         return nullptr;
77     }
78 
79     SkString familyName;
80     this->getFamilyName(&familyName);
81 
82     return sk_make_sp<SkTypeface_FreeTypeStream>(
83         std::move(data), familyName, style, this->isFixedPitch());
84 }
85 
onMakeFontData() const86 std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
87     int index;
88     std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
89     if (!stream) {
90         return nullptr;
91     }
92     return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
93 }
94 
95 ///////////////////////////////////////////////////////////////////////////////
96 
SkFontStyleSet_Custom(SkString familyName)97 SkFontStyleSet_Custom::SkFontStyleSet_Custom(SkString familyName)
98         : fFamilyName(std::move(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 sk_sp<SkTypeface> SkFontStyleSet_Custom::createTypeface(int index) {
119     SkASSERT(index < fStyles.size());
120     return fStyles[index];
121 }
122 
matchStyle(const SkFontStyle & pattern)123 sk_sp<SkTypeface> SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
124     return this->matchStyleCSS3(pattern);
125 }
126 
getFamilyName()127 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
128 
SkFontMgr_Custom(const SystemFontLoader & loader)129 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader)
130         : fDefaultFamily(nullptr)
131         , fScanner(SkFontScanner_Make_FreeType()) {
132 
133     loader.loadSystemFonts(fScanner.get(), &fFamilies);
134 
135     // Try to pick a default font.
136     static const char* defaultNames[] = {
137         "Arial", "Verdana", "Times New Roman", "Droid Sans", "DejaVu Serif", nullptr
138     };
139     for (size_t i = 0; i < std::size(defaultNames); ++i) {
140         sk_sp<SkFontStyleSet> set(this->onMatchFamily(defaultNames[i]));
141         if (nullptr == set) {
142             continue;
143         }
144 
145         sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
146                                                          SkFontStyle::kNormal_Width,
147                                                          SkFontStyle::kUpright_Slant)));
148         if (nullptr == tf) {
149             continue;
150         }
151 
152         fDefaultFamily = set;
153         break;
154     }
155     if (nullptr == fDefaultFamily) {
156         fDefaultFamily = fFamilies[0];
157     }
158 }
159 
onCountFamilies() const160 int SkFontMgr_Custom::onCountFamilies() const {
161     return fFamilies.size();
162 }
163 
onGetFamilyName(int index,SkString * familyName) const164 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
165     SkASSERT(index < fFamilies.size());
166     familyName->set(fFamilies[index]->getFamilyName());
167 }
168 
onCreateStyleSet(int index) const169 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onCreateStyleSet(int index) const {
170     SkASSERT(index < fFamilies.size());
171     return fFamilies[index];
172 }
173 
onMatchFamily(const char familyName[]) const174 sk_sp<SkFontStyleSet> SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
175     for (int i = 0; i < fFamilies.size(); ++i) {
176         if (fFamilies[i]->getFamilyName().equals(familyName)) {
177             return fFamilies[i];
178         }
179     }
180     return nullptr;
181 }
182 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const183 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
184                                                        const SkFontStyle& fontStyle) const
185 {
186     sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
187     return sset->matchStyle(fontStyle);
188 }
189 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar) const190 sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyleCharacter(
191     const char familyName[], const SkFontStyle&,
192     const char* bcp47[], int bcp47Count,
193     SkUnichar) const
194 {
195     return nullptr;
196 }
197 
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const198 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
199     return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
200 }
201 
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const202 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
203                                                           int ttcIndex) const {
204     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
205 }
206 
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const207 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
208                                                          const SkFontArguments& args) const {
209     return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
210 }
211 
onMakeFromFile(const char path[],int ttcIndex) const212 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
213     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
214     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
215 }
216 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const217 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
218                                                          SkFontStyle style) const {
219     sk_sp<SkTypeface> tf;
220 
221     if (familyName) {
222         tf = this->onMatchFamilyStyle(familyName, style);
223     }
224 
225     if (!tf) {
226         tf = fDefaultFamily->matchStyle(style);
227     }
228 
229     return tf;
230 }
231