blob: 708f4a6e67df45aa2df669fa451ae41e0668fa7a [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
Ben Wagnerfc497342017-02-24 11:15:26 -05008#include "SkFontArguments.h"
djsollen@google.com97145162012-05-31 19:55:08 +00009#include "SkFontDescriptor.h"
bungemanf20488b2015-07-29 11:49:40 -070010#include "SkFontHost_FreeType_common.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000011#include "SkFontMgr.h"
bungeman5cf19492015-06-15 15:17:21 -070012#include "SkFontMgr_custom.h"
bungemanf20488b2015-07-29 11:49:40 -070013#include "SkFontStyle.h"
bungemanf93d7112016-09-16 06:24:20 -070014#include "SkMakeUnique.h"
bungemanf20488b2015-07-29 11:49:40 -070015#include "SkRefCnt.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000016#include "SkStream.h"
bungemanf20488b2015-07-29 11:49:40 -070017#include "SkString.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000018#include "SkTArray.h"
bungemanf20488b2015-07-29 11:49:40 -070019#include "SkTemplates.h"
20#include "SkTypeface.h"
bungemanf20488b2015-07-29 11:49:40 -070021#include "SkTypes.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000022
23#include <limits>
bungeman4772bd52016-06-10 04:14:51 -070024#include <memory>
reed@android.com8a1c16f2008-12-17 15:59:43 +000025
bungemanf20488b2015-07-29 11:49:40 -070026class SkData;
27
Ben Wagner8ab590f2017-02-08 17:29:33 -050028SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
29 bool sysFont, const SkString familyName, int index)
30 : INHERITED(style, isFixedPitch)
31 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
32{ }
chudy@google.comada44802012-07-30 12:59:12 +000033
Ben Wagner8ab590f2017-02-08 17:29:33 -050034bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
reed@google.com292b1d42013-03-22 17:21:59 +000035
Ben Wagner8ab590f2017-02-08 17:29:33 -050036void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
37 *familyName = fFamilyName;
38}
bungemanb374d6a2014-09-17 07:48:59 -070039
Ben Wagner8ab590f2017-02-08 17:29:33 -050040void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
41 desc->setFamilyName(fFamilyName.c_str());
42 desc->setStyle(this->fontStyle());
43 *isLocal = !this->isSysFont();
44}
reed@google.com5526ede2013-03-25 13:03:37 +000045
Ben Wagner8ab590f2017-02-08 17:29:33 -050046int SkTypeface_Custom::getIndex() const { return fIndex; }
bungemand71b7572014-09-18 10:55:32 -070047
chudy@google.comada44802012-07-30 12:59:12 +000048
Ben Wagner8ab590f2017-02-08 17:29:33 -050049SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
reed@android.com8a1c16f2008-12-17 15:59:43 +000050
Ben Wagner8ab590f2017-02-08 17:29:33 -050051SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
chudy@google.comada44802012-07-30 12:59:12 +000052
Bruce Wang0ea256c2018-06-22 15:44:47 -040053sk_sp<SkTypeface> SkTypeface_Empty::onMakeClone(const SkFontArguments& args) const {
54 return sk_ref_sp(this);
55}
reed@google.com292b1d42013-03-22 17:21:59 +000056
Ben Wagner8ab590f2017-02-08 17:29:33 -050057SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
58 const SkFontStyle& style, bool isFixedPitch, bool sysFont,
59 const SkString familyName)
60 : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
61 , fData(std::move(fontData))
62{ }
reed@android.comf244f1b2010-04-16 12:40:08 +000063
Ben Wagner8ab590f2017-02-08 17:29:33 -050064SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
65 *ttcIndex = fData->getIndex();
Mike Reed98c5d922017-09-15 21:39:47 -040066 return fData->getStream()->duplicate().release();
Ben Wagner8ab590f2017-02-08 17:29:33 -050067}
chudy@google.comada44802012-07-30 12:59:12 +000068
Ben Wagner8ab590f2017-02-08 17:29:33 -050069std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
70 return skstd::make_unique<SkFontData>(*fData);
71}
bungeman4772bd52016-06-10 04:14:51 -070072
Bruce Wang0ea256c2018-06-22 15:44:47 -040073sk_sp<SkTypeface> SkTypeface_Stream::onMakeClone(const SkFontArguments& args) const {
74 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
75 if (!data) {
76 return nullptr;
77 }
78
79 SkString familyName;
80 this->getFamilyName(&familyName);
81
82 return sk_make_sp<SkTypeface_Stream>(std::move(data),
83 this->fontStyle(),
84 this->isFixedPitch(),
85 this->isSysFont(),
86 familyName);
87}
reed@google.com292b1d42013-03-22 17:21:59 +000088
Ben Wagner8ab590f2017-02-08 17:29:33 -050089SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
90 const SkString familyName, const char path[], int index)
91 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
92 , fPath(path)
93{ }
chudy@google.comada44802012-07-30 12:59:12 +000094
Ben Wagner8ab590f2017-02-08 17:29:33 -050095SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
96 *ttcIndex = this->getIndex();
97 return SkStream::MakeFromFile(fPath.c_str()).release();
98}
reed@android.com8a1c16f2008-12-17 15:59:43 +000099
Bruce Wang0ea256c2018-06-22 15:44:47 -0400100sk_sp<SkTypeface> SkTypeface_File::onMakeClone(const SkFontArguments& args) const {
101 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
102 if (!data) {
103 return nullptr;
104 }
105
106 SkString familyName;
107 this->getFamilyName(&familyName);
108
109 return sk_make_sp<SkTypeface_Stream>(std::move(data),
110 this->fontStyle(),
111 this->isFixedPitch(),
112 this->isSysFont(),
113 familyName);
114}
115
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117
Ben Wagner8ab590f2017-02-08 17:29:33 -0500118SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000119
Ben Wagner8ab590f2017-02-08 17:29:33 -0500120void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
121 fStyles.emplace_back(std::move(typeface));
122}
123
124int SkFontStyleSet_Custom::count() {
125 return fStyles.count();
126}
127
128void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
129 SkASSERT(index < fStyles.count());
130 if (style) {
131 *style = fStyles[index]->fontStyle();
bungeman5c9fa282015-03-30 12:53:48 -0700132 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500133 if (name) {
134 name->reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500136}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137
Ben Wagner8ab590f2017-02-08 17:29:33 -0500138SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
139 SkASSERT(index < fStyles.count());
140 return SkRef(fStyles[index].get());
141}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000142
Ben Wagner8ab590f2017-02-08 17:29:33 -0500143SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
144 return this->matchStyleCSS3(pattern);
145}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146
Ben Wagner8ab590f2017-02-08 17:29:33 -0500147SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000148
bungeman5c9fa282015-03-30 12:53:48 -0700149
Ben Wagner8ab590f2017-02-08 17:29:33 -0500150SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
151 loader.loadSystemFonts(fScanner, &fFamilies);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000152
Ben Wagner8ab590f2017-02-08 17:29:33 -0500153 // Try to pick a default font.
154 static const char* defaultNames[] = {
155 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
bungeman5c9fa282015-03-30 12:53:48 -0700156 };
Ben Wagner8ab590f2017-02-08 17:29:33 -0500157 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
158 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
159 if (nullptr == set) {
160 continue;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000161 }
bungeman4772bd52016-06-10 04:14:51 -0700162
Ben Wagner8ab590f2017-02-08 17:29:33 -0500163 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
164 SkFontStyle::kNormal_Width,
165 SkFontStyle::kUpright_Slant)));
halcanary96fcdcc2015-08-27 07:41:13 -0700166 if (nullptr == tf) {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500167 continue;
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000168 }
169
Ben Wagner8ab590f2017-02-08 17:29:33 -0500170 fDefaultFamily = set.get();
171 break;
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000172 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500173 if (nullptr == fDefaultFamily) {
174 fDefaultFamily = fFamilies[0].get();
175 }
176}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000177
Ben Wagner8ab590f2017-02-08 17:29:33 -0500178int SkFontMgr_Custom::onCountFamilies() const {
179 return fFamilies.count();
180}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000181
Ben Wagner8ab590f2017-02-08 17:29:33 -0500182void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
183 SkASSERT(index < fFamilies.count());
184 familyName->set(fFamilies[index]->getFamilyName());
185}
bungeman5c9fa282015-03-30 12:53:48 -0700186
Ben Wagner8ab590f2017-02-08 17:29:33 -0500187SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
188 SkASSERT(index < fFamilies.count());
189 return SkRef(fFamilies[index].get());
190}
bungeman5c9fa282015-03-30 12:53:48 -0700191
Ben Wagner8ab590f2017-02-08 17:29:33 -0500192SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
193 for (int i = 0; i < fFamilies.count(); ++i) {
194 if (fFamilies[i]->getFamilyName().equals(familyName)) {
195 return SkRef(fFamilies[i].get());
bungeman5c9fa282015-03-30 12:53:48 -0700196 }
197 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500198 return nullptr;
199}
bungeman5c9fa282015-03-30 12:53:48 -0700200
Ben Wagner8ab590f2017-02-08 17:29:33 -0500201SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
202 const SkFontStyle& fontStyle) const
203{
204 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
205 return sset->matchStyle(fontStyle);
206}
207
208SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
209 const SkFontStyle&,
210 const char* bcp47[], int bcp47Count,
211 SkUnichar character) const
212{
213 return nullptr;
214}
215
216SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
217 const SkFontStyle& fontStyle) const
218{
219 for (int i = 0; i < fFamilies.count(); ++i) {
220 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
221 if (fFamilies[i]->fStyles[j].get() == familyMember) {
222 return fFamilies[i]->matchStyle(fontStyle);
bungeman5c9fa282015-03-30 12:53:48 -0700223 }
224 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500225 }
226 return nullptr;
227}
228
Mike Reed59227392017-09-26 09:46:08 -0400229sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
230 return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
Ben Wagner8ab590f2017-02-08 17:29:33 -0500231}
232
Mike Reed59227392017-09-26 09:46:08 -0400233sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
234 int ttcIndex) const {
235 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex));
Ben Wagner8ab590f2017-02-08 17:29:33 -0500236}
237
Mike Reed59227392017-09-26 09:46:08 -0400238sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
239 const SkFontArguments& args) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500240 using Scanner = SkTypeface_FreeType::Scanner;
Ben Wagner8ab590f2017-02-08 17:29:33 -0500241 bool isFixedPitch;
242 SkFontStyle style;
243 SkString name;
244 Scanner::AxisDefinitions axisDefinitions;
Ben Wagnerfc497342017-02-24 11:15:26 -0500245 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
Ben Wagner8ab590f2017-02-08 17:29:33 -0500246 &name, &style, &isFixedPitch, &axisDefinitions))
247 {
halcanary96fcdcc2015-08-27 07:41:13 -0700248 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700249 }
250
Ben Wagnerfc497342017-02-24 11:15:26 -0500251 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
Ben Wagner8ab590f2017-02-08 17:29:33 -0500252 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Ben Wagnerfc497342017-02-24 11:15:26 -0500253 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000254
Ben Wagnerfc497342017-02-24 11:15:26 -0500255 auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
256 axisValues.get(), axisDefinitions.count());
Mike Reed59227392017-09-26 09:46:08 -0400257 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
Ben Wagner3546ff12017-01-03 13:32:36 -0500258}
bungeman5cf19492015-06-15 15:17:21 -0700259
Mike Reed59227392017-09-26 09:46:08 -0400260sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500261 bool isFixedPitch;
262 SkFontStyle style;
263 SkString name;
264 if (!fScanner.scanFont(data->getStream(), data->getIndex(),
Mike Reed59227392017-09-26 09:46:08 -0400265 &name, &style, &isFixedPitch, nullptr)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700266 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700267 }
Mike Reed59227392017-09-26 09:46:08 -0400268 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name));
Ben Wagner3546ff12017-01-03 13:32:36 -0500269}
caryclarkfe7ada72016-03-21 06:55:52 -0700270
Mike Reed59227392017-09-26 09:46:08 -0400271sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500272 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
Mike Reed59227392017-09-26 09:46:08 -0400273 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
Ben Wagner8ab590f2017-02-08 17:29:33 -0500274}
caryclarkfe7ada72016-03-21 06:55:52 -0700275
Mike Reed59227392017-09-26 09:46:08 -0400276sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[],
277 SkFontStyle style) const {
278 sk_sp<SkTypeface> tf;
caryclarkfe7ada72016-03-21 06:55:52 -0700279
Ben Wagner8ab590f2017-02-08 17:29:33 -0500280 if (familyName) {
Mike Reed59227392017-09-26 09:46:08 -0400281 tf.reset(this->onMatchFamilyStyle(familyName, style));
caryclarkfe7ada72016-03-21 06:55:52 -0700282 }
283
Ben Wagner8ab590f2017-02-08 17:29:33 -0500284 if (nullptr == tf) {
Mike Reed59227392017-09-26 09:46:08 -0400285 tf.reset(fDefaultFamily->matchStyle(style));
Ben Wagner8ab590f2017-02-08 17:29:33 -0500286 }
caryclarkfe7ada72016-03-21 06:55:52 -0700287
Ben Wagner8ab590f2017-02-08 17:29:33 -0500288 return tf;
Ben Wagner3546ff12017-01-03 13:32:36 -0500289}