blob: 8be11e8dbc345e85a021e44d46805f1d5226e80d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#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/SkTArray.h"
17#include "include/private/SkTemplates.h"
18#include "src/core/SkFontDescriptor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/ports/SkFontHost_FreeType_common.h"
20#include "src/ports/SkFontMgr_custom.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000021
22#include <limits>
bungeman4772bd52016-06-10 04:14:51 -070023#include <memory>
reed@android.com8a1c16f2008-12-17 15:59:43 +000024
bungemanf20488b2015-07-29 11:49:40 -070025class SkData;
26
Ben Wagner8ab590f2017-02-08 17:29:33 -050027SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
28 bool sysFont, const SkString familyName, int index)
29 : INHERITED(style, isFixedPitch)
30 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
31{ }
chudy@google.comada44802012-07-30 12:59:12 +000032
Ben Wagner8ab590f2017-02-08 17:29:33 -050033bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
reed@google.com292b1d42013-03-22 17:21:59 +000034
Ben Wagner8ab590f2017-02-08 17:29:33 -050035void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
36 *familyName = fFamilyName;
37}
bungemanb374d6a2014-09-17 07:48:59 -070038
Ben Wagner8ab590f2017-02-08 17:29:33 -050039void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
40 desc->setFamilyName(fFamilyName.c_str());
41 desc->setStyle(this->fontStyle());
42 *isLocal = !this->isSysFont();
43}
reed@google.com5526ede2013-03-25 13:03:37 +000044
Ben Wagner8ab590f2017-02-08 17:29:33 -050045int SkTypeface_Custom::getIndex() const { return fIndex; }
bungemand71b7572014-09-18 10:55:32 -070046
chudy@google.comada44802012-07-30 12:59:12 +000047
Ben Wagner8ab590f2017-02-08 17:29:33 -050048SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
reed@android.com8a1c16f2008-12-17 15:59:43 +000049
Ben Wagner4212a7d2019-02-25 14:27:46 -050050std::unique_ptr<SkStreamAsset> SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
chudy@google.comada44802012-07-30 12:59:12 +000051
Bruce Wang0ea256c2018-06-22 15:44:47 -040052sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
53 return sk_ref_sp(this);
54}
reed@google.com292b1d42013-03-22 17:21:59 +000055
Ben Wagner8ab590f2017-02-08 17:29:33 -050056SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
57 const SkFontStyle& style, bool isFixedPitch, bool sysFont,
58 const SkString familyName)
59 : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
60 , fData(std::move(fontData))
61{ }
reed@android.comf244f1b2010-04-16 12:40:08 +000062
Ben Wagner4212a7d2019-02-25 14:27:46 -050063std::unique_ptr<SkStreamAsset> SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -050064 *ttcIndex = fData->getIndex();
Ben Wagner4212a7d2019-02-25 14:27:46 -050065 return fData->getStream()->duplicate();
Ben Wagner8ab590f2017-02-08 17:29:33 -050066}
chudy@google.comada44802012-07-30 12:59:12 +000067
Ben Wagner8ab590f2017-02-08 17:29:33 -050068std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
Mike Kleinf46d5ca2019-12-11 10:45:01 -050069 return std::make_unique<SkFontData>(*fData);
Ben Wagner8ab590f2017-02-08 17:29:33 -050070}
bungeman4772bd52016-06-10 04:14:51 -070071
Bruce Wang0ea256c2018-06-22 15:44:47 -040072sk_sp<SkTypeface> SkTypeface_Stream::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_Stream>(std::move(data),
82 this->fontStyle(),
83 this->isFixedPitch(),
84 this->isSysFont(),
85 familyName);
86}
reed@google.com292b1d42013-03-22 17:21:59 +000087
Ben Wagner8ab590f2017-02-08 17:29:33 -050088SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
89 const SkString familyName, const char path[], int index)
90 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
91 , fPath(path)
92{ }
chudy@google.comada44802012-07-30 12:59:12 +000093
Ben Wagner4212a7d2019-02-25 14:27:46 -050094std::unique_ptr<SkStreamAsset> SkTypeface_File::onOpenStream(int* ttcIndex) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -050095 *ttcIndex = this->getIndex();
Ben Wagner4212a7d2019-02-25 14:27:46 -050096 return SkStream::MakeFromFile(fPath.c_str());
Ben Wagner8ab590f2017-02-08 17:29:33 -050097}
reed@android.com8a1c16f2008-12-17 15:59:43 +000098
Bruce Wang0ea256c2018-06-22 15:44:47 -040099sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
100 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
101 if (!data) {
102 return nullptr;
103 }
104
105 SkString familyName;
106 this->getFamilyName(&familyName);
107
108 return sk_make_sp<SkTypeface_Stream>(std::move(data),
109 this->fontStyle(),
110 this->isFixedPitch(),
111 this->isSysFont(),
112 familyName);
113}
114
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116
Ben Wagner8ab590f2017-02-08 17:29:33 -0500117SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000118
Ben Wagner8ab590f2017-02-08 17:29:33 -0500119void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
120 fStyles.emplace_back(std::move(typeface));
121}
122
123int SkFontStyleSet_Custom::count() {
124 return fStyles.count();
125}
126
127void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
128 SkASSERT(index < fStyles.count());
129 if (style) {
130 *style = fStyles[index]->fontStyle();
bungeman5c9fa282015-03-30 12:53:48 -0700131 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500132 if (name) {
133 name->reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500135}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136
Ben Wagner8ab590f2017-02-08 17:29:33 -0500137SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
138 SkASSERT(index < fStyles.count());
139 return SkRef(fStyles[index].get());
140}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141
Ben Wagner8ab590f2017-02-08 17:29:33 -0500142SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
143 return this->matchStyleCSS3(pattern);
144}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145
Ben Wagner8ab590f2017-02-08 17:29:33 -0500146SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000147
bungeman5c9fa282015-03-30 12:53:48 -0700148
Ben Wagner8ab590f2017-02-08 17:29:33 -0500149SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
150 loader.loadSystemFonts(fScanner, &fFamilies);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000151
Ben Wagner8ab590f2017-02-08 17:29:33 -0500152 // Try to pick a default font.
153 static const char* defaultNames[] = {
154 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
bungeman5c9fa282015-03-30 12:53:48 -0700155 };
Ben Wagner8ab590f2017-02-08 17:29:33 -0500156 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
157 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
158 if (nullptr == set) {
159 continue;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000160 }
bungeman4772bd52016-06-10 04:14:51 -0700161
Ben Wagner8ab590f2017-02-08 17:29:33 -0500162 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
163 SkFontStyle::kNormal_Width,
164 SkFontStyle::kUpright_Slant)));
halcanary96fcdcc2015-08-27 07:41:13 -0700165 if (nullptr == tf) {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500166 continue;
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000167 }
168
Ben Wagner8ab590f2017-02-08 17:29:33 -0500169 fDefaultFamily = set.get();
170 break;
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000171 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500172 if (nullptr == fDefaultFamily) {
173 fDefaultFamily = fFamilies[0].get();
174 }
175}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000176
Ben Wagner8ab590f2017-02-08 17:29:33 -0500177int SkFontMgr_Custom::onCountFamilies() const {
178 return fFamilies.count();
179}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000180
Ben Wagner8ab590f2017-02-08 17:29:33 -0500181void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
182 SkASSERT(index < fFamilies.count());
183 familyName->set(fFamilies[index]->getFamilyName());
184}
bungeman5c9fa282015-03-30 12:53:48 -0700185
Ben Wagner8ab590f2017-02-08 17:29:33 -0500186SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
187 SkASSERT(index < fFamilies.count());
188 return SkRef(fFamilies[index].get());
189}
bungeman5c9fa282015-03-30 12:53:48 -0700190
Ben Wagner8ab590f2017-02-08 17:29:33 -0500191SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
192 for (int i = 0; i < fFamilies.count(); ++i) {
193 if (fFamilies[i]->getFamilyName().equals(familyName)) {
194 return SkRef(fFamilies[i].get());
bungeman5c9fa282015-03-30 12:53:48 -0700195 }
196 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500197 return nullptr;
198}
bungeman5c9fa282015-03-30 12:53:48 -0700199
Ben Wagner8ab590f2017-02-08 17:29:33 -0500200SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
201 const SkFontStyle& fontStyle) const
202{
203 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
204 return sset->matchStyle(fontStyle);
205}
206
207SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
208 const SkFontStyle&,
209 const char* bcp47[], int bcp47Count,
210 SkUnichar character) const
211{
212 return nullptr;
213}
214
215SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
216 const SkFontStyle& fontStyle) const
217{
218 for (int i = 0; i < fFamilies.count(); ++i) {
219 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
220 if (fFamilies[i]->fStyles[j].get() == familyMember) {
221 return fFamilies[i]->matchStyle(fontStyle);
bungeman5c9fa282015-03-30 12:53:48 -0700222 }
223 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500224 }
225 return nullptr;
226}
227
Mike Reed59227392017-09-26 09:46:08 -0400228sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500229 return this->makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
Ben Wagner8ab590f2017-02-08 17:29:33 -0500230}
231
Mike Reed59227392017-09-26 09:46:08 -0400232sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
233 int ttcIndex) const {
234 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
Ben Wagner8ab590f2017-02-08 17:29:33 -0500235}
236
Mike Reed59227392017-09-26 09:46:08 -0400237sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
238 const SkFontArguments& args) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500239 using Scanner = SkTypeface_FreeType::Scanner;
Ben Wagner8ab590f2017-02-08 17:29:33 -0500240 bool isFixedPitch;
241 SkFontStyle style;
242 SkString name;
243 Scanner::AxisDefinitions axisDefinitions;
Ben Wagnerfc497342017-02-24 11:15:26 -0500244 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
Ben Wagner8ab590f2017-02-08 17:29:33 -0500245 &name, &style, &isFixedPitch, &axisDefinitions))
246 {
halcanary96fcdcc2015-08-27 07:41:13 -0700247 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700248 }
249
Ben Wagnerfc497342017-02-24 11:15:26 -0500250 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
Ben Wagner8ab590f2017-02-08 17:29:33 -0500251 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Ben Wagnerfc497342017-02-24 11:15:26 -0500252 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000253
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500254 auto data = std::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
Ben Wagnerfc497342017-02-24 11:15:26 -0500255 axisValues.get(), axisDefinitions.count());
Mike Reed59227392017-09-26 09:46:08 -0400256 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
Ben Wagner3546ff12017-01-03 13:32:36 -0500257}
bungeman5cf19492015-06-15 15:17:21 -0700258
Mike Reed59227392017-09-26 09:46:08 -0400259sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500260 bool isFixedPitch;
261 SkFontStyle style;
262 SkString name;
263 if (!fScanner.scanFont(data->getStream(), data->getIndex(),
Mike Reed59227392017-09-26 09:46:08 -0400264 &name, &style, &isFixedPitch, nullptr)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700265 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700266 }
Mike Reed59227392017-09-26 09:46:08 -0400267 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
Ben Wagner3546ff12017-01-03 13:32:36 -0500268}
caryclarkfe7ada72016-03-21 06:55:52 -0700269
Mike Reed59227392017-09-26 09:46:08 -0400270sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500271 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
Mike Reed59227392017-09-26 09:46:08 -0400272 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
Ben Wagner8ab590f2017-02-08 17:29:33 -0500273}
caryclarkfe7ada72016-03-21 06:55:52 -0700274
Mike Reed59227392017-09-26 09:46:08 -0400275sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
276 SkFontStyle style) const {
277 sk_sp<SkTypeface> tf;
caryclarkfe7ada72016-03-21 06:55:52 -0700278
Ben Wagner8ab590f2017-02-08 17:29:33 -0500279 if (familyName) {
Mike Reed59227392017-09-26 09:46:08 -0400280 tf.reset(this->onMatchFamilyStyle(familyName, style));
caryclarkfe7ada72016-03-21 06:55:52 -0700281 }
282
Ben Wagner8ab590f2017-02-08 17:29:33 -0500283 if (nullptr == tf) {
Mike Reed59227392017-09-26 09:46:08 -0400284 tf.reset(fDefaultFamily->matchStyle(style));
Ben Wagner8ab590f2017-02-08 17:29:33 -0500285 }
caryclarkfe7ada72016-03-21 06:55:52 -0700286
Ben Wagner8ab590f2017-02-08 17:29:33 -0500287 return tf;
Ben Wagner3546ff12017-01-03 13:32:36 -0500288}