18d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman/* 28d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * Copyright 2014 Google Inc. 38d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * 48d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * Use of this source code is governed by a BSD-style license that can be 58d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * found in the LICENSE file. 68d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */ 78d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 81ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include "SkTypes.h" 91ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 10ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar#include "SkData.h" 11f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkFixed.h" 128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontDescriptor.h" 138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontHost_FreeType_common.h" 148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontMgr.h" 157fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#include "SkFontMgr_android.h" 16c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman#include "SkFontMgr_android_parser.h" 178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkFontStyle.h" 18ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar#include "SkOSFile.h" 1924a104d94696bc4b5170e82a28ef05053b302a2dbungeman#include "SkPaint.h" 20f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkRefCnt.h" 21f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkString.h" 228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkStream.h" 23f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTArray.h" 248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTDArray.h" 258d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTSearch.h" 26f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTemplates.h" 278d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include "SkTypefaceCache.h" 288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman#include <limits> 308d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 31f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungemanclass SkData; 32f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman 338d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_Android : public SkTypeface_FreeType { 348d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic: 3541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkTypeface_Android(const SkFontStyle& style, 368d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman bool isFixedPitch, 374b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman const SkString& familyName) 388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) 3941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman , fFamilyName(familyName) 4041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman { } 418d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 428d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprotected: 4336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFamilyName(SkString* familyName) const override { 44b374d6a62c0259387d90cad74753d8bad9ee1beabungeman *familyName = fFamilyName; 45b374d6a62c0259387d90cad74753d8bad9ee1beabungeman } 46b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkString fFamilyName; 488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 498d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate: 508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman typedef SkTypeface_FreeType INHERITED; 518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 538d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_AndroidSystem : public SkTypeface_Android { 548d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic: 554b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman SkTypeface_AndroidSystem(const SkString& pathName, 56ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar const bool cacheFontFiles, 578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman int index, 5841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const SkFixed* axes, int axesCount, 59a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman const SkFontStyle& style, 608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman bool isFixedPitch, 614b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman const SkString& familyName, 6265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman const SkLanguage& lang, 633b6255493e458c6b2c1412af908581f0bf3f6b70djsollen FontVariant variantStyle) 6441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman : INHERITED(style, isFixedPitch, familyName) 6565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman , fPathName(pathName) 6641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman , fIndex(index) 6741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman , fAxes(axes, axesCount) 6865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman , fLang(lang) 69ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar , fVariantStyle(variantStyle) 70ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar , fFile(cacheFontFiles ? sk_fopen(fPathName.c_str(), kRead_SkFILE_Flag) : nullptr) { 71ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar if (cacheFontFiles) { 72ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar SkASSERT(fFile); 73ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar } 74ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar } 75ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar 76ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar SkStreamAsset* createStream() const { 77ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar if (fFile) { 78ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar SkData* data = SkData::NewFromFILE(fFile); 79ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar return data ? new SkMemoryStream(data) : nullptr; 80ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar } 81ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar return SkStream::NewFromFile(fPathName.c_str()); 82ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar } 838d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 8441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override { 858d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(desc); 868d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(serialize); 878d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman desc->setFamilyName(fFamilyName.c_str()); 888d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *serialize = false; 898d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 9036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkStreamAsset* onOpenStream(int* ttcIndex) const override { 918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *ttcIndex = fIndex; 92ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar return this->createStream(); 938d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 9441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkFontData* onCreateFontData() const override { 95ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar return new SkFontData(this->createStream(), fIndex, fAxes.begin(), fAxes.count()); 9641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 978d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 9865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman const SkString fPathName; 9941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman int fIndex; 10041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const SkSTArray<4, SkFixed, true> fAxes; 10165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman const SkLanguage fLang; 1023b6255493e458c6b2c1412af908581f0bf3f6b70djsollen const FontVariant fVariantStyle; 103ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar SkAutoTCallVProc<FILE, sk_fclose> fFile; 1048d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 1058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman typedef SkTypeface_Android INHERITED; 1068d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 1078d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 1088d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkTypeface_AndroidStream : public SkTypeface_Android { 1098d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic: 11041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkTypeface_AndroidStream(SkFontData* data, 111a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman const SkFontStyle& style, 1128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman bool isFixedPitch, 1134b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman const SkString& familyName) 11441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman : INHERITED(style, isFixedPitch, familyName) 11541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman , fData(data) 11641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman { } 1178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 1188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman virtual void onGetFontDescriptor(SkFontDescriptor* desc, 11936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool* serialize) const override { 1208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(desc); 1218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(serialize); 1228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman desc->setFamilyName(fFamilyName.c_str()); 1238d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *serialize = true; 1248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 1258d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 12636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkStreamAsset* onOpenStream(int* ttcIndex) const override { 12741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman *ttcIndex = fData->getIndex(); 12841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman return fData->duplicateStream(); 1293489ee0f4fa34f124f9de090d12bdc2107d52aa9bungeman } 1305ae1312c9faa25531c07e591b4dff6804020f121bungeman 13141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkFontData* onCreateFontData() const override { 13241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman return new SkFontData(*fData.get()); 13341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 134465706820d0d373f76ab4831c286115ee0d86b7arobertphillips 13541868fe5625fc3bd70daa3f461c881b5db6a9265bungemanprivate: 13641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const SkAutoTDelete<const SkFontData> fData; 1378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman typedef SkTypeface_Android INHERITED; 1388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 1398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 1408d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkFontStyleSet_Android : public SkFontStyleSet { 14141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman typedef SkTypeface_FreeType::Scanner Scanner; 14241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 1438d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic: 144ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar explicit SkFontStyleSet_Android(const FontFamily& family, const Scanner& scanner, 145ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar const bool cacheFontFiles) { 14696fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkString* cannonicalFamilyName = nullptr; 14765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman if (family.fNames.count() > 0) { 14865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman cannonicalFamilyName = &family.fNames[0]; 14965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 1508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman // TODO? make this lazy 151d3ddea284ec6611a93a6b75e64de39d0bc7e083ctomhudson for (int i = 0; i < family.fFonts.count(); ++i) { 152d3ddea284ec6611a93a6b75e64de39d0bc7e083ctomhudson const FontFileInfo& fontFile = family.fFonts[i]; 1538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 1547fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkString pathName(family.fBasePath); 1557fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman pathName.append(fontFile.fFileName); 1568d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 157a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str())); 1588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (!stream.get()) { 1597fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkDEBUGF(("Requested font file %s does not exist or cannot be opened.\n", 1607fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman pathName.c_str())); 1618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman continue; 1628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 1638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 16465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman const int ttcIndex = fontFile.fIndex; 16565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkString familyName; 166a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman SkFontStyle style; 1678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman bool isFixedWidth; 16841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman Scanner::AxisDefinitions axisDefinitions; 16941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman if (!scanner.scanFont(stream.get(), ttcIndex, 17041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman &familyName, &style, &isFixedWidth, &axisDefinitions)) 17141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman { 1727fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkDEBUGF(("Requested font file %s exists, but is not a valid font.\n", 1737fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman pathName.c_str())); 1748d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman continue; 1758d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 1768d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 177e85a754a4ce9b279159270faa6717932f7a8548fbungeman int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight(); 178e85a754a4ce9b279159270faa6717932f7a8548fbungeman SkFontStyle::Slant slant = style.slant(); 179e85a754a4ce9b279159270faa6717932f7a8548fbungeman switch (fontFile.fStyle) { 180e85a754a4ce9b279159270faa6717932f7a8548fbungeman case FontFileInfo::Style::kAuto: slant = style.slant(); break; 181e85a754a4ce9b279159270faa6717932f7a8548fbungeman case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright_Slant; break; 182e85a754a4ce9b279159270faa6717932f7a8548fbungeman case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_Slant; break; 183e85a754a4ce9b279159270faa6717932f7a8548fbungeman default: SkASSERT(false); break; 1844b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman } 185e85a754a4ce9b279159270faa6717932f7a8548fbungeman style = SkFontStyle(weight, style.width(), slant); 1864b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman 1873b6255493e458c6b2c1412af908581f0bf3f6b70djsollen const SkLanguage& lang = family.fLanguage; 1883b6255493e458c6b2c1412af908581f0bf3f6b70djsollen uint32_t variant = family.fVariant; 1893b6255493e458c6b2c1412af908581f0bf3f6b70djsollen if (kDefault_FontVariant == variant) { 1903b6255493e458c6b2c1412af908581f0bf3f6b70djsollen variant = kCompact_FontVariant | kElegant_FontVariant; 19165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 19265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 19365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // The first specified family name overrides the family name found in the font. 19465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return 19565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // all of the specified family names in addition to the names found in the font. 19696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (cannonicalFamilyName != nullptr) { 19765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman familyName = *cannonicalFamilyName; 19865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 19965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 20041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 20147a1e96b957b50662274360f1a390d76ab3d02ccbungeman Scanner::computeAxisValues(axisDefinitions, 20247a1e96b957b50662274360f1a390d76ab3d02ccbungeman fontFile.fAxes.begin(), fontFile.fAxes.count(), 20347a1e96b957b50662274360f1a390d76ab3d02ccbungeman axisValues, familyName); 20441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 205f6c7107d0385cc2b556802354b93b7dcff61570dbungeman fStyles.push_back().reset(new SkTypeface_AndroidSystem( 206ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar pathName, cacheFontFiles, ttcIndex, axisValues.get(), axisDefinitions.count(), 207ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar style, isFixedWidth, familyName, lang, variant)); 2088d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2098d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 21136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int count() override { 2128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return fStyles.count(); 2138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 21436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getStyle(int index, SkFontStyle* style, SkString* name) override { 2158d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (index < 0 || fStyles.count() <= index) { 2168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return; 2178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (style) { 2198d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman *style = this->style(index); 2208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (name) { 2228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman name->reset(); 2238d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 22536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface_AndroidSystem* createTypeface(int index) override { 2268d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (index < 0 || fStyles.count() <= index) { 22796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 2288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return SkRef(fStyles[index].get()); 2308d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2318d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2328d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman /** Find the typeface in this style set that most closely matches the given pattern. 2338d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); 2348d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * this simpler version using match_score() passes all our tests. 2358d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */ 23636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) override { 2378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (0 == fStyles.count()) { 23896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 2398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 24065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkTypeface_AndroidSystem* closest = fStyles[0]; 2418d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman int minScore = std::numeric_limits<int>::max(); 2428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (int i = 0; i < fStyles.count(); ++i) { 2438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkFontStyle style = this->style(i); 2448d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman int score = match_score(pattern, style); 2458d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (score < minScore) { 2468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman closest = fStyles[i]; 2478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman minScore = score; 2488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return SkRef(closest); 2518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2538d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate: 2548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkFontStyle style(int index) { 2554b86bacb0428b07cba01fd46452d5c46e6f21af0bungeman return fStyles[index]->fontStyle(); 2568d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) { 2588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman int score = 0; 259f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman score += SkTAbs((pattern.width() - candidate.width()) * 100); 260f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman score += SkTAbs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000); 261f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman score += SkTAbs(pattern.weight() - candidate.weight()); 2628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return score; 2638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 2648d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 26565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles; 2668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman friend struct NameToFamily; 2688d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman friend class SkFontMgr_Android; 2698d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2708d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman typedef SkFontStyleSet INHERITED; 2718d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 2728d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2738d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman/** On Android a single family can have many names, but our API assumes unique names. 2748d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * Map names to the back end so that all names for a given family refer to the same 2758d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * (non-replicated) set of typefaces. 2768d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping. 2778d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */ 2788d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanstruct NameToFamily { 2798d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkString name; 2808d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkFontStyleSet_Android* styleSet; 2818d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 2828d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 2838d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanclass SkFontMgr_Android : public SkFontMgr { 2848d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanpublic: 2857fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom) { 2867fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkTDArray<FontFamily*> families; 2877fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fSystemFontUse) { 2887fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkString base(custom->fBasePath); 289c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman SkFontMgr_Android_Parser::GetCustomFontFamilies( 290c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman families, base, custom->fFontsXml, custom->fFallbackFontsXml); 2917fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman } 2927fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman if (!custom || 2937fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSystemFontUse)) 2947fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman { 295c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman SkFontMgr_Android_Parser::GetSystemFontFamilies(families); 2967fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman } 2977fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem == custom->fSystemFontUse) { 2987fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkString base(custom->fBasePath); 299c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman SkFontMgr_Android_Parser::GetCustomFontFamilies( 300c53085413e0b4704aa89cc18396613d59e6ccb4dbungeman families, base, custom->fFontsXml, custom->fFallbackFontsXml); 3017fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman } 302ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar this->buildNameToFamilyMap(families, custom ? custom->fIsolated : false); 3038d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman this->findDefaultFont(); 3047fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman families.deleteAll(); 3058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3068d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 3078d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprotected: 3088d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman /** Returns not how many families we have, but how many unique names 3098d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman * exist among the families. 3108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman */ 31136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int onCountFamilies() const override { 3128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return fNameToFamilyMap.count(); 3138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 31536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFamilyName(int index, SkString* familyName) const override { 3168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (index < 0 || fNameToFamilyMap.count() <= index) { 3178d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman familyName->reset(); 3188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return; 3198d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3208d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman familyName->set(fNameToFamilyMap[index].name); 3218d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3228d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 32336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkFontStyleSet* onCreateStyleSet(int index) const override { 3248d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (index < 0 || fNameToFamilyMap.count() <= index) { 32596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3268d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3278d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return SkRef(fNameToFamilyMap[index].styleSet); 3288d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3298d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 33036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkFontStyleSet* onMatchFamily(const char familyName[]) const override { 3318d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (!familyName) { 33296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3338d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3348d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkAutoAsciiToLC tolc(familyName); 3358d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (int i = 0; i < fNameToFamilyMap.count(); ++i) { 3368d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (fNameToFamilyMap[i].name.equals(tolc.lc())) { 3378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return SkRef(fNameToFamilyMap[i].styleSet); 3388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3398d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 34065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // TODO: eventually we should not need to name fallback families. 34165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { 34265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { 34365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman return SkRef(fFallbackNameToFamilyMap[i].styleSet); 34465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 34565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 34696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 3498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman virtual SkTypeface* onMatchFamilyStyle(const char familyName[], 35036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const SkFontStyle& style) const override { 3518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); 3528d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return sset->matchStyle(style); 3538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 3558d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, 35636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const SkFontStyle& style) const override { 3578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (int i = 0; i < fFontStyleSets.count(); ++i) { 3588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { 3598d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman if (fFontStyleSets[i]->fStyles[j] == typeface) { 3608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman return fFontStyleSets[i]->matchStyle(style); 3618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3638d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 36496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3658d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 3668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 367c9232dcda016feb2d30abb51483b3b1862775f84bungeman static SkTypeface_AndroidSystem* find_family_style_character( 368c9232dcda016feb2d30abb51483b3b1862775f84bungeman const SkTDArray<NameToFamily>& fallbackNameToFamilyMap, 369c9232dcda016feb2d30abb51483b3b1862775f84bungeman const SkFontStyle& style, bool elegant, 370c9232dcda016feb2d30abb51483b3b1862775f84bungeman const SkString& langTag, SkUnichar character) 371c9232dcda016feb2d30abb51483b3b1862775f84bungeman { 372c9232dcda016feb2d30abb51483b3b1862775f84bungeman for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) { 373c9232dcda016feb2d30abb51483b3b1862775f84bungeman SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet; 374c9232dcda016feb2d30abb51483b3b1862775f84bungeman SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style)); 375c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman 376c9232dcda016feb2d30abb51483b3b1862775f84bungeman if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c_str())) { 377c9232dcda016feb2d30abb51483b3b1862775f84bungeman continue; 378c9232dcda016feb2d30abb51483b3b1862775f84bungeman } 379c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman 380c9232dcda016feb2d30abb51483b3b1862775f84bungeman if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) { 381c9232dcda016feb2d30abb51483b3b1862775f84bungeman continue; 382c9232dcda016feb2d30abb51483b3b1862775f84bungeman } 383c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman 38424a104d94696bc4b5170e82a28ef05053b302a2dbungeman SkPaint paint; 38524a104d94696bc4b5170e82a28ef05053b302a2dbungeman paint.setTypeface(face); 38624a104d94696bc4b5170e82a28ef05053b302a2dbungeman paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); 38724a104d94696bc4b5170e82a28ef05053b302a2dbungeman 38824a104d94696bc4b5170e82a28ef05053b302a2dbungeman uint16_t glyphID; 38924a104d94696bc4b5170e82a28ef05053b302a2dbungeman paint.textToGlyphs(&character, sizeof(character), &glyphID); 39024a104d94696bc4b5170e82a28ef05053b302a2dbungeman if (glyphID != 0) { 391c9232dcda016feb2d30abb51483b3b1862775f84bungeman return face.detach(); 392c9232dcda016feb2d30abb51483b3b1862775f84bungeman } 393c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman } 39496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 395c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman } 396c9232dcda016feb2d30abb51483b3b1862775f84bungeman 39765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], 39865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman const SkFontStyle& style, 399c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman const char* bcp47[], 400c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman int bcp47Count, 40136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkUnichar character) const override 40265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman { 40365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'. 40465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // The variant 'default' means 'compact and elegant'. 40565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // As a result, it is not possible to know the variant context from the font alone. 40665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. 40765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 408c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman // The first time match anything elegant, second time anything not elegant. 409c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman for (int elegant = 2; elegant --> 0;) { 410c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman for (int bcp47Index = bcp47Count; bcp47Index --> 0;) { 411c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkLanguage lang(bcp47[bcp47Index]); 412c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman while (!lang.getTag().isEmpty()) { 413c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkTypeface_AndroidSystem* matchingTypeface = 414c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman find_family_style_character(fFallbackNameToFamilyMap, 415c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman style, SkToBool(elegant), 416c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman lang.getTag(), character); 417c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman if (matchingTypeface) { 418c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman return matchingTypeface; 41965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 42065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 421c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman lang = lang.getParent(); 42265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 423c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman } 424c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkTypeface_AndroidSystem* matchingTypeface = 425c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman find_family_style_character(fFallbackNameToFamilyMap, 426c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman style, SkToBool(elegant), 427c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkString(), character); 428c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman if (matchingTypeface) { 429c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman return matchingTypeface; 430c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman } 43165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 43296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 43365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 43465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 43536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { 436a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo return this->createFromStream(new SkMemoryStream(data), ttcIndex); 4378d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 4388d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 43936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 4405f213d9627d2eefa7da81cd97f36754f75eb4ae9bungeman SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); 44196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : nullptr; 4428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 4438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 44436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override { 4455f213d9627d2eefa7da81cd97f36754f75eb4ae9bungeman SkAutoTDelete<SkStreamAsset> stream(bareStream); 4468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman bool isFixedPitch; 447a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman SkFontStyle style; 4488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkString name; 44996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch, nullptr)) { 45096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 45141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 45296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkFontData* data(new SkFontData(stream.detach(), ttcIndex, nullptr, 0)); 453385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); 45441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 45541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 456f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override { 457f6c7107d0385cc2b556802354b93b7dcff61570dbungeman using Scanner = SkTypeface_FreeType::Scanner; 458f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkAutoTDelete<SkStreamAsset> stream(s); 459f6c7107d0385cc2b556802354b93b7dcff61570dbungeman bool isFixedPitch; 460f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkFontStyle style; 461f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkString name; 462f6c7107d0385cc2b556802354b93b7dcff61570dbungeman Scanner::AxisDefinitions axisDefinitions; 463f6c7107d0385cc2b556802354b93b7dcff61570dbungeman if (!fScanner.scanFont(stream, params.getCollectionIndex(), &name, &style, &isFixedPitch, 464f6c7107d0385cc2b556802354b93b7dcff61570dbungeman &axisDefinitions)) 465f6c7107d0385cc2b556802354b93b7dcff61570dbungeman { 466f6c7107d0385cc2b556802354b93b7dcff61570dbungeman return nullptr; 467f6c7107d0385cc2b556802354b93b7dcff61570dbungeman } 468f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 469f6c7107d0385cc2b556802354b93b7dcff61570dbungeman int paramAxisCount; 470f6c7107d0385cc2b556802354b93b7dcff61570dbungeman const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); 471f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 472f6c7107d0385cc2b556802354b93b7dcff61570dbungeman Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); 473f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 474f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkFontData* data(new SkFontData(stream.detach(), params.getCollectionIndex(), 475f6c7107d0385cc2b556802354b93b7dcff61570dbungeman axisValues.get(), axisDefinitions.count())); 476f6c7107d0385cc2b556802354b93b7dcff61570dbungeman return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); 477f6c7107d0385cc2b556802354b93b7dcff61570dbungeman } 478f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 47941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkTypeface* onCreateFromFontData(SkFontData* data) const override { 48041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkStreamAsset* stream(data->getStream()); 48141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman bool isFixedPitch; 48241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkFontStyle style; 48341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkString name; 48496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!fScanner.scanFont(stream, data->getIndex(), &name, &style, &isFixedPitch, nullptr)) { 48596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 4868d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 487385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkTypeface_AndroidStream(data, style, isFixedPitch, name); 4888d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 4898d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 4908d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 4918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 49236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein unsigned styleBits) const override { 493a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman SkFontStyle style = SkFontStyle(styleBits); 4948d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 49549f085dddff10473b6ebf832a974288300224e60bsalomon if (familyName) { 49696fcdcc219d2a0d3579719b84b28bede76efba64halcanary // On Android, we must return nullptr when we can't find the requested 4978d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman // named typeface so that the system/app can provide their own recovery 4988d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman // mechanism. On other platforms we'd provide a typeface from the 4998d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman // default family instead. 50007cfb20a0b9a14b8daeb56fcf21d810e91387fd1bungeman return this->onMatchFamilyStyle(familyName, style); 5018d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 50207cfb20a0b9a14b8daeb56fcf21d810e91387fd1bungeman return fDefaultFamily->matchStyle(style); 5038d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5048d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5058d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5068d84c995319dd4a82e4f2054bbd19f968c671ca6bungemanprivate: 5078d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 50814df8339841f246a7337a8fb0d90f1b7ee689619bungeman SkTypeface_FreeType::Scanner fScanner; 50914df8339841f246a7337a8fb0d90f1b7ee689619bungeman 5108d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets; 5118d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkFontStyleSet* fDefaultFamily; 5128d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkTypeface* fDefaultTypeface; 5138d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5148d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkTDArray<NameToFamily> fNameToFamilyMap; 51565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkTDArray<NameToFamily> fFallbackNameToFamilyMap; 5168d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 517ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar void buildNameToFamilyMap(SkTDArray<FontFamily*> families, const bool isolated) { 5188d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (int i = 0; i < families.count(); i++) { 51965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman FontFamily& family = *families[i]; 52065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 52165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap; 52265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman if (family.fIsFallbackFont) { 52365fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman nameToFamily = &fFallbackNameToFamilyMap; 52465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 52565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman if (0 == family.fNames.count()) { 52665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman SkString& fallbackName = family.fNames.push_back(); 52765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman fallbackName.printf("%.2x##fallback", i); 52865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 52965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 53065fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 531ebc465b8f271f362015fdf352b8355989e59a3f3khushalsagar SkFontStyleSet_Android* newSet = new SkFontStyleSet_Android(family, fScanner, isolated); 53265fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman if (0 == newSet->count()) { 533385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete newSet; 53465fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman continue; 53565fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman } 53665fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman fFontStyleSets.push_back().reset(newSet); 53765fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman 53865fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman for (int j = 0; j < family.fNames.count(); j++) { 53965fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman NameToFamily* nextEntry = nameToFamily->append(); 540385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new (&nextEntry->name) SkString(family.fNames[j]); 54165fcd3de3cb9dfd766c460500586eb939e6a6d68bungeman nextEntry->styleSet = newSet; 5428d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5438d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5448d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5458d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5468d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman void findDefaultFont() { 5478d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(!fFontStyleSets.empty()); 5488d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5498d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman static const char* gDefaultNames[] = { "sans-serif" }; 5508d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { 5518d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]); 55296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == set) { 5538d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman continue; 5548d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5558d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkTypeface* tf = set->matchStyle(SkFontStyle()); 55696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == tf) { 5578d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman continue; 5588d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5598d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman fDefaultFamily = set; 5608d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman fDefaultTypeface = tf; 5618d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman break; 5628d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 56396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fDefaultTypeface) { 5648d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman fDefaultFamily = fFontStyleSets[0]; 5658d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman fDefaultTypeface = fDefaultFamily->createTypeface(0); 5668d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5678d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(fDefaultFamily); 5688d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman SkASSERT(fDefaultTypeface); 5698d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman } 5708d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5718d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman typedef SkFontMgr INHERITED; 5728d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman}; 5738d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman 5747fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#ifdef SK_DEBUG 5757fa87cd09f49f1ee9bc27e263038d0f0ae706241bungemanstatic char const * const gSystemFontUseStrings[] = { 5767fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman "OnlyCustom", "PreferCustom", "PreferSystem" 5777fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman}; 5787fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman#endif 5797fa87cd09f49f1ee9bc27e263038d0f0ae706241bungemanSkFontMgr* SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) { 5807fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman if (custom) { 5817fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkASSERT(0 <= custom->fSystemFontUse); 5827fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkASSERT(custom->fSystemFontUse < SK_ARRAY_COUNT(gSystemFontUseStrings)); 5837fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman SkDEBUGF(("SystemFontUse: %s BasePath: %s Fonts: %s FallbackFonts: %s\n", 5847fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman gSystemFontUseStrings[custom->fSystemFontUse], 5857fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman custom->fBasePath, 5867fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman custom->fFontsXml, 5877fa87cd09f49f1ee9bc27e263038d0f0ae706241bungeman custom->fFallbackFontsXml)); 5884e3523cf546df4079cf769b8ecc8011403420a45bungeman } 5894e3523cf546df4079cf769b8ecc8011403420a45bungeman 590385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkFontMgr_Android(custom); 5918d84c995319dd4a82e4f2054bbd19f968c671ca6bungeman} 592