blob: 4e4887d27dc15027b2212a5104d85e29153715ba [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
djsollen@google.com97145162012-05-31 19:55:08 +00008#include "SkFontDescriptor.h"
bungemanf20488b2015-07-29 11:49:40 -07009#include "SkFontHost_FreeType_common.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000010#include "SkFontMgr.h"
bungeman5cf19492015-06-15 15:17:21 -070011#include "SkFontMgr_custom.h"
bungemanf20488b2015-07-29 11:49:40 -070012#include "SkFontStyle.h"
bungemanf93d7112016-09-16 06:24:20 -070013#include "SkMakeUnique.h"
bungemanf20488b2015-07-29 11:49:40 -070014#include "SkRefCnt.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015#include "SkStream.h"
bungemanf20488b2015-07-29 11:49:40 -070016#include "SkString.h"
bungeman@google.comb3d154d2013-11-11 15:53:29 +000017#include "SkTArray.h"
bungemanf20488b2015-07-29 11:49:40 -070018#include "SkTemplates.h"
19#include "SkTypeface.h"
bungemanf20488b2015-07-29 11:49:40 -070020#include "SkTypes.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 Wagner8ab590f2017-02-08 17:29:33 -050050SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
chudy@google.comada44802012-07-30 12:59:12 +000051
reed@google.com292b1d42013-03-22 17:21:59 +000052
Ben Wagner8ab590f2017-02-08 17:29:33 -050053SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
54 const SkFontStyle& style, bool isFixedPitch, bool sysFont,
55 const SkString familyName)
56 : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
57 , fData(std::move(fontData))
58{ }
reed@android.comf244f1b2010-04-16 12:40:08 +000059
Ben Wagner8ab590f2017-02-08 17:29:33 -050060SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
61 *ttcIndex = fData->getIndex();
62 return fData->getStream()->duplicate();
63}
chudy@google.comada44802012-07-30 12:59:12 +000064
Ben Wagner8ab590f2017-02-08 17:29:33 -050065std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
66 return skstd::make_unique<SkFontData>(*fData);
67}
bungeman4772bd52016-06-10 04:14:51 -070068
reed@google.com292b1d42013-03-22 17:21:59 +000069
Ben Wagner8ab590f2017-02-08 17:29:33 -050070SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
71 const SkString familyName, const char path[], int index)
72 : INHERITED(style, isFixedPitch, sysFont, familyName, index)
73 , fPath(path)
74{ }
chudy@google.comada44802012-07-30 12:59:12 +000075
Ben Wagner8ab590f2017-02-08 17:29:33 -050076SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
77 *ttcIndex = this->getIndex();
78 return SkStream::MakeFromFile(fPath.c_str()).release();
79}
reed@android.com8a1c16f2008-12-17 15:59:43 +000080
81///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000082
Ben Wagner8ab590f2017-02-08 17:29:33 -050083SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
bungeman@google.comb3d154d2013-11-11 15:53:29 +000084
Ben Wagner8ab590f2017-02-08 17:29:33 -050085void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
86 fStyles.emplace_back(std::move(typeface));
87}
88
89int SkFontStyleSet_Custom::count() {
90 return fStyles.count();
91}
92
93void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
94 SkASSERT(index < fStyles.count());
95 if (style) {
96 *style = fStyles[index]->fontStyle();
bungeman5c9fa282015-03-30 12:53:48 -070097 }
Ben Wagner8ab590f2017-02-08 17:29:33 -050098 if (name) {
99 name->reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500101}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102
Ben Wagner8ab590f2017-02-08 17:29:33 -0500103SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
104 SkASSERT(index < fStyles.count());
105 return SkRef(fStyles[index].get());
106}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000107
Ben Wagner8ab590f2017-02-08 17:29:33 -0500108SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
109 return this->matchStyleCSS3(pattern);
110}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111
Ben Wagner8ab590f2017-02-08 17:29:33 -0500112SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000113
bungeman5c9fa282015-03-30 12:53:48 -0700114
Ben Wagner8ab590f2017-02-08 17:29:33 -0500115SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
116 loader.loadSystemFonts(fScanner, &fFamilies);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000117
Ben Wagner8ab590f2017-02-08 17:29:33 -0500118 // Try to pick a default font.
119 static const char* defaultNames[] = {
120 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
bungeman5c9fa282015-03-30 12:53:48 -0700121 };
Ben Wagner8ab590f2017-02-08 17:29:33 -0500122 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
123 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
124 if (nullptr == set) {
125 continue;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126 }
bungeman4772bd52016-06-10 04:14:51 -0700127
Ben Wagner8ab590f2017-02-08 17:29:33 -0500128 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
129 SkFontStyle::kNormal_Width,
130 SkFontStyle::kUpright_Slant)));
halcanary96fcdcc2015-08-27 07:41:13 -0700131 if (nullptr == tf) {
Ben Wagner8ab590f2017-02-08 17:29:33 -0500132 continue;
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000133 }
134
Ben Wagner8ab590f2017-02-08 17:29:33 -0500135 fDefaultFamily = set.get();
136 break;
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000137 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500138 if (nullptr == fDefaultFamily) {
139 fDefaultFamily = fFamilies[0].get();
140 }
141}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000142
Ben Wagner8ab590f2017-02-08 17:29:33 -0500143int SkFontMgr_Custom::onCountFamilies() const {
144 return fFamilies.count();
145}
bungeman@google.com2cf84ec2012-09-26 19:16:54 +0000146
Ben Wagner8ab590f2017-02-08 17:29:33 -0500147void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
148 SkASSERT(index < fFamilies.count());
149 familyName->set(fFamilies[index]->getFamilyName());
150}
bungeman5c9fa282015-03-30 12:53:48 -0700151
Ben Wagner8ab590f2017-02-08 17:29:33 -0500152SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
153 SkASSERT(index < fFamilies.count());
154 return SkRef(fFamilies[index].get());
155}
bungeman5c9fa282015-03-30 12:53:48 -0700156
Ben Wagner8ab590f2017-02-08 17:29:33 -0500157SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
158 for (int i = 0; i < fFamilies.count(); ++i) {
159 if (fFamilies[i]->getFamilyName().equals(familyName)) {
160 return SkRef(fFamilies[i].get());
bungeman5c9fa282015-03-30 12:53:48 -0700161 }
162 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500163 return nullptr;
164}
bungeman5c9fa282015-03-30 12:53:48 -0700165
Ben Wagner8ab590f2017-02-08 17:29:33 -0500166SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
167 const SkFontStyle& fontStyle) const
168{
169 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
170 return sset->matchStyle(fontStyle);
171}
172
173SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
174 const SkFontStyle&,
175 const char* bcp47[], int bcp47Count,
176 SkUnichar character) const
177{
178 return nullptr;
179}
180
181SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
182 const SkFontStyle& fontStyle) const
183{
184 for (int i = 0; i < fFamilies.count(); ++i) {
185 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
186 if (fFamilies[i]->fStyles[j].get() == familyMember) {
187 return fFamilies[i]->matchStyle(fontStyle);
bungeman5c9fa282015-03-30 12:53:48 -0700188 }
189 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500190 }
191 return nullptr;
192}
193
194SkTypeface* SkFontMgr_Custom::onCreateFromData(SkData* data, int ttcIndex) const {
195 return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
196}
197
198SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const {
199 return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
200}
201
202SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s,
203 const FontParameters& params) const
204{
205 using Scanner = SkTypeface_FreeType::Scanner;
206 std::unique_ptr<SkStreamAsset> stream(s);
207 bool isFixedPitch;
208 SkFontStyle style;
209 SkString name;
210 Scanner::AxisDefinitions axisDefinitions;
211 if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(),
212 &name, &style, &isFixedPitch, &axisDefinitions))
213 {
halcanary96fcdcc2015-08-27 07:41:13 -0700214 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700215 }
216
Ben Wagner8ab590f2017-02-08 17:29:33 -0500217 int paramAxisCount;
218 const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
219 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
220 Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
bungeman@google.comb3d154d2013-11-11 15:53:29 +0000221
Ben Wagner8ab590f2017-02-08 17:29:33 -0500222 auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(),
223 axisValues.get(), axisDefinitions.count());
224 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
Ben Wagner3546ff12017-01-03 13:32:36 -0500225}
bungeman5cf19492015-06-15 15:17:21 -0700226
Ben Wagner8ab590f2017-02-08 17:29:33 -0500227SkTypeface* SkFontMgr_Custom::onCreateFromFontData(std::unique_ptr<SkFontData> data) const {
228 bool isFixedPitch;
229 SkFontStyle style;
230 SkString name;
231 if (!fScanner.scanFont(data->getStream(), data->getIndex(),
232 &name, &style, &isFixedPitch, nullptr))
bungeman5c9fa282015-03-30 12:53:48 -0700233 {
halcanary96fcdcc2015-08-27 07:41:13 -0700234 return nullptr;
bungeman5c9fa282015-03-30 12:53:48 -0700235 }
Ben Wagner8ab590f2017-02-08 17:29:33 -0500236 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
Ben Wagner3546ff12017-01-03 13:32:36 -0500237}
caryclarkfe7ada72016-03-21 06:55:52 -0700238
Ben Wagner8ab590f2017-02-08 17:29:33 -0500239SkTypeface* SkFontMgr_Custom::onCreateFromFile(const char path[], int ttcIndex) const {
240 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
241 return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
242}
caryclarkfe7ada72016-03-21 06:55:52 -0700243
Ben Wagner8ab590f2017-02-08 17:29:33 -0500244SkTypeface* SkFontMgr_Custom::onLegacyCreateTypeface(const char familyName[],
245 SkFontStyle style) const
246{
247 SkTypeface* tf = nullptr;
caryclarkfe7ada72016-03-21 06:55:52 -0700248
Ben Wagner8ab590f2017-02-08 17:29:33 -0500249 if (familyName) {
250 tf = this->onMatchFamilyStyle(familyName, style);
caryclarkfe7ada72016-03-21 06:55:52 -0700251 }
252
Ben Wagner8ab590f2017-02-08 17:29:33 -0500253 if (nullptr == tf) {
254 tf = fDefaultFamily->matchStyle(style);
255 }
caryclarkfe7ada72016-03-21 06:55:52 -0700256
Ben Wagner8ab590f2017-02-08 17:29:33 -0500257 return tf;
Ben Wagner3546ff12017-01-03 13:32:36 -0500258}