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