blob: 5194e1f7b73d6afb67bb714324a9f83c7aedd254 [file] [log] [blame]
bungeman8d84c992014-07-24 08:05:09 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
mtklein1ee76512015-11-02 10:20:27 -08008#include "SkTypes.h"
mtklein1ee76512015-11-02 10:20:27 -08009
khushalsagarebc465b2016-02-12 12:42:48 -080010#include "SkData.h"
bungemanf20488b2015-07-29 11:49:40 -070011#include "SkFixed.h"
bungeman8d84c992014-07-24 08:05:09 -070012#include "SkFontDescriptor.h"
13#include "SkFontHost_FreeType_common.h"
14#include "SkFontMgr.h"
bungeman7fa87cd2015-02-06 07:59:19 -080015#include "SkFontMgr_android.h"
bungemanc5308542015-06-23 13:25:46 -070016#include "SkFontMgr_android_parser.h"
bungeman8d84c992014-07-24 08:05:09 -070017#include "SkFontStyle.h"
bungemanf93d7112016-09-16 06:24:20 -070018#include "SkMakeUnique.h"
khushalsagarebc465b2016-02-12 12:42:48 -080019#include "SkOSFile.h"
bungeman24a104d2015-07-30 10:31:57 -070020#include "SkPaint.h"
bungemanf20488b2015-07-29 11:49:40 -070021#include "SkRefCnt.h"
22#include "SkString.h"
bungeman8d84c992014-07-24 08:05:09 -070023#include "SkStream.h"
bungemanf20488b2015-07-29 11:49:40 -070024#include "SkTArray.h"
bungeman8d84c992014-07-24 08:05:09 -070025#include "SkTDArray.h"
26#include "SkTSearch.h"
bungemanf20488b2015-07-29 11:49:40 -070027#include "SkTemplates.h"
bungeman8d84c992014-07-24 08:05:09 -070028#include "SkTypefaceCache.h"
29
Ben Wagneraee878d2017-08-10 13:49:41 -040030#include <algorithm>
bungeman8d84c992014-07-24 08:05:09 -070031#include <limits>
bungeman8d84c992014-07-24 08:05:09 -070032
bungemanf20488b2015-07-29 11:49:40 -070033class SkData;
34
bungeman8d84c992014-07-24 08:05:09 -070035class SkTypeface_Android : public SkTypeface_FreeType {
36public:
bungeman41868fe2015-05-20 09:21:04 -070037 SkTypeface_Android(const SkFontStyle& style,
bungeman8d84c992014-07-24 08:05:09 -070038 bool isFixedPitch,
bungeman4b86bac2014-11-04 10:54:31 -080039 const SkString& familyName)
bungemane3aea102016-07-13 05:16:58 -070040 : INHERITED(style, isFixedPitch)
bungeman41868fe2015-05-20 09:21:04 -070041 , fFamilyName(familyName)
42 { }
bungeman8d84c992014-07-24 08:05:09 -070043
bungeman8d84c992014-07-24 08:05:09 -070044protected:
mtklein36352bf2015-03-25 18:17:31 -070045 void onGetFamilyName(SkString* familyName) const override {
bungemanb374d6a2014-09-17 07:48:59 -070046 *familyName = fFamilyName;
47 }
48
bungeman8d84c992014-07-24 08:05:09 -070049 SkString fFamilyName;
50
51private:
52 typedef SkTypeface_FreeType INHERITED;
53};
54
55class SkTypeface_AndroidSystem : public SkTypeface_Android {
56public:
bungeman4b86bac2014-11-04 10:54:31 -080057 SkTypeface_AndroidSystem(const SkString& pathName,
khushalsagarebc465b2016-02-12 12:42:48 -080058 const bool cacheFontFiles,
bungeman8d84c992014-07-24 08:05:09 -070059 int index,
bungeman41868fe2015-05-20 09:21:04 -070060 const SkFixed* axes, int axesCount,
bungemana4c4a2d2014-10-20 13:33:19 -070061 const SkFontStyle& style,
bungeman8d84c992014-07-24 08:05:09 -070062 bool isFixedPitch,
bungeman4b86bac2014-11-04 10:54:31 -080063 const SkString& familyName,
Ben Wagneraee878d2017-08-10 13:49:41 -040064 const SkTArray<SkLanguage, true>& lang,
djsollen3b625542014-08-14 06:29:02 -070065 FontVariant variantStyle)
bungeman41868fe2015-05-20 09:21:04 -070066 : INHERITED(style, isFixedPitch, familyName)
bungeman65fcd3d2014-08-06 11:12:20 -070067 , fPathName(pathName)
bungeman41868fe2015-05-20 09:21:04 -070068 , fIndex(index)
69 , fAxes(axes, axesCount)
bungeman65fcd3d2014-08-06 11:12:20 -070070 , fLang(lang)
khushalsagarebc465b2016-02-12 12:42:48 -080071 , fVariantStyle(variantStyle)
72 , fFile(cacheFontFiles ? sk_fopen(fPathName.c_str(), kRead_SkFILE_Flag) : nullptr) {
73 if (cacheFontFiles) {
74 SkASSERT(fFile);
75 }
76 }
77
bungemanf93d7112016-09-16 06:24:20 -070078 std::unique_ptr<SkStreamAsset> makeStream() const {
khushalsagarebc465b2016-02-12 12:42:48 -080079 if (fFile) {
bungeman38d909e2016-08-02 14:40:46 -070080 sk_sp<SkData> data(SkData::MakeFromFILE(fFile));
bungemanf93d7112016-09-16 06:24:20 -070081 return data ? skstd::make_unique<SkMemoryStream>(std::move(data)) : nullptr;
khushalsagarebc465b2016-02-12 12:42:48 -080082 }
bungemanf93d7112016-09-16 06:24:20 -070083 return SkStream::MakeFromFile(fPathName.c_str());
khushalsagarebc465b2016-02-12 12:42:48 -080084 }
bungeman8d84c992014-07-24 08:05:09 -070085
bungeman41868fe2015-05-20 09:21:04 -070086 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
bungeman8d84c992014-07-24 08:05:09 -070087 SkASSERT(desc);
88 SkASSERT(serialize);
89 desc->setFamilyName(fFamilyName.c_str());
bungemanb8113782016-07-25 16:54:59 -070090 desc->setStyle(this->fontStyle());
bungeman8d84c992014-07-24 08:05:09 -070091 *serialize = false;
92 }
mtklein36352bf2015-03-25 18:17:31 -070093 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
bungeman8d84c992014-07-24 08:05:09 -070094 *ttcIndex = fIndex;
bungemanf93d7112016-09-16 06:24:20 -070095 return this->makeStream().release();
bungeman8d84c992014-07-24 08:05:09 -070096 }
bungemanf93d7112016-09-16 06:24:20 -070097 std::unique_ptr<SkFontData> onMakeFontData() const override {
98 return skstd::make_unique<SkFontData>(this->makeStream(), fIndex,
99 fAxes.begin(), fAxes.count());
bungeman41868fe2015-05-20 09:21:04 -0700100 }
bungeman8d84c992014-07-24 08:05:09 -0700101
bungeman65fcd3d2014-08-06 11:12:20 -0700102 const SkString fPathName;
bungeman41868fe2015-05-20 09:21:04 -0700103 int fIndex;
104 const SkSTArray<4, SkFixed, true> fAxes;
Ben Wagneraee878d2017-08-10 13:49:41 -0400105 const SkSTArray<4, SkLanguage, true> fLang;
djsollen3b625542014-08-14 06:29:02 -0700106 const FontVariant fVariantStyle;
khushalsagarebc465b2016-02-12 12:42:48 -0800107 SkAutoTCallVProc<FILE, sk_fclose> fFile;
bungeman8d84c992014-07-24 08:05:09 -0700108
109 typedef SkTypeface_Android INHERITED;
110};
111
112class SkTypeface_AndroidStream : public SkTypeface_Android {
113public:
bungemanf93d7112016-09-16 06:24:20 -0700114 SkTypeface_AndroidStream(std::unique_ptr<SkFontData> data,
bungemana4c4a2d2014-10-20 13:33:19 -0700115 const SkFontStyle& style,
bungeman8d84c992014-07-24 08:05:09 -0700116 bool isFixedPitch,
bungeman4b86bac2014-11-04 10:54:31 -0800117 const SkString& familyName)
bungeman41868fe2015-05-20 09:21:04 -0700118 : INHERITED(style, isFixedPitch, familyName)
bungemanf93d7112016-09-16 06:24:20 -0700119 , fData(std::move(data))
bungeman41868fe2015-05-20 09:21:04 -0700120 { }
bungeman8d84c992014-07-24 08:05:09 -0700121
122 virtual void onGetFontDescriptor(SkFontDescriptor* desc,
mtklein36352bf2015-03-25 18:17:31 -0700123 bool* serialize) const override {
bungeman8d84c992014-07-24 08:05:09 -0700124 SkASSERT(desc);
125 SkASSERT(serialize);
126 desc->setFamilyName(fFamilyName.c_str());
bungeman8d84c992014-07-24 08:05:09 -0700127 *serialize = true;
128 }
129
mtklein36352bf2015-03-25 18:17:31 -0700130 SkStreamAsset* onOpenStream(int* ttcIndex) const override {
bungeman41868fe2015-05-20 09:21:04 -0700131 *ttcIndex = fData->getIndex();
Mike Reed98c5d922017-09-15 21:39:47 -0400132 return fData->getStream()->duplicate().release();
bungeman41868fe2015-05-20 09:21:04 -0700133 }
134
bungemanf93d7112016-09-16 06:24:20 -0700135 std::unique_ptr<SkFontData> onMakeFontData() const override {
136 return skstd::make_unique<SkFontData>(*fData);
bungeman8d84c992014-07-24 08:05:09 -0700137 }
138
Bruce Wangebf0cf52018-06-18 14:04:19 -0400139 sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
140 std::unique_ptr<SkFontData> data = this->cloneFontData(args);
141 if (!data) {
142 return nullptr;
143 }
144 return sk_make_sp<SkTypeface_AndroidStream>(std::move(data),
145 this->fontStyle(),
146 this->isFixedPitch(),
147 fFamilyName);
148 }
149
bungeman8d84c992014-07-24 08:05:09 -0700150private:
bungemanf93d7112016-09-16 06:24:20 -0700151 const std::unique_ptr<const SkFontData> fData;
bungeman8d84c992014-07-24 08:05:09 -0700152 typedef SkTypeface_Android INHERITED;
153};
154
bungeman8d84c992014-07-24 08:05:09 -0700155class SkFontStyleSet_Android : public SkFontStyleSet {
bungeman41868fe2015-05-20 09:21:04 -0700156 typedef SkTypeface_FreeType::Scanner Scanner;
157
bungeman8d84c992014-07-24 08:05:09 -0700158public:
khushalsagarebc465b2016-02-12 12:42:48 -0800159 explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& scanner,
160 const bool cacheFontFiles) {
halcanary96fcdcc2015-08-27 07:41:13 -0700161 const SkString* cannonicalFamilyName = nullptr;
bungeman65fcd3d2014-08-06 11:12:20 -0700162 if (family.fNames.count() > 0) {
163 cannonicalFamilyName = &family.fNames[0];
164 }
bungeman8d84c992014-07-24 08:05:09 -0700165 // TODO? make this lazy
tomhudsond3ddea22014-08-11 11:28:00 -0700166 for (int i = 0; i < family.fFonts.count(); ++i) {
167 const FontFileInfo& fontFile = family.fFonts[i];
bungeman8d84c992014-07-24 08:05:09 -0700168
bungeman7fa87cd2015-02-06 07:59:19 -0800169 SkString pathName(family.fBasePath);
170 pathName.append(fontFile.fFileName);
bungeman8d84c992014-07-24 08:05:09 -0700171
bungemanf93d7112016-09-16 06:24:20 -0700172 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(pathName.c_str());
173 if (!stream) {
bungeman7fa87cd2015-02-06 07:59:19 -0800174 SkDEBUGF(("Requested font file %s does not exist or cannot be opened.\n",
175 pathName.c_str()));
bungeman8d84c992014-07-24 08:05:09 -0700176 continue;
177 }
178
bungeman65fcd3d2014-08-06 11:12:20 -0700179 const int ttcIndex = fontFile.fIndex;
180 SkString familyName;
bungemana4c4a2d2014-10-20 13:33:19 -0700181 SkFontStyle style;
bungeman8d84c992014-07-24 08:05:09 -0700182 bool isFixedWidth;
bungeman41868fe2015-05-20 09:21:04 -0700183 Scanner::AxisDefinitions axisDefinitions;
184 if (!scanner.scanFont(stream.get(), ttcIndex,
185 &familyName, &style, &isFixedWidth, &axisDefinitions))
186 {
bungeman7fa87cd2015-02-06 07:59:19 -0800187 SkDEBUGF(("Requested font file %s exists, but is not a valid font.\n",
188 pathName.c_str()));
bungeman8d84c992014-07-24 08:05:09 -0700189 continue;
190 }
191
bungemane85a7542015-04-17 13:51:08 -0700192 int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight();
193 SkFontStyle::Slant slant = style.slant();
194 switch (fontFile.fStyle) {
195 case FontFileInfo::Style::kAuto: slant = style.slant(); break;
196 case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright_Slant; break;
197 case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_Slant; break;
198 default: SkASSERT(false); break;
bungeman4b86bac2014-11-04 10:54:31 -0800199 }
bungemane85a7542015-04-17 13:51:08 -0700200 style = SkFontStyle(weight, style.width(), slant);
bungeman4b86bac2014-11-04 10:54:31 -0800201
djsollen3b625542014-08-14 06:29:02 -0700202 uint32_t variant = family.fVariant;
203 if (kDefault_FontVariant == variant) {
204 variant = kCompact_FontVariant | kElegant_FontVariant;
bungeman65fcd3d2014-08-06 11:12:20 -0700205 }
206
207 // The first specified family name overrides the family name found in the font.
208 // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
209 // all of the specified family names in addition to the names found in the font.
halcanary96fcdcc2015-08-27 07:41:13 -0700210 if (cannonicalFamilyName != nullptr) {
bungeman65fcd3d2014-08-06 11:12:20 -0700211 familyName = *cannonicalFamilyName;
212 }
213
bungeman41868fe2015-05-20 09:21:04 -0700214 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Ben Wagnerfc497342017-02-24 11:15:26 -0500215 SkFontArguments::VariationPosition position = {
216 fontFile.fVariationDesignPosition.begin(),
217 fontFile.fVariationDesignPosition.count()
218 };
219 Scanner::computeAxisValues(axisDefinitions, position,
bungeman47a1e962016-02-25 11:20:01 -0800220 axisValues, familyName);
bungeman41868fe2015-05-20 09:21:04 -0700221
bungemanf6c71072016-01-21 14:17:47 -0800222 fStyles.push_back().reset(new SkTypeface_AndroidSystem(
khushalsagarebc465b2016-02-12 12:42:48 -0800223 pathName, cacheFontFiles, ttcIndex, axisValues.get(), axisDefinitions.count(),
Ben Wagneraee878d2017-08-10 13:49:41 -0400224 style, isFixedWidth, familyName, family.fLanguages, variant));
bungeman8d84c992014-07-24 08:05:09 -0700225 }
226 }
227
mtklein36352bf2015-03-25 18:17:31 -0700228 int count() override {
bungeman8d84c992014-07-24 08:05:09 -0700229 return fStyles.count();
230 }
mtklein36352bf2015-03-25 18:17:31 -0700231 void getStyle(int index, SkFontStyle* style, SkString* name) override {
bungeman8d84c992014-07-24 08:05:09 -0700232 if (index < 0 || fStyles.count() <= index) {
233 return;
234 }
235 if (style) {
bungeman03675682016-08-18 14:36:02 -0700236 *style = fStyles[index]->fontStyle();
bungeman8d84c992014-07-24 08:05:09 -0700237 }
238 if (name) {
239 name->reset();
240 }
241 }
mtklein36352bf2015-03-25 18:17:31 -0700242 SkTypeface_AndroidSystem* createTypeface(int index) override {
bungeman8d84c992014-07-24 08:05:09 -0700243 if (index < 0 || fStyles.count() <= index) {
halcanary96fcdcc2015-08-27 07:41:13 -0700244 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700245 }
246 return SkRef(fStyles[index].get());
247 }
248
mtklein36352bf2015-03-25 18:17:31 -0700249 SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) override {
bungeman03675682016-08-18 14:36:02 -0700250 return static_cast<SkTypeface_AndroidSystem*>(this->matchStyleCSS3(pattern));
bungeman8d84c992014-07-24 08:05:09 -0700251 }
252
253private:
Hal Canary67b39de2016-11-07 11:47:44 -0500254 SkTArray<sk_sp<SkTypeface_AndroidSystem>, true> fStyles;
bungeman8d84c992014-07-24 08:05:09 -0700255
256 friend struct NameToFamily;
257 friend class SkFontMgr_Android;
258
259 typedef SkFontStyleSet INHERITED;
260};
261
262/** On Android a single family can have many names, but our API assumes unique names.
263 * Map names to the back end so that all names for a given family refer to the same
264 * (non-replicated) set of typefaces.
265 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
266 */
267struct NameToFamily {
268 SkString name;
269 SkFontStyleSet_Android* styleSet;
270};
271
272class SkFontMgr_Android : public SkFontMgr {
273public:
bungeman7fa87cd2015-02-06 07:59:19 -0800274 SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom) {
275 SkTDArray<FontFamily*> families;
276 if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fSystemFontUse) {
277 SkString base(custom->fBasePath);
bungemanc5308542015-06-23 13:25:46 -0700278 SkFontMgr_Android_Parser::GetCustomFontFamilies(
279 families, base, custom->fFontsXml, custom->fFallbackFontsXml);
bungeman7fa87cd2015-02-06 07:59:19 -0800280 }
281 if (!custom ||
282 (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSystemFontUse))
283 {
bungemanc5308542015-06-23 13:25:46 -0700284 SkFontMgr_Android_Parser::GetSystemFontFamilies(families);
bungeman7fa87cd2015-02-06 07:59:19 -0800285 }
286 if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem == custom->fSystemFontUse) {
287 SkString base(custom->fBasePath);
bungemanc5308542015-06-23 13:25:46 -0700288 SkFontMgr_Android_Parser::GetCustomFontFamilies(
289 families, base, custom->fFontsXml, custom->fFallbackFontsXml);
bungeman7fa87cd2015-02-06 07:59:19 -0800290 }
khushalsagarebc465b2016-02-12 12:42:48 -0800291 this->buildNameToFamilyMap(families, custom ? custom->fIsolated : false);
bungeman83b24ff2016-08-19 05:03:26 -0700292 this->findDefaultStyleSet();
bungeman7fa87cd2015-02-06 07:59:19 -0800293 families.deleteAll();
bungeman8d84c992014-07-24 08:05:09 -0700294 }
295
296protected:
297 /** Returns not how many families we have, but how many unique names
298 * exist among the families.
299 */
mtklein36352bf2015-03-25 18:17:31 -0700300 int onCountFamilies() const override {
bungeman8d84c992014-07-24 08:05:09 -0700301 return fNameToFamilyMap.count();
302 }
303
mtklein36352bf2015-03-25 18:17:31 -0700304 void onGetFamilyName(int index, SkString* familyName) const override {
bungeman8d84c992014-07-24 08:05:09 -0700305 if (index < 0 || fNameToFamilyMap.count() <= index) {
306 familyName->reset();
307 return;
308 }
309 familyName->set(fNameToFamilyMap[index].name);
310 }
311
mtklein36352bf2015-03-25 18:17:31 -0700312 SkFontStyleSet* onCreateStyleSet(int index) const override {
bungeman8d84c992014-07-24 08:05:09 -0700313 if (index < 0 || fNameToFamilyMap.count() <= index) {
halcanary96fcdcc2015-08-27 07:41:13 -0700314 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700315 }
316 return SkRef(fNameToFamilyMap[index].styleSet);
317 }
318
mtklein36352bf2015-03-25 18:17:31 -0700319 SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
bungeman8d84c992014-07-24 08:05:09 -0700320 if (!familyName) {
halcanary96fcdcc2015-08-27 07:41:13 -0700321 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700322 }
323 SkAutoAsciiToLC tolc(familyName);
324 for (int i = 0; i < fNameToFamilyMap.count(); ++i) {
325 if (fNameToFamilyMap[i].name.equals(tolc.lc())) {
326 return SkRef(fNameToFamilyMap[i].styleSet);
327 }
328 }
bungeman65fcd3d2014-08-06 11:12:20 -0700329 // TODO: eventually we should not need to name fallback families.
330 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
331 if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) {
332 return SkRef(fFallbackNameToFamilyMap[i].styleSet);
333 }
334 }
halcanary96fcdcc2015-08-27 07:41:13 -0700335 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700336 }
337
338 virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
mtklein36352bf2015-03-25 18:17:31 -0700339 const SkFontStyle& style) const override {
Hal Canary67b39de2016-11-07 11:47:44 -0500340 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
bungeman8d84c992014-07-24 08:05:09 -0700341 return sset->matchStyle(style);
342 }
343
344 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
mtklein36352bf2015-03-25 18:17:31 -0700345 const SkFontStyle& style) const override {
bungeman83b24ff2016-08-19 05:03:26 -0700346 for (int i = 0; i < fStyleSets.count(); ++i) {
347 for (int j = 0; j < fStyleSets[i]->fStyles.count(); ++j) {
Hal Canary67b39de2016-11-07 11:47:44 -0500348 if (fStyleSets[i]->fStyles[j].get() == typeface) {
bungeman83b24ff2016-08-19 05:03:26 -0700349 return fStyleSets[i]->matchStyle(style);
bungeman8d84c992014-07-24 08:05:09 -0700350 }
351 }
352 }
halcanary96fcdcc2015-08-27 07:41:13 -0700353 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700354 }
355
bungeman13b9c952016-05-12 10:09:30 -0700356 static sk_sp<SkTypeface_AndroidSystem> find_family_style_character(
bungeman83b24ff2016-08-19 05:03:26 -0700357 const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap,
bungemanc9232dc2014-11-10 13:29:33 -0800358 const SkFontStyle& style, bool elegant,
359 const SkString& langTag, SkUnichar character)
360 {
361 for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) {
362 SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet;
bungeman13b9c952016-05-12 10:09:30 -0700363 sk_sp<SkTypeface_AndroidSystem> face(family->matchStyle(style));
bungemanc20386e2014-10-23 07:08:05 -0700364
Ben Wagneraee878d2017-08-10 13:49:41 -0400365 if (!langTag.isEmpty() &&
366 std::none_of(face->fLang.begin(), face->fLang.end(), [&](SkLanguage lang){
367 return lang.getTag().startsWith(langTag.c_str());
368 }))
369 {
bungemanc9232dc2014-11-10 13:29:33 -0800370 continue;
371 }
372
373 if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
374 continue;
375 }
376
bungeman24a104d2015-07-30 10:31:57 -0700377 SkPaint paint;
378 paint.setTypeface(face);
379 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
380
381 uint16_t glyphID;
382 paint.textToGlyphs(&character, sizeof(character), &glyphID);
scroggo9a9a7b22016-05-12 06:22:30 -0700383 if (glyphID != 0) {
bungeman13b9c952016-05-12 10:09:30 -0700384 return face;
scroggo9a9a7b22016-05-12 06:22:30 -0700385 }
bungemanc20386e2014-10-23 07:08:05 -0700386 }
halcanary96fcdcc2015-08-27 07:41:13 -0700387 return nullptr;
bungemanc20386e2014-10-23 07:08:05 -0700388 }
bungemanc9232dc2014-11-10 13:29:33 -0800389
bungeman65fcd3d2014-08-06 11:12:20 -0700390 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
391 const SkFontStyle& style,
bungemanc20386e2014-10-23 07:08:05 -0700392 const char* bcp47[],
393 int bcp47Count,
mtklein36352bf2015-03-25 18:17:31 -0700394 SkUnichar character) const override
bungeman65fcd3d2014-08-06 11:12:20 -0700395 {
396 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'.
397 // The variant 'default' means 'compact and elegant'.
398 // As a result, it is not possible to know the variant context from the font alone.
399 // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
400
bungemanc20386e2014-10-23 07:08:05 -0700401 // The first time match anything elegant, second time anything not elegant.
402 for (int elegant = 2; elegant --> 0;) {
403 for (int bcp47Index = bcp47Count; bcp47Index --> 0;) {
404 SkLanguage lang(bcp47[bcp47Index]);
405 while (!lang.getTag().isEmpty()) {
bungeman13b9c952016-05-12 10:09:30 -0700406 sk_sp<SkTypeface_AndroidSystem> matchingTypeface =
bungemanc20386e2014-10-23 07:08:05 -0700407 find_family_style_character(fFallbackNameToFamilyMap,
408 style, SkToBool(elegant),
409 lang.getTag(), character);
410 if (matchingTypeface) {
bungeman13b9c952016-05-12 10:09:30 -0700411 return matchingTypeface.release();
bungeman65fcd3d2014-08-06 11:12:20 -0700412 }
413
bungemanc20386e2014-10-23 07:08:05 -0700414 lang = lang.getParent();
bungeman65fcd3d2014-08-06 11:12:20 -0700415 }
bungemanc20386e2014-10-23 07:08:05 -0700416 }
bungeman13b9c952016-05-12 10:09:30 -0700417 sk_sp<SkTypeface_AndroidSystem> matchingTypeface =
bungemanc20386e2014-10-23 07:08:05 -0700418 find_family_style_character(fFallbackNameToFamilyMap,
419 style, SkToBool(elegant),
420 SkString(), character);
421 if (matchingTypeface) {
bungeman13b9c952016-05-12 10:09:30 -0700422 return matchingTypeface.release();
bungemanc20386e2014-10-23 07:08:05 -0700423 }
bungeman65fcd3d2014-08-06 11:12:20 -0700424 }
halcanary96fcdcc2015-08-27 07:41:13 -0700425 return nullptr;
bungeman65fcd3d2014-08-06 11:12:20 -0700426 }
427
Mike Reed59227392017-09-26 09:46:08 -0400428 sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override {
429 return this->makeFromStream(std::unique_ptr<SkStreamAsset>(new SkMemoryStream(std::move(data))),
430 ttcIndex);
bungeman8d84c992014-07-24 08:05:09 -0700431 }
432
Mike Reed59227392017-09-26 09:46:08 -0400433 sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
bungemanf93d7112016-09-16 06:24:20 -0700434 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
Mike Reed59227392017-09-26 09:46:08 -0400435 return stream.get() ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700436 }
437
Mike Reed59227392017-09-26 09:46:08 -0400438 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
439 int ttcIndex) const override {
bungeman8d84c992014-07-24 08:05:09 -0700440 bool isFixedPitch;
bungemana4c4a2d2014-10-20 13:33:19 -0700441 SkFontStyle style;
bungeman8d84c992014-07-24 08:05:09 -0700442 SkString name;
bungemanf93d7112016-09-16 06:24:20 -0700443 if (!fScanner.scanFont(stream.get(), ttcIndex, &name, &style, &isFixedPitch, nullptr)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700444 return nullptr;
bungeman8d84c992014-07-24 08:05:09 -0700445 }
bungemanf93d7112016-09-16 06:24:20 -0700446 auto data = skstd::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0);
Mike Reed59227392017-09-26 09:46:08 -0400447 return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data),
448 style, isFixedPitch, name));
bungeman41868fe2015-05-20 09:21:04 -0700449 }
450
Mike Reed59227392017-09-26 09:46:08 -0400451 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
452 const SkFontArguments& args) const override {
bungemanf6c71072016-01-21 14:17:47 -0800453 using Scanner = SkTypeface_FreeType::Scanner;
bungemanf6c71072016-01-21 14:17:47 -0800454 bool isFixedPitch;
455 SkFontStyle style;
456 SkString name;
457 Scanner::AxisDefinitions axisDefinitions;
Ben Wagnerfc497342017-02-24 11:15:26 -0500458 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
bungemanf93d7112016-09-16 06:24:20 -0700459 &name, &style, &isFixedPitch, &axisDefinitions))
bungemanf6c71072016-01-21 14:17:47 -0800460 {
461 return nullptr;
462 }
463
bungemanf6c71072016-01-21 14:17:47 -0800464 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
Ben Wagnerfc497342017-02-24 11:15:26 -0500465 Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(),
466 axisValues, name);
bungemanf6c71072016-01-21 14:17:47 -0800467
Ben Wagnerfc497342017-02-24 11:15:26 -0500468 auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
bungemanf93d7112016-09-16 06:24:20 -0700469 axisValues.get(), axisDefinitions.count());
Mike Reed59227392017-09-26 09:46:08 -0400470 return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data),
471 style, isFixedPitch, name));
bungemanf6c71072016-01-21 14:17:47 -0800472 }
473
Mike Reed59227392017-09-26 09:46:08 -0400474 sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData> data) const override {
bungeman41868fe2015-05-20 09:21:04 -0700475 SkStreamAsset* stream(data->getStream());
476 bool isFixedPitch;
477 SkFontStyle style;
478 SkString name;
halcanary96fcdcc2015-08-27 07:41:13 -0700479 if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixedPitch, nullptr)) {
480 return nullptr;
bungeman41868fe2015-05-20 09:21:04 -0700481 }
Mike Reed59227392017-09-26 09:46:08 -0400482 return sk_sp<SkTypeface>(new SkTypeface_AndroidStream(std::move(data),
483 style, isFixedPitch, name));
bungeman8d84c992014-07-24 08:05:09 -0700484 }
485
Mike Reed59227392017-09-26 09:46:08 -0400486 sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override {
bsalomon49f085d2014-09-05 13:34:00 -0700487 if (familyName) {
halcanary96fcdcc2015-08-27 07:41:13 -0700488 // On Android, we must return nullptr when we can't find the requested
bungeman8d84c992014-07-24 08:05:09 -0700489 // named typeface so that the system/app can provide their own recovery
490 // mechanism. On other platforms we'd provide a typeface from the
491 // default family instead.
Mike Reed59227392017-09-26 09:46:08 -0400492 return sk_sp<SkTypeface>(this->onMatchFamilyStyle(familyName, style));
bungeman8d84c992014-07-24 08:05:09 -0700493 }
Mike Reed59227392017-09-26 09:46:08 -0400494 return sk_sp<SkTypeface>(fDefaultStyleSet->matchStyle(style));
bungeman8d84c992014-07-24 08:05:09 -0700495 }
496
497
498private:
499
bungeman14df8332014-10-28 15:07:23 -0700500 SkTypeface_FreeType::Scanner fScanner;
501
bungeman83b24ff2016-08-19 05:03:26 -0700502 SkTArray<sk_sp<SkFontStyleSet_Android>, true> fStyleSets;
503 sk_sp<SkFontStyleSet> fDefaultStyleSet;
bungeman8d84c992014-07-24 08:05:09 -0700504
bungeman83b24ff2016-08-19 05:03:26 -0700505 SkTArray<NameToFamily, true> fNameToFamilyMap;
506 SkTArray<NameToFamily, true> fFallbackNameToFamilyMap;
bungeman8d84c992014-07-24 08:05:09 -0700507
khushalsagarebc465b2016-02-12 12:42:48 -0800508 void buildNameToFamilyMap(SkTDArray<FontFamily*> families, const bool isolated) {
bungeman8d84c992014-07-24 08:05:09 -0700509 for (int i = 0; i < families.count(); i++) {
bungeman65fcd3d2014-08-06 11:12:20 -0700510 FontFamily& family = *families[i];
511
bungeman83b24ff2016-08-19 05:03:26 -0700512 SkTArray<NameToFamily, true>* nameToFamily = &fNameToFamilyMap;
bungeman65fcd3d2014-08-06 11:12:20 -0700513 if (family.fIsFallbackFont) {
514 nameToFamily = &fFallbackNameToFamilyMap;
515
516 if (0 == family.fNames.count()) {
517 SkString& fallbackName = family.fNames.push_back();
518 fallbackName.printf("%.2x##fallback", i);
519 }
520 }
521
bungeman83b24ff2016-08-19 05:03:26 -0700522 sk_sp<SkFontStyleSet_Android> newSet =
523 sk_make_sp<SkFontStyleSet_Android>(family, fScanner, isolated);
bungeman65fcd3d2014-08-06 11:12:20 -0700524 if (0 == newSet->count()) {
bungeman65fcd3d2014-08-06 11:12:20 -0700525 continue;
526 }
bungeman65fcd3d2014-08-06 11:12:20 -0700527
bungeman83b24ff2016-08-19 05:03:26 -0700528 for (const SkString& name : family.fNames) {
529 nameToFamily->emplace_back(NameToFamily{name, newSet.get()});
bungeman8d84c992014-07-24 08:05:09 -0700530 }
bungeman83b24ff2016-08-19 05:03:26 -0700531 fStyleSets.emplace_back(std::move(newSet));
bungeman8d84c992014-07-24 08:05:09 -0700532 }
533 }
534
bungeman83b24ff2016-08-19 05:03:26 -0700535 void findDefaultStyleSet() {
536 SkASSERT(!fStyleSets.empty());
bungeman8d84c992014-07-24 08:05:09 -0700537
bungeman83b24ff2016-08-19 05:03:26 -0700538 static const char* defaultNames[] = { "sans-serif" };
539 for (const char* defaultName : defaultNames) {
540 fDefaultStyleSet.reset(this->onMatchFamily(defaultName));
541 if (fDefaultStyleSet) {
542 break;
bungeman8d84c992014-07-24 08:05:09 -0700543 }
bungeman8d84c992014-07-24 08:05:09 -0700544 }
bungeman83b24ff2016-08-19 05:03:26 -0700545 if (nullptr == fDefaultStyleSet) {
546 fDefaultStyleSet = fStyleSets[0];
bungeman8d84c992014-07-24 08:05:09 -0700547 }
bungeman83b24ff2016-08-19 05:03:26 -0700548 SkASSERT(fDefaultStyleSet);
bungeman8d84c992014-07-24 08:05:09 -0700549 }
550
551 typedef SkFontMgr INHERITED;
552};
553
bungeman7fa87cd2015-02-06 07:59:19 -0800554#ifdef SK_DEBUG
555static char const * const gSystemFontUseStrings[] = {
556 "OnlyCustom", "PreferCustom", "PreferSystem"
557};
558#endif
Ben Wagner20d031a2017-01-11 13:54:39 -0500559
Ben Wagner3546ff12017-01-03 13:32:36 -0500560sk_sp<SkFontMgr> SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) {
bungeman7fa87cd2015-02-06 07:59:19 -0800561 if (custom) {
562 SkASSERT(0 <= custom->fSystemFontUse);
563 SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings));
564 SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n",
565 gSystemFontUseStrings[custom->fSystemFontUse],
566 custom->fBasePath,
567 custom->fFontsXml,
568 custom->fFallbackFontsXml));
bungeman4e3523c2014-08-08 12:06:51 -0700569 }
Ben Wagner3546ff12017-01-03 13:32:36 -0500570 return sk_make_sp<SkFontMgr_Android>(custom);
bungeman8d84c992014-07-24 08:05:09 -0700571}