xref: /aosp_15_r20/external/skia/src/ports/SkFontMgr_custom.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2006 The Android Open Source Project
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontArguments.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/ports/SkFontScanner_FreeType.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkFontDescriptor.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/ports/SkFontMgr_custom.h"
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker #include <limits>
23*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker class SkData;
28*c8dee2aaSAndroid Build Coastguard Worker 
SkTypeface_Custom(const SkFontStyle & style,bool isFixedPitch,bool sysFont,SkString familyName,int index)29*c8dee2aaSAndroid Build Coastguard Worker SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
30*c8dee2aaSAndroid Build Coastguard Worker                                      bool sysFont, SkString familyName, int index)
31*c8dee2aaSAndroid Build Coastguard Worker     : INHERITED(style, isFixedPitch)
32*c8dee2aaSAndroid Build Coastguard Worker     , fIsSysFont(sysFont), fFamilyName(std::move(familyName)), fIndex(index)
33*c8dee2aaSAndroid Build Coastguard Worker { }
34*c8dee2aaSAndroid Build Coastguard Worker 
isSysFont() const35*c8dee2aaSAndroid Build Coastguard Worker bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
36*c8dee2aaSAndroid Build Coastguard Worker 
onGetFamilyName(SkString * familyName) const37*c8dee2aaSAndroid Build Coastguard Worker void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
38*c8dee2aaSAndroid Build Coastguard Worker     *familyName = fFamilyName;
39*c8dee2aaSAndroid Build Coastguard Worker }
40*c8dee2aaSAndroid Build Coastguard Worker 
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const41*c8dee2aaSAndroid Build Coastguard Worker void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
42*c8dee2aaSAndroid Build Coastguard Worker     desc->setFamilyName(fFamilyName.c_str());
43*c8dee2aaSAndroid Build Coastguard Worker     desc->setStyle(this->fontStyle());
44*c8dee2aaSAndroid Build Coastguard Worker     desc->setFactoryId(SkTypeface_FreeType::FactoryId);
45*c8dee2aaSAndroid Build Coastguard Worker     *isLocal = !this->isSysFont();
46*c8dee2aaSAndroid Build Coastguard Worker }
47*c8dee2aaSAndroid Build Coastguard Worker 
getIndex() const48*c8dee2aaSAndroid Build Coastguard Worker int SkTypeface_Custom::getIndex() const { return fIndex; }
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker 
SkTypeface_Empty()51*c8dee2aaSAndroid Build Coastguard Worker SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
52*c8dee2aaSAndroid Build Coastguard Worker 
onOpenStream(int *) const53*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
54*c8dee2aaSAndroid Build Coastguard Worker 
onMakeClone(const SkFontArguments & args) const55*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
56*c8dee2aaSAndroid Build Coastguard Worker     return sk_ref_sp(this);
57*c8dee2aaSAndroid Build Coastguard Worker }
58*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFontData() const59*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkFontData> SkTypeface_Empty::onMakeFontData() const { return nullptr; }
60*c8dee2aaSAndroid Build Coastguard Worker 
SkTypeface_File(const SkFontStyle & style,bool isFixedPitch,bool sysFont,SkString familyName,const char path[],int index)61*c8dee2aaSAndroid Build Coastguard Worker SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
62*c8dee2aaSAndroid Build Coastguard Worker                                  SkString familyName, const char path[], int index)
63*c8dee2aaSAndroid Build Coastguard Worker     : INHERITED(style, isFixedPitch, sysFont, std::move(familyName), index)
64*c8dee2aaSAndroid Build Coastguard Worker     , fPath(path)
65*c8dee2aaSAndroid Build Coastguard Worker { }
66*c8dee2aaSAndroid Build Coastguard Worker 
onOpenStream(int * ttcIndex) const67*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
68*c8dee2aaSAndroid Build Coastguard Worker     *ttcIndex = this->getIndex();
69*c8dee2aaSAndroid Build Coastguard Worker     return SkStream::MakeFromFile(fPath.c_str());
70*c8dee2aaSAndroid Build Coastguard Worker }
71*c8dee2aaSAndroid Build Coastguard Worker 
onMakeClone(const SkFontArguments & args) const72*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
73*c8dee2aaSAndroid Build Coastguard Worker     SkFontStyle style = this->fontStyle();
74*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
75*c8dee2aaSAndroid Build Coastguard Worker     if (!data) {
76*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
77*c8dee2aaSAndroid Build Coastguard Worker     }
78*c8dee2aaSAndroid Build Coastguard Worker 
79*c8dee2aaSAndroid Build Coastguard Worker     SkString familyName;
80*c8dee2aaSAndroid Build Coastguard Worker     this->getFamilyName(&familyName);
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker     return sk_make_sp<SkTypeface_FreeTypeStream>(
83*c8dee2aaSAndroid Build Coastguard Worker         std::move(data), familyName, style, this->isFixedPitch());
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFontData() const86*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkFontData> SkTypeface_File::onMakeFontData() const {
87*c8dee2aaSAndroid Build Coastguard Worker     int index;
88*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
89*c8dee2aaSAndroid Build Coastguard Worker     if (!stream) {
90*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
91*c8dee2aaSAndroid Build Coastguard Worker     }
92*c8dee2aaSAndroid Build Coastguard Worker     return std::make_unique<SkFontData>(std::move(stream), index, 0, nullptr, 0, nullptr, 0);
93*c8dee2aaSAndroid Build Coastguard Worker }
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
96*c8dee2aaSAndroid Build Coastguard Worker 
SkFontStyleSet_Custom(SkString familyName)97*c8dee2aaSAndroid Build Coastguard Worker SkFontStyleSet_Custom::SkFontStyleSet_Custom(SkString familyName)
98*c8dee2aaSAndroid Build Coastguard Worker         : fFamilyName(std::move(familyName)) {}
99*c8dee2aaSAndroid Build Coastguard Worker 
appendTypeface(sk_sp<SkTypeface> typeface)100*c8dee2aaSAndroid Build Coastguard Worker void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface> typeface) {
101*c8dee2aaSAndroid Build Coastguard Worker     fStyles.emplace_back(std::move(typeface));
102*c8dee2aaSAndroid Build Coastguard Worker }
103*c8dee2aaSAndroid Build Coastguard Worker 
count()104*c8dee2aaSAndroid Build Coastguard Worker int SkFontStyleSet_Custom::count() {
105*c8dee2aaSAndroid Build Coastguard Worker     return fStyles.size();
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker 
getStyle(int index,SkFontStyle * style,SkString * name)108*c8dee2aaSAndroid Build Coastguard Worker void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
109*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(index < fStyles.size());
110*c8dee2aaSAndroid Build Coastguard Worker     if (style) {
111*c8dee2aaSAndroid Build Coastguard Worker         *style = fStyles[index]->fontStyle();
112*c8dee2aaSAndroid Build Coastguard Worker     }
113*c8dee2aaSAndroid Build Coastguard Worker     if (name) {
114*c8dee2aaSAndroid Build Coastguard Worker         name->reset();
115*c8dee2aaSAndroid Build Coastguard Worker     }
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker 
createTypeface(int index)118*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontStyleSet_Custom::createTypeface(int index) {
119*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(index < fStyles.size());
120*c8dee2aaSAndroid Build Coastguard Worker     return fStyles[index];
121*c8dee2aaSAndroid Build Coastguard Worker }
122*c8dee2aaSAndroid Build Coastguard Worker 
matchStyle(const SkFontStyle & pattern)123*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
124*c8dee2aaSAndroid Build Coastguard Worker     return this->matchStyleCSS3(pattern);
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker 
getFamilyName()127*c8dee2aaSAndroid Build Coastguard Worker SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
128*c8dee2aaSAndroid Build Coastguard Worker 
SkFontMgr_Custom(const SystemFontLoader & loader)129*c8dee2aaSAndroid Build Coastguard Worker SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader)
130*c8dee2aaSAndroid Build Coastguard Worker         : fDefaultFamily(nullptr)
131*c8dee2aaSAndroid Build Coastguard Worker         , fScanner(SkFontScanner_Make_FreeType()) {
132*c8dee2aaSAndroid Build Coastguard Worker 
133*c8dee2aaSAndroid Build Coastguard Worker     loader.loadSystemFonts(fScanner.get(), &fFamilies);
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     // Try to pick a default font.
136*c8dee2aaSAndroid Build Coastguard Worker     static const char* defaultNames[] = {
137*c8dee2aaSAndroid Build Coastguard Worker         "Arial", "Verdana", "Times New Roman", "Droid Sans", "DejaVu Serif", nullptr
138*c8dee2aaSAndroid Build Coastguard Worker     };
139*c8dee2aaSAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(defaultNames); ++i) {
140*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkFontStyleSet> set(this->onMatchFamily(defaultNames[i]));
141*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == set) {
142*c8dee2aaSAndroid Build Coastguard Worker             continue;
143*c8dee2aaSAndroid Build Coastguard Worker         }
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
146*c8dee2aaSAndroid Build Coastguard Worker                                                          SkFontStyle::kNormal_Width,
147*c8dee2aaSAndroid Build Coastguard Worker                                                          SkFontStyle::kUpright_Slant)));
148*c8dee2aaSAndroid Build Coastguard Worker         if (nullptr == tf) {
149*c8dee2aaSAndroid Build Coastguard Worker             continue;
150*c8dee2aaSAndroid Build Coastguard Worker         }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker         fDefaultFamily = set;
153*c8dee2aaSAndroid Build Coastguard Worker         break;
154*c8dee2aaSAndroid Build Coastguard Worker     }
155*c8dee2aaSAndroid Build Coastguard Worker     if (nullptr == fDefaultFamily) {
156*c8dee2aaSAndroid Build Coastguard Worker         fDefaultFamily = fFamilies[0];
157*c8dee2aaSAndroid Build Coastguard Worker     }
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker 
onCountFamilies() const160*c8dee2aaSAndroid Build Coastguard Worker int SkFontMgr_Custom::onCountFamilies() const {
161*c8dee2aaSAndroid Build Coastguard Worker     return fFamilies.size();
162*c8dee2aaSAndroid Build Coastguard Worker }
163*c8dee2aaSAndroid Build Coastguard Worker 
onGetFamilyName(int index,SkString * familyName) const164*c8dee2aaSAndroid Build Coastguard Worker void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
165*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(index < fFamilies.size());
166*c8dee2aaSAndroid Build Coastguard Worker     familyName->set(fFamilies[index]->getFamilyName());
167*c8dee2aaSAndroid Build Coastguard Worker }
168*c8dee2aaSAndroid Build Coastguard Worker 
onCreateStyleSet(int index) const169*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontStyleSet> SkFontMgr_Custom::onCreateStyleSet(int index) const {
170*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(index < fFamilies.size());
171*c8dee2aaSAndroid Build Coastguard Worker     return fFamilies[index];
172*c8dee2aaSAndroid Build Coastguard Worker }
173*c8dee2aaSAndroid Build Coastguard Worker 
onMatchFamily(const char familyName[]) const174*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontStyleSet> SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
175*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fFamilies.size(); ++i) {
176*c8dee2aaSAndroid Build Coastguard Worker         if (fFamilies[i]->getFamilyName().equals(familyName)) {
177*c8dee2aaSAndroid Build Coastguard Worker             return fFamilies[i];
178*c8dee2aaSAndroid Build Coastguard Worker         }
179*c8dee2aaSAndroid Build Coastguard Worker     }
180*c8dee2aaSAndroid Build Coastguard Worker     return nullptr;
181*c8dee2aaSAndroid Build Coastguard Worker }
182*c8dee2aaSAndroid Build Coastguard Worker 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & fontStyle) const183*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
184*c8dee2aaSAndroid Build Coastguard Worker                                                        const SkFontStyle& fontStyle) const
185*c8dee2aaSAndroid Build Coastguard Worker {
186*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
187*c8dee2aaSAndroid Build Coastguard Worker     return sset->matchStyle(fontStyle);
188*c8dee2aaSAndroid Build Coastguard Worker }
189*c8dee2aaSAndroid Build Coastguard Worker 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle &,const char * bcp47[],int bcp47Count,SkUnichar) const190*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMatchFamilyStyleCharacter(
191*c8dee2aaSAndroid Build Coastguard Worker     const char familyName[], const SkFontStyle&,
192*c8dee2aaSAndroid Build Coastguard Worker     const char* bcp47[], int bcp47Count,
193*c8dee2aaSAndroid Build Coastguard Worker     SkUnichar) const
194*c8dee2aaSAndroid Build Coastguard Worker {
195*c8dee2aaSAndroid Build Coastguard Worker     return nullptr;
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFromData(sk_sp<SkData> data,int ttcIndex) const198*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
199*c8dee2aaSAndroid Build Coastguard Worker     return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,int ttcIndex) const202*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
203*c8dee2aaSAndroid Build Coastguard Worker                                                           int ttcIndex) const {
204*c8dee2aaSAndroid Build Coastguard Worker     return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
205*c8dee2aaSAndroid Build Coastguard Worker }
206*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const207*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
208*c8dee2aaSAndroid Build Coastguard Worker                                                          const SkFontArguments& args) const {
209*c8dee2aaSAndroid Build Coastguard Worker     return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
210*c8dee2aaSAndroid Build Coastguard Worker }
211*c8dee2aaSAndroid Build Coastguard Worker 
onMakeFromFile(const char path[],int ttcIndex) const212*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
213*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
214*c8dee2aaSAndroid Build Coastguard Worker     return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
215*c8dee2aaSAndroid Build Coastguard Worker }
216*c8dee2aaSAndroid Build Coastguard Worker 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const217*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
218*c8dee2aaSAndroid Build Coastguard Worker                                                          SkFontStyle style) const {
219*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTypeface> tf;
220*c8dee2aaSAndroid Build Coastguard Worker 
221*c8dee2aaSAndroid Build Coastguard Worker     if (familyName) {
222*c8dee2aaSAndroid Build Coastguard Worker         tf = this->onMatchFamilyStyle(familyName, style);
223*c8dee2aaSAndroid Build Coastguard Worker     }
224*c8dee2aaSAndroid Build Coastguard Worker 
225*c8dee2aaSAndroid Build Coastguard Worker     if (!tf) {
226*c8dee2aaSAndroid Build Coastguard Worker         tf = fDefaultFamily->matchStyle(style);
227*c8dee2aaSAndroid Build Coastguard Worker     }
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker     return tf;
230*c8dee2aaSAndroid Build Coastguard Worker }
231