1a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman/* 2a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Copyright 2014 Google Inc. 3a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * 4a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Use of this source code is governed by a BSD-style license that can be 5a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * found in the LICENSE file. 6a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 7a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 8a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkDataTable.h" 9f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkFixed.h" 10a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkFontDescriptor.h" 11a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkFontHost_FreeType_common.h" 12a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkFontMgr.h" 13a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkFontStyle.h" 14a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkMath.h" 151b24933e52f50773de29332387a12721811f3012mtklein#include "SkMutex.h" 16f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkOSFile.h" 17f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkRefCnt.h" 18a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkStream.h" 19f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkString.h" 20a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkTDArray.h" 21f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTemplates.h" 22f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTypeface.h" 23a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include "SkTypefaceCache.h" 24f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTypes.h" 25a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 26a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#include <fontconfig/fontconfig.h> 27f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include <string.h> 28f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman 29f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungemanclass SkData; 30a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 31a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// FC_POSTSCRIPT_NAME was added with b561ff20 which ended up in 2.10.92 32a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// Ubuntu 12.04 is on 2.8.0, 13.10 is on 2.10.93 33a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// Debian 7 is on 2.9.0, 8 is on 2.11 34a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// OpenSUSE 12.2 is on 2.9.0, 12.3 is on 2.10.2, 13.1 2.11.0 35a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// Fedora 19 is on 2.10.93 36a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#ifndef FC_POSTSCRIPT_NAME 37a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman# define FC_POSTSCRIPT_NAME "postscriptname" 38a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#endif 39a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 40a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#ifdef SK_DEBUG 41a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman# include "SkTLS.h" 42a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#endif 43a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 44a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman/** Since FontConfig is poorly documented, this gives a high level overview: 45a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * 46a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * FcConfig is a handle to a FontConfig configuration instance. Each 'configuration' is independent 47a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * from any others which may exist. There exists a default global configuration which is created 48a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * and destroyed by FcInit and FcFini, but this default should not normally be used. 49a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Instead, one should use FcConfigCreate and FcInit* to have a named local state. 50a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * 51a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * FcPatterns are {objectName -> [element]} (maps from object names to a list of elements). 52a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Each element is some internal data plus an FcValue which is a variant (a union with a type tag). 53a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Lists of elements are not typed, except by convention. Any collection of FcValues must be 54a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * assumed to be heterogeneous by the code, but the code need not do anything particularly 55a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * interesting if the values go against convention. 56a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * 57a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Somewhat like DirectWrite, FontConfig supports synthetics through FC_EMBOLDEN and FC_MATRIX. 58a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Like all synthetic information, such information must be passed with the font data. 59a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 60a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 61a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemannamespace { 62a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 63a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex. 646950de6c4166fabb35e6c756fc009e0cf1c47819halcanary// See https://bug.skia.org/1497 for background. 65a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanSK_DECLARE_STATIC_MUTEX(gFCMutex); 66a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 67a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#ifdef SK_DEBUG 68385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryvoid* CreateThreadFcLocked() { return new bool(false); } 69385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryvoid DeleteThreadFcLocked(void* v) { delete static_cast<bool*>(v); } 70a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman# define THREAD_FC_LOCKED \ 71a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked)) 72a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman#endif 73a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 74a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstruct FCLocker { 75a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Assume FcGetVersion() has always been thread safe. 76a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 77a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker() { 78a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcGetVersion() < 21091) { 79a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman gFCMutex.acquire(); 80a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } else { 81a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED); 82a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkASSERT(false == *threadLocked); 83a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkDEBUGCODE(*threadLocked = true); 84a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 85a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 86a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 87a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ~FCLocker() { 88a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman AssertHeld(); 89a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcGetVersion() < 21091) { 90a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman gFCMutex.release(); 91a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } else { 92a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkDEBUGCODE(*THREAD_FC_LOCKED = false); 93a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 94a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 95a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 96a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static void AssertHeld() { SkDEBUGCODE( 97a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcGetVersion() < 21091) { 98a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman gFCMutex.assertHeld(); 99a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } else { 100a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkASSERT(true == *THREAD_FC_LOCKED); 101a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 102a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ) } 103a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 104a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 105a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} // namespace 106a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 1076bc2c94de334efb40e1a09e31112262dec77532bbungemantemplate<typename T, void (*D)(T*)> void FcTDestroy(T* t) { 108a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker::AssertHeld(); 1096bc2c94de334efb40e1a09e31112262dec77532bbungeman D(t); 110a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 1116bc2c94de334efb40e1a09e31112262dec77532bbungemantemplate <typename T, T* (*C)(), void (*D)(T*)> class SkAutoFc 1126bc2c94de334efb40e1a09e31112262dec77532bbungeman : public SkAutoTCallVProc<T, FcTDestroy<T, D> > { 113a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanpublic: 1146bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFc() : SkAutoTCallVProc<T, FcTDestroy<T, D> >(C()) { 1156bc2c94de334efb40e1a09e31112262dec77532bbungeman T* obj = this->operator T*(); 116f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollen SkASSERT_RELEASE(nullptr != obj); 1176bc2c94de334efb40e1a09e31112262dec77532bbungeman } 1186bc2c94de334efb40e1a09e31112262dec77532bbungeman explicit SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, D> >(obj) {} 119a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 120a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 1216bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet; 1226bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig; 1236bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet; 1246bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet; 1256bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObjectSet; 1266bc2c94de334efb40e1a09e31112262dec77532bbungemantypedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern; 127a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 128a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic int get_int(FcPattern* pattern, const char object[], int missing) { 129a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int value; 130a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) { 131a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return missing; 132a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 133a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return value; 134a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 135a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 136a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic const char* get_string(FcPattern* pattern, const char object[], const char* missing = "") { 137a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcChar8* value; 138a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcPatternGetString(pattern, object, 0, &value) != FcResultMatch) { 139a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return missing; 140a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 141a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return (const char*)value; 142a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 143a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 144a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanenum SkWeakReturn { 145a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman kIsWeak_WeakReturn, 146a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman kIsStrong_WeakReturn, 147a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman kNoId_WeakReturn 148a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 149a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman/** Ideally there would exist a call like 150a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak); 151a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * 152a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit. 153a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Currently, the only reliable way of finding the weak bit is by its effect on matching. 154a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values. 155a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * A element with the weak bit is scored after FC_LANG, without the weak bit is scored before. 156a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * Note that the weak bit is stored on the element, not on the value it holds. 157a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 158a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic SkWeakReturn is_weak(FcPattern* pattern, const char object[], int id) { 159a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker::AssertHeld(); 160a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 161a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcResult result; 162a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 163a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Create a copy of the pattern with only the value 'pattern'['object'['id']] in it. 164a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Internally, FontConfig pattern objects are linked lists, so faster to remove from head. 16596fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr)); 166a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly)); 167a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcBool hasId = true; 168a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int i = 0; hasId && i < id; ++i) { 169a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman hasId = FcPatternRemove(minimal, object, 0); 170a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 171a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (!hasId) { 172a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return kNoId_WeakReturn; 173a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 174a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcValue value; 175a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman result = FcPatternGet(minimal, object, 0, &value); 176a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (result != FcResultMatch) { 177a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return kNoId_WeakReturn; 178a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 179a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman while (hasId) { 180a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman hasId = FcPatternRemove(minimal, object, 1); 181a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 182a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 183a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Create a font set with two patterns. 184a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'. 185a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // 2. a different 'object' from minimal and a lang object with only 'matchlang'. 1866bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcFontSet fontSet; 187a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 1886bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcLangSet strongLangSet; 189a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang"); 190a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcPattern strong(FcPatternDuplicate(minimal)); 191a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddLangSet(strong, FC_LANG, strongLangSet); 192a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 1936bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcLangSet weakLangSet; 194a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang"); 1956bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern weak; 196a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring"); 197a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddLangSet(weak, FC_LANG, weakLangSet); 198a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 199a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSetAdd(fontSet, strong.detach()); 200a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSetAdd(fontSet, weak.detach()); 201a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 202a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Add 'matchlang' to the copy of the pattern. 203a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddLangSet(minimal, FC_LANG, weakLangSet); 204a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 205a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Run a match against the copy of the pattern. 206a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // If the 'id' was weak, then we should match the pattern with 'matchlang'. 207a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // If the 'id' was strong, then we should match the pattern with 'nomatchlang'. 208a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 209a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Note that this config is only used for FcFontRenderPrepare, which we don't even want. 210a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // However, there appears to be no way to match/sort without it. 2116bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcConfig config; 212a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSet* fontSets[1] = { fontSet }; 213a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSets), 214a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman minimal, &result)); 215a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 216a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcLangSet* matchLangSet; 217a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet); 218a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchlang") 219a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ? kIsWeak_WeakReturn : kIsStrong_WeakReturn; 220a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 221a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 222a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman/** Removes weak elements from either FC_FAMILY or FC_POSTSCRIPT_NAME objects in the property. 223a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * This can be quite expensive, and should not be used more than once per font lookup. 224a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * This removes all of the weak elements after the last strong element. 225a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 226a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic void remove_weak(FcPattern* pattern, const char object[]) { 227a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker::AssertHeld(); 228a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 22996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr)); 230a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly)); 231a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 232a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int lastStrongId = -1; 233a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int numIds; 234a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkWeakReturn result; 235a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int id = 0; ; ++id) { 236a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman result = is_weak(minimal, object, 0); 237a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (kNoId_WeakReturn == result) { 238a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman numIds = id; 239a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman break; 240a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 241a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (kIsStrong_WeakReturn == result) { 242a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman lastStrongId = id; 243a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 244a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAssertResult(FcPatternRemove(minimal, object, 0)); 245a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 246a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 247a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // If they were all weak, then leave the pattern alone. 248a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (lastStrongId < 0) { 249a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return; 250a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 251a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 252a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Remove everything after the last strong. 253a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int id = lastStrongId + 1; id < numIds; ++id) { 254a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAssertResult(FcPatternRemove(pattern, object, lastStrongId + 1)); 255a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 256a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 257a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 258a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic int map_range(SkFixed value, 259a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFixed old_min, SkFixed old_max, 260a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFixed new_min, SkFixed new_max) 261a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman{ 262a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkASSERT(old_min < old_max); 263a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkASSERT(new_min <= new_max); 264a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min); 265a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 266a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 267a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic int ave(SkFixed a, SkFixed b) { 268a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return SkFixedAve(a, b); 269a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 270a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 271a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstruct MapRanges { 272a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFixed old_val; 273a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFixed new_val; 274a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 275a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 276a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) { 277a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // -Inf to [0] 278a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (val < ranges[0].old_val) { 279a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return ranges[0].new_val; 280a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 281a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 282a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Linear from [i] to ave([i], [i+1]), then from ave([i], [i+1]) to [i+1] 283a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int i = 0; i < rangesCount - 1; ++i) { 284a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) { 285a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, ranges[i+1].old_val), 286a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ranges[i].new_val, ave(ranges[i].new_val, ranges[i+1].new_val)); 287a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 288a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (val < ranges[i+1].old_val) { 289a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), ranges[i+1].old_val, 290a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ave(ranges[i].new_val, ranges[i+1].new_val), ranges[i+1].new_val); 291a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 292a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 293a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 294a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // From [n] to +Inf 295a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // if (fcweight < Inf) 296a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return ranges[rangesCount-1].new_val; 297a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 298a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 299a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic int map_ranges(int val, MapRanges const ranges[], int rangesCount) { 300a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount)); 301a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 302a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 303a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemantemplate<int n> struct SkTFixed { 30499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(-32768 <= n && n <= 32767, "SkTFixed_n_not_in_range"); 305a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const SkFixed value = static_cast<SkFixed>(n << 16); 306a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 307a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 308a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) { 309a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman typedef SkFontStyle SkFS; 310a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 311a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const MapRanges weightRanges[] = { 312a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_THIN>::value, SkTFixed<SkFS::kThin_Weight>::value }, 313a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value }, 314a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_LIGHT>::value, SkTFixed<SkFS::kLight_Weight>::value }, 315a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_REGULAR>::value, SkTFixed<SkFS::kNormal_Weight>::value }, 316a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_MEDIUM>::value, SkTFixed<SkFS::kMedium_Weight>::value }, 317a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_DEMIBOLD>::value, SkTFixed<SkFS::kSemiBold_Weight>::value }, 318a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_BOLD>::value, SkTFixed<SkFS::kBold_Weight>::value }, 319a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_EXTRABOLD>::value, SkTFixed<SkFS::kExtraBold_Weight>::value }, 320a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_BLACK>::value, SkTFixed<SkFS::kBlack_Weight>::value }, 321a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value }, 322a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman }; 323a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR), 324a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman weightRanges, SK_ARRAY_COUNT(weightRanges)); 325a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 326a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const MapRanges widthRanges[] = { 327a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value }, 328a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value }, 329a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_CONDENSED>::value, SkTFixed<SkFS::kCondensed_Width>::value }, 330a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_SEMICONDENSED>::value, SkTFixed<SkFS::kSemiCondensed_Width>::value }, 331a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_NORMAL>::value, SkTFixed<SkFS::kNormal_Width>::value }, 332a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value, SkTFixed<SkFS::kSemiExpanded_Width>::value }, 333a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_EXPANDED>::value, SkTFixed<SkFS::kExpanded_Width>::value }, 334a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value, SkTFixed<SkFS::kExtraExpanded_Width>::value }, 335a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value, SkTFixed<SkFS::kUltaExpanded_Width>::value }, 336a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman }; 337a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL), 338a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman widthRanges, SK_ARRAY_COUNT(widthRanges)); 339a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 340a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0 341a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman ? SkFS::kItalic_Slant 342a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman : SkFS::kUpright_Slant; 343a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 344a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return SkFontStyle(weight, width, slant); 345a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 346a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 347a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanstatic void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) { 348a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker::AssertHeld(); 349a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 350a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman typedef SkFontStyle SkFS; 351a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 352a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const MapRanges weightRanges[] = { 353a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kThin_Weight>::value, SkTFixed<FC_WEIGHT_THIN>::value }, 354a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value }, 355a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kLight_Weight>::value, SkTFixed<FC_WEIGHT_LIGHT>::value }, 356a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kNormal_Weight>::value, SkTFixed<FC_WEIGHT_REGULAR>::value }, 357a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kMedium_Weight>::value, SkTFixed<FC_WEIGHT_MEDIUM>::value }, 358a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kSemiBold_Weight>::value, SkTFixed<FC_WEIGHT_DEMIBOLD>::value }, 359a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kBold_Weight>::value, SkTFixed<FC_WEIGHT_BOLD>::value }, 360a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kExtraBold_Weight>::value, SkTFixed<FC_WEIGHT_EXTRABOLD>::value }, 361a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kBlack_Weight>::value, SkTFixed<FC_WEIGHT_BLACK>::value }, 362a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<1000>::value, SkTFixed<FC_WEIGHT_EXTRABLACK>::value }, 363a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman }; 364a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges)); 365a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 366a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const MapRanges widthRanges[] = { 367a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value }, 368a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value }, 369a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kCondensed_Width>::value, SkTFixed<FC_WIDTH_CONDENSED>::value }, 370a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kSemiCondensed_Width>::value, SkTFixed<FC_WIDTH_SEMICONDENSED>::value }, 371a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kNormal_Width>::value, SkTFixed<FC_WIDTH_NORMAL>::value }, 372a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kSemiExpanded_Width>::value, SkTFixed<FC_WIDTH_SEMIEXPANDED>::value }, 373a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kExpanded_Width>::value, SkTFixed<FC_WIDTH_EXPANDED>::value }, 374a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kExtraExpanded_Width>::value, SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value }, 375a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { SkTFixed<SkFS::kUltaExpanded_Width>::value, SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value }, 376a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman }; 377a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges)); 378a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 379a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddInteger(pattern, FC_WEIGHT, weight); 380a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddInteger(pattern, FC_WIDTH, width); 381a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); 382a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 383a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 384a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanclass SkTypeface_stream : public SkTypeface_FreeType { 385a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanpublic: 38641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman /** @param data takes ownership of the font data.*/ 38741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkTypeface_stream(SkFontData* data, const SkFontStyle& style, bool fixedWidth) 388a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) 38941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman , fData(data) 390a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { }; 391a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 39236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFamilyName(SkString* familyName) const override { 393b374d6a62c0259387d90cad74753d8bad9ee1beabungeman familyName->reset(); 394b374d6a62c0259387d90cad74753d8bad9ee1beabungeman } 395b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 39636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override { 397a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *serialize = true; 398a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 399a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 40036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkStreamAsset* onOpenStream(int* ttcIndex) const override { 40141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman *ttcIndex = fData->getIndex(); 40241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman return fData->duplicateStream(); 40341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 40441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 40541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkFontData* onCreateFontData() const override { 40641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman return new SkFontData(*fData.get()); 407a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 408a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 409a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanprivate: 41041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const SkAutoTDelete<const SkFontData> fData; 411a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 412a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman typedef SkTypeface_FreeType INHERITED; 413a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 414a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 415a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanclass SkTypeface_fontconfig : public SkTypeface_FreeType { 416a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanpublic: 417a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** @param pattern takes ownership of the reference. */ 418a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static SkTypeface_fontconfig* Create(FcPattern* pattern) { 419385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkTypeface_fontconfig(pattern); 420a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 421a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman mutable SkAutoFcPattern fPattern; 422a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 42336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFamilyName(SkString* familyName) const override { 424b374d6a62c0259387d90cad74753d8bad9ee1beabungeman *familyName = get_string(fPattern, FC_FAMILY); 425b374d6a62c0259387d90cad74753d8bad9ee1beabungeman } 426b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 42736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override { 428a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 429a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman desc->setFamilyName(get_string(fPattern, FC_FAMILY)); 430a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman desc->setFullName(get_string(fPattern, FC_FULLNAME)); 431a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman desc->setPostscriptName(get_string(fPattern, FC_POSTSCRIPT_NAME)); 432a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *serialize = false; 433a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 434a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 43536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkStreamAsset* onOpenStream(int* ttcIndex) const override { 436a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 437a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *ttcIndex = get_int(fPattern, FC_INDEX, 0); 438a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return SkStream::NewFromFile(get_string(fPattern, FC_FILE)); 439a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 440a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 441a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual ~SkTypeface_fontconfig() { 442a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Hold the lock while unrefing the pattern. 443a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 444a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fPattern.reset(); 445a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 446a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 447a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanprivate: 448a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** @param pattern takes ownership of the reference. */ 449a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTypeface_fontconfig(FcPattern* pattern) 450a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman : INHERITED(skfontstyle_from_fcpattern(pattern), 451a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTypefaceCache::NewFontID(), 452a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL)) 453a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman , fPattern(pattern) 454a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { }; 455a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 456a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman typedef SkTypeface_FreeType INHERITED; 457a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 458a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 459a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanclass SkFontMgr_fontconfig : public SkFontMgr { 460a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman mutable SkAutoFcConfig fFC; 461a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoTUnref<SkDataTable> fFamilyNames; 46214df8339841f246a7337a8fb0d90f1b7ee689619bungeman SkTypeface_FreeType::Scanner fScanner; 463a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 464a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman class StyleSet : public SkFontStyleSet { 465a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman public: 466a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** @param parent does not take ownership of the reference. 467a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * @param fontSet takes ownership of the reference. 468a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 469a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman StyleSet(const SkFontMgr_fontconfig* parent, FcFontSet* fontSet) 470a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman : fFontMgr(SkRef(parent)), fFontSet(fontSet) 471a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { } 472a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 473a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual ~StyleSet() { 474a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Hold the lock while unrefing the font set. 475a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 476a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fFontSet.reset(); 477a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 478a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 47936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int count() override { return fFontSet->nfont; } 480a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 48136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getStyle(int index, SkFontStyle* style, SkString* styleName) override { 482a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (index < 0 || fFontSet->nfont <= index) { 483a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return; 484a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 485a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 486a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 487a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (style) { 488a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *style = skfontstyle_from_fcpattern(fFontSet->fonts[index]); 489a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 490a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (styleName) { 491a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *styleName = get_string(fFontSet->fonts[index], FC_STYLE); 492a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 493a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 494a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 49536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* createTypeface(int index) override { 496a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 497a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 498a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPattern* match = fFontSet->fonts[index]; 499a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return fFontMgr->createTypefaceFromFcPattern(match); 500a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 501a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 50236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* matchStyle(const SkFontStyle& style) override { 503a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 504a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 5056bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern pattern; 506a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fcpattern_from_skfontstyle(style, pattern); 507a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern); 508a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcDefaultSubstitute(pattern); 509a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 510a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcResult result; 511a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSet* fontSets[1] = { fFontSet }; 512a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC, 513a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fontSets, SK_ARRAY_COUNT(fontSets), 514a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman pattern, &result)); 51596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == match) { 51696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 517a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 518a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 519a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return fFontMgr->createTypefaceFromFcPattern(match); 520a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 521a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 522a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman private: 523a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoTUnref<const SkFontMgr_fontconfig> fFontMgr; 524a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoFcFontSet fFontSet; 525a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman }; 526a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 527a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static bool FindName(const SkTDArray<const char*>& list, const char* str) { 528a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman int count = list.count(); 529a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int i = 0; i < count; ++i) { 530a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (!strcmp(list[i], str)) { 531a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return true; 532a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 533a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 534a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return false; 535a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 536a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 537a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static SkDataTable* GetFamilyNames(FcConfig* fcconfig) { 538a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 539a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 540a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTDArray<const char*> names; 541a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTDArray<size_t> sizes; 542a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 543a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication }; 544a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) { 545a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Return value of FcConfigGetFonts must not be destroyed. 546a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSet* allFonts(FcConfigGetFonts(fcconfig, fcNameSet[setIndex])); 54796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == allFonts) { 548a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman continue; 549a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 550a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 551a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) { 552a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPattern* current = allFonts->fonts[fontIndex]; 553a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int id = 0; ; ++id) { 554a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcChar8* fcFamilyName; 555a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcResult result = FcPatternGetString(current, FC_FAMILY, id, &fcFamilyName); 556a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultNoId == result) { 557a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman break; 558a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 559a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultMatch != result) { 560a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman continue; 561a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 562a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman const char* familyName = reinterpret_cast<const char*>(fcFamilyName); 563a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (familyName && !FindName(names, familyName)) { 564a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *names.append() = familyName; 565a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman *sizes.append() = strlen(familyName) + 1; 566a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 567a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 568a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 569a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 570a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 571a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return SkDataTable::NewCopyArrays((void const *const *)names.begin(), 572a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman sizes.begin(), names.count()); 573a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 574a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 575a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman static bool FindByFcPattern(SkTypeface* cached, const SkFontStyle&, void* ctx) { 576a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached); 577a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPattern* ctxPattern = static_cast<FcPattern*>(ctx); 578a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern); 579a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 580a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 581a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman mutable SkMutex fTFCacheMutex; 582a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman mutable SkTypefaceCache fTFCache; 583a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** Creates a typeface using a typeface cache. 584a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * @param pattern a complete pattern from FcFontRenderPrepare. 585a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 586a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTypeface* createTypefaceFromFcPattern(FcPattern* pattern) const { 587a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker::AssertHeld(); 588a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoMutexAcquire ama(fTFCacheMutex); 589a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkTypeface* face = fTFCache.findByProcAndRef(FindByFcPattern, pattern); 59096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == face) { 591a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternReference(pattern); 592a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman face = SkTypeface_fontconfig::Create(pattern); 593a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (face) { 59460b6e9dbbc492f987a5b887dff60aec107ab70d0mtklein fTFCache.add(face, SkFontStyle()); 595a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 596a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 597a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return face; 598a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 599a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 600a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanpublic: 601a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** Takes control of the reference to 'config'. */ 602a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman explicit SkFontMgr_fontconfig(FcConfig* config) 6030b1de2626a289ab21bd3b93277ed34d022824b3dbungeman : fFC(config ? config : FcInitLoadConfigAndFonts()) 604a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman , fFamilyNames(GetFamilyNames(fFC)) { } 605a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 606a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual ~SkFontMgr_fontconfig() { 607a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Hold the lock while unrefing the config. 608a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 609a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fFC.reset(); 610a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 611a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 612a6785ccb540b1b752ab536cdf579a698eadbf7d2bungemanprotected: 61336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int onCountFamilies() const override { 614a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return fFamilyNames->count(); 615a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 616a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 61736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onGetFamilyName(int index, SkString* familyName) const override { 618a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman familyName->set(fFamilyNames->atStr(index)); 619a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 620a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 62136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkFontStyleSet* onCreateStyleSet(int index) const override { 622a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return this->onMatchFamily(fFamilyNames->atStr(index)); 623a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 624a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 625a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman /** True if any string object value in the font is the same 626a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman * as a string object value in the pattern. 627a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman */ 628a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static bool AnyMatching(FcPattern* font, FcPattern* pattern, const char* object) { 629a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcChar8* fontString; 630a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcChar8* patternString; 631a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcResult result; 632a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Set an arbitrary limit on the number of pattern object values to consider. 633a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // TODO: re-write this to avoid N*M 634a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const int maxId = 16; 635a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int patternId = 0; patternId < maxId; ++patternId) { 636a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman result = FcPatternGetString(pattern, object, patternId, &patternString); 637a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultNoId == result) { 638a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman break; 639a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 640a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultMatch != result) { 641a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman continue; 642a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 643a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int fontId = 0; fontId < maxId; ++fontId) { 644a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman result = FcPatternGetString(font, object, fontId, &fontString); 645a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultNoId == result) { 646a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman break; 647a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 648a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (FcResultMatch != result) { 649a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman continue; 650a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 651a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (0 == FcStrCmpIgnoreCase(patternString, fontString)) { 652a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return true; 653a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 654a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 655a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 656a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return false; 657a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 658a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 6596bc2c94de334efb40e1a09e31112262dec77532bbungeman static bool FontAccessible(FcPattern* font) { 660a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // FontConfig can return fonts which are unreadable. 66196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const char* filename = get_string(font, FC_FILE, nullptr); 66296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == filename) { 663a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return false; 664a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 665a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return sk_exists(filename, kRead_SkFILE_Flag); 666a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 667a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 6686bc2c94de334efb40e1a09e31112262dec77532bbungeman static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) { 6696bc2c94de334efb40e1a09e31112262dec77532bbungeman return AnyMatching(font, pattern, FC_FAMILY); 6706bc2c94de334efb40e1a09e31112262dec77532bbungeman } 6716bc2c94de334efb40e1a09e31112262dec77532bbungeman 6726bc2c94de334efb40e1a09e31112262dec77532bbungeman static bool FontContainsCharacter(FcPattern* font, uint32_t character) { 6736bc2c94de334efb40e1a09e31112262dec77532bbungeman FcResult result; 6746bc2c94de334efb40e1a09e31112262dec77532bbungeman FcCharSet* matchCharSet; 6756bc2c94de334efb40e1a09e31112262dec77532bbungeman for (int charSetId = 0; ; ++charSetId) { 6766bc2c94de334efb40e1a09e31112262dec77532bbungeman result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet); 6776bc2c94de334efb40e1a09e31112262dec77532bbungeman if (FcResultNoId == result) { 6786bc2c94de334efb40e1a09e31112262dec77532bbungeman break; 6796bc2c94de334efb40e1a09e31112262dec77532bbungeman } 6806bc2c94de334efb40e1a09e31112262dec77532bbungeman if (FcResultMatch != result) { 6816bc2c94de334efb40e1a09e31112262dec77532bbungeman continue; 6826bc2c94de334efb40e1a09e31112262dec77532bbungeman } 6836bc2c94de334efb40e1a09e31112262dec77532bbungeman if (FcCharSetHasChar(matchCharSet, character)) { 6846bc2c94de334efb40e1a09e31112262dec77532bbungeman return true; 6856bc2c94de334efb40e1a09e31112262dec77532bbungeman } 6866bc2c94de334efb40e1a09e31112262dec77532bbungeman } 6876bc2c94de334efb40e1a09e31112262dec77532bbungeman return false; 688a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 689a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 69036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkFontStyleSet* onMatchFamily(const char familyName[]) const override { 691a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 692a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 6936bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern pattern; 694a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); 695a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcConfigSubstitute(fFC, pattern, FcMatchPattern); 696a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcDefaultSubstitute(pattern); 697a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 698a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPattern* matchPattern; 69996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoFcPattern strongPattern(nullptr); 700a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (familyName) { 701a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman strongPattern.reset(FcPatternDuplicate(pattern)); 702a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman remove_weak(strongPattern, FC_FAMILY); 703a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman matchPattern = strongPattern; 704a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } else { 705a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman matchPattern = pattern; 706a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 707a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 7086bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcFontSet matches; 709a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // TODO: Some families have 'duplicates' due to symbolic links. 710a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // The patterns are exactly the same except for the FC_FILE. 711a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // It should be possible to collapse these patterns by normalizing. 712a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication }; 713a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) { 714a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // Return value of FcConfigGetFonts must not be destroyed. 715a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex])); 71696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == allFonts) { 717a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman continue; 718a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 719a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 720a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) { 7216bc2c94de334efb40e1a09e31112262dec77532bbungeman FcPattern* font = allFonts->fonts[fontIndex]; 7226bc2c94de334efb40e1a09e31112262dec77532bbungeman if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) { 7236bc2c94de334efb40e1a09e31112262dec77532bbungeman FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font)); 724a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 725a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 726a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 727a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 728385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new StyleSet(this, matches.detach()); 729a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 730a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 731a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual SkTypeface* onMatchFamilyStyle(const char familyName[], 73236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const SkFontStyle& style) const override 733a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { 734a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FCLocker lock; 735a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 7366bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern pattern; 737a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); 738a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman fcpattern_from_skfontstyle(style, pattern); 739a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcConfigSubstitute(fFC, pattern, FcMatchPattern); 740a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcDefaultSubstitute(pattern); 741a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 742a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // We really want to match strong (prefered) and same (acceptable) only here. 743a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // If a family name was specified, assume that any weak matches after the last strong match 744a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // are weak (default) and ignore them. 745a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // The reason for is that after substitution the pattern for 'sans-serif' looks like 746a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults. 747a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // So it is possible to have weakly matching but preferred names. 748a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // In aliases, bindings are weak by default, so this is easy and common. 749a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman // If no family name was specified, we'll probably only get weak matches, but that's ok. 750a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcPattern* matchPattern; 75196fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoFcPattern strongPattern(nullptr); 752a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (familyName) { 753a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman strongPattern.reset(FcPatternDuplicate(pattern)); 754a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman remove_weak(strongPattern, FC_FAMILY); 755a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman matchPattern = strongPattern; 756a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } else { 757a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman matchPattern = pattern; 758a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 759a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 760a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman FcResult result; 7616bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); 76296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) { 76396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 7646bc2c94de334efb40e1a09e31112262dec77532bbungeman } 7656bc2c94de334efb40e1a09e31112262dec77532bbungeman 7666bc2c94de334efb40e1a09e31112262dec77532bbungeman return createTypefaceFromFcPattern(font); 7676bc2c94de334efb40e1a09e31112262dec77532bbungeman } 7686bc2c94de334efb40e1a09e31112262dec77532bbungeman 7696bc2c94de334efb40e1a09e31112262dec77532bbungeman virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], 7706bc2c94de334efb40e1a09e31112262dec77532bbungeman const SkFontStyle& style, 771c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman const char* bcp47[], 772c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman int bcp47Count, 77336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkUnichar character) const override 7746bc2c94de334efb40e1a09e31112262dec77532bbungeman { 7756bc2c94de334efb40e1a09e31112262dec77532bbungeman FCLocker lock; 7766bc2c94de334efb40e1a09e31112262dec77532bbungeman 7776bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern pattern; 7786837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman if (familyName) { 7796837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman FcValue familyNameValue; 7806837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman familyNameValue.type = FcTypeString; 7816837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman familyNameValue.u.s = reinterpret_cast<const FcChar8*>(familyName); 7826837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman FcPatternAddWeak(pattern, FC_FAMILY, familyNameValue, FcFalse); 7836837b38a62a1621ff43c7e1085b1a3bd208fcd49bungeman } 7846bc2c94de334efb40e1a09e31112262dec77532bbungeman fcpattern_from_skfontstyle(style, pattern); 7856bc2c94de334efb40e1a09e31112262dec77532bbungeman 7866bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcCharSet charSet; 7876bc2c94de334efb40e1a09e31112262dec77532bbungeman FcCharSetAddChar(charSet, character); 7886bc2c94de334efb40e1a09e31112262dec77532bbungeman FcPatternAddCharSet(pattern, FC_CHARSET, charSet); 7896bc2c94de334efb40e1a09e31112262dec77532bbungeman 790c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman if (bcp47Count > 0) { 791c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkASSERT(bcp47); 7926bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcLangSet langSet; 793c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman for (int i = bcp47Count; i --> 0;) { 794c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman FcLangSetAdd(langSet, (const FcChar8*)bcp47[i]); 795c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman } 7966bc2c94de334efb40e1a09e31112262dec77532bbungeman FcPatternAddLangSet(pattern, FC_LANG, langSet); 7976bc2c94de334efb40e1a09e31112262dec77532bbungeman } 7986bc2c94de334efb40e1a09e31112262dec77532bbungeman 7996bc2c94de334efb40e1a09e31112262dec77532bbungeman FcConfigSubstitute(fFC, pattern, FcMatchPattern); 8006bc2c94de334efb40e1a09e31112262dec77532bbungeman FcDefaultSubstitute(pattern); 8016bc2c94de334efb40e1a09e31112262dec77532bbungeman 8026bc2c94de334efb40e1a09e31112262dec77532bbungeman FcResult result; 8036bc2c94de334efb40e1a09e31112262dec77532bbungeman SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); 80496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) { 80596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 806a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 807a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 8086bc2c94de334efb40e1a09e31112262dec77532bbungeman return createTypefaceFromFcPattern(font); 809a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 810a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 811a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, 81236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const SkFontStyle& style) const override 813a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman { 814a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman //TODO: should the SkTypeface_fontconfig know its family? 815b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman const SkTypeface_fontconfig* fcTypeface = 8169db509272a6fa2badbbdd2f5afce827370960a5fbungeman static_cast<const SkTypeface_fontconfig*>(typeface); 817b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style); 818a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 819a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 82036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override { 8215f213d9627d2eefa7da81cd97f36754f75eb4ae9bungeman SkAutoTDelete<SkStreamAsset> stream(bareStream); 822a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman const size_t length = stream->getLength(); 823a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman if (length <= 0 || (1u << 30) < length) { 82496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 825a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 826a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 827a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungeman SkFontStyle style; 828a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman bool isFixedWidth = false; 82996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!fScanner.scanFont(stream, ttcIndex, nullptr, &style, &isFixedWidth, nullptr)) { 83096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 831a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 832a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 83396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return new SkTypeface_stream(new SkFontData(stream.detach(), ttcIndex, nullptr, 0), style, 834385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary isFixedWidth); 835a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 836a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 837f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override { 838f6c7107d0385cc2b556802354b93b7dcff61570dbungeman using Scanner = SkTypeface_FreeType::Scanner; 839f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkAutoTDelete<SkStreamAsset> stream(s); 840f6c7107d0385cc2b556802354b93b7dcff61570dbungeman bool isFixedPitch; 841f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkFontStyle style; 842f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkString name; 843f6c7107d0385cc2b556802354b93b7dcff61570dbungeman Scanner::AxisDefinitions axisDefinitions; 844f6c7107d0385cc2b556802354b93b7dcff61570dbungeman if (!fScanner.scanFont(stream, params.getCollectionIndex(), &name, &style, &isFixedPitch, 845f6c7107d0385cc2b556802354b93b7dcff61570dbungeman &axisDefinitions)) 846f6c7107d0385cc2b556802354b93b7dcff61570dbungeman { 847f6c7107d0385cc2b556802354b93b7dcff61570dbungeman return nullptr; 848f6c7107d0385cc2b556802354b93b7dcff61570dbungeman } 849f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 850f6c7107d0385cc2b556802354b93b7dcff61570dbungeman int paramAxisCount; 851f6c7107d0385cc2b556802354b93b7dcff61570dbungeman const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); 852f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 853f6c7107d0385cc2b556802354b93b7dcff61570dbungeman Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); 854f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 855f6c7107d0385cc2b556802354b93b7dcff61570dbungeman SkFontData* data(new SkFontData(stream.detach(), params.getCollectionIndex(), 856f6c7107d0385cc2b556802354b93b7dcff61570dbungeman axisValues.get(), axisDefinitions.count())); 857f6c7107d0385cc2b556802354b93b7dcff61570dbungeman return new SkTypeface_stream(data, style, isFixedPitch); 858f6c7107d0385cc2b556802354b93b7dcff61570dbungeman } 859f6c7107d0385cc2b556802354b93b7dcff61570dbungeman 86036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { 861385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return this->createFromStream(new SkMemoryStream(data), ttcIndex); 862a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 863a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 86436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 865a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo return this->createFromStream(SkStream::NewFromFile(path), ttcIndex); 866a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 867a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 86841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkTypeface* onCreateFromFontData(SkFontData* fontData) const override { 86941868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkStreamAsset* stream(fontData->getStream()); 87041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const size_t length = stream->getLength(); 87141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman if (length <= 0 || (1u << 30) < length) { 87296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 87341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 87441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 87541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman const int ttcIndex = fontData->getIndex(); 87641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman SkFontStyle style; 87741868fe5625fc3bd70daa3f461c881b5db6a9265bungeman bool isFixedWidth = false; 87896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!fScanner.scanFont(stream, ttcIndex, nullptr, &style, &isFixedWidth, nullptr)) { 87996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 88041868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 88141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 882385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkTypeface_stream(fontData, style, isFixedWidth); 88341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman } 88441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman 885a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 88636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein unsigned styleBits) const override { 887a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman bool bold = styleBits & SkTypeface::kBold; 888a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman bool italic = styleBits & SkTypeface::kItalic; 889a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight 890a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman : SkFontStyle::kNormal_Weight, 891a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkFontStyle::kNormal_Width, 892a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman italic ? SkFontStyle::kItalic_Slant 893a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman : SkFontStyle::kUpright_Slant); 894a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman SkAutoTUnref<SkTypeface> typeface(this->matchFamilyStyle(familyName, style)); 89549f085dddff10473b6ebf832a974288300224e60bsalomon if (typeface.get()) { 896a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman return typeface.detach(); 897a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 898a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 89996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return this->matchFamilyStyle(nullptr, style); 900a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman } 901a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman}; 902a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman 9030b1de2626a289ab21bd3b93277ed34d022824b3dbungemanSK_API SkFontMgr* SkFontMgr_New_FontConfig(FcConfig* fc) { 9040b1de2626a289ab21bd3b93277ed34d022824b3dbungeman return new SkFontMgr_fontconfig(fc); 905a6785ccb540b1b752ab536cdf579a698eadbf7d2bungeman} 906