Home | History | Annotate | Download | only in ports
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkAdvancedTypefaceMetrics.h"
      9 #include "SkDataTable.h"
     10 #include "SkFixed.h"
     11 #include "SkFontDescriptor.h"
     12 #include "SkFontHost_FreeType_common.h"
     13 #include "SkFontMgr.h"
     14 #include "SkFontStyle.h"
     15 #include "SkMakeUnique.h"
     16 #include "SkMath.h"
     17 #include "SkMutex.h"
     18 #include "SkOSFile.h"
     19 #include "SkRefCnt.h"
     20 #include "SkStream.h"
     21 #include "SkString.h"
     22 #include "SkTDArray.h"
     23 #include "SkTemplates.h"
     24 #include "SkTypeface.h"
     25 #include "SkTypefaceCache.h"
     26 #include "SkTypes.h"
     27 
     28 #include <fontconfig/fontconfig.h>
     29 #include <string.h>
     30 
     31 class SkData;
     32 
     33 // FC_POSTSCRIPT_NAME was added with b561ff20 which ended up in 2.10.92
     34 // Ubuntu 12.04 is on 2.8.0, 13.10 is on 2.10.93
     35 // Debian 7 is on 2.9.0, 8 is on 2.11
     36 // OpenSUSE 12.2 is on 2.9.0, 12.3 is on 2.10.2, 13.1 2.11.0
     37 // Fedora 19 is on 2.10.93
     38 #ifndef FC_POSTSCRIPT_NAME
     39 #    define FC_POSTSCRIPT_NAME  "postscriptname"
     40 #endif
     41 
     42 #ifdef SK_DEBUG
     43 #    include "SkTLS.h"
     44 #endif
     45 
     46 /** Since FontConfig is poorly documented, this gives a high level overview:
     47  *
     48  *  FcConfig is a handle to a FontConfig configuration instance. Each 'configuration' is independent
     49  *  from any others which may exist. There exists a default global configuration which is created
     50  *  and destroyed by FcInit and FcFini, but this default should not normally be used.
     51  *  Instead, one should use FcConfigCreate and FcInit* to have a named local state.
     52  *
     53  *  FcPatterns are {objectName -> [element]} (maps from object names to a list of elements).
     54  *  Each element is some internal data plus an FcValue which is a variant (a union with a type tag).
     55  *  Lists of elements are not typed, except by convention. Any collection of FcValues must be
     56  *  assumed to be heterogeneous by the code, but the code need not do anything particularly
     57  *  interesting if the values go against convention.
     58  *
     59  *  Somewhat like DirectWrite, FontConfig supports synthetics through FC_EMBOLDEN and FC_MATRIX.
     60  *  Like all synthetic information, such information must be passed with the font data.
     61  */
     62 
     63 namespace {
     64 
     65 // Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
     66 // See https://bug.skia.org/1497 for background.
     67 SK_DECLARE_STATIC_MUTEX(gFCMutex);
     68 
     69 #ifdef SK_DEBUG
     70 void* CreateThreadFcLocked() { return new bool(false); }
     71 void DeleteThreadFcLocked(void* v) { delete static_cast<bool*>(v); }
     72 #   define THREAD_FC_LOCKED \
     73         static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked))
     74 #endif
     75 
     76 class FCLocker {
     77     // Assume FcGetVersion() has always been thread safe.
     78     static void lock() {
     79         if (FcGetVersion() < 21091) {
     80             gFCMutex.acquire();
     81         } else {
     82             SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED);
     83             SkASSERT(false == *threadLocked);
     84             SkDEBUGCODE(*threadLocked = true);
     85         }
     86     }
     87     static void unlock() {
     88         AssertHeld();
     89         if (FcGetVersion() < 21091) {
     90             gFCMutex.release();
     91         } else {
     92             SkDEBUGCODE(*THREAD_FC_LOCKED = false);
     93         }
     94     }
     95 
     96 public:
     97     FCLocker() { lock(); }
     98     ~FCLocker() { unlock(); }
     99 
    100     /** If acquire and release were free, FCLocker would be used around each call into FontConfig.
    101      *  Instead a much more granular approach is taken, but this means there are times when the
    102      *  mutex is held when it should not be. A Suspend will drop the lock until it is destroyed.
    103      *  While a Suspend exists, FontConfig should not be used without re-taking the lock.
    104      */
    105     struct Suspend {
    106         Suspend() { unlock(); }
    107         ~Suspend() { lock(); }
    108     };
    109 
    110     static void AssertHeld() { SkDEBUGCODE(
    111         if (FcGetVersion() < 21091) {
    112             gFCMutex.assertHeld();
    113         } else {
    114             SkASSERT(true == *THREAD_FC_LOCKED);
    115         }
    116     ) }
    117 };
    118 
    119 } // namespace
    120 
    121 template<typename T, void (*D)(T*)> void FcTDestroy(T* t) {
    122     FCLocker::AssertHeld();
    123     D(t);
    124 }
    125 template <typename T, T* (*C)(), void (*D)(T*)> class SkAutoFc
    126     : public SkAutoTCallVProc<T, FcTDestroy<T, D> > {
    127 public:
    128     SkAutoFc() : SkAutoTCallVProc<T, FcTDestroy<T, D> >(C()) {
    129         T* obj = this->operator T*();
    130         SkASSERT_RELEASE(nullptr != obj);
    131     }
    132     explicit SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, D> >(obj) {}
    133 };
    134 
    135 typedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet;
    136 typedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig;
    137 typedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet;
    138 typedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet;
    139 typedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObjectSet;
    140 typedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern;
    141 
    142 static bool get_bool(FcPattern* pattern, const char object[], bool missing = false) {
    143     FcBool value;
    144     if (FcPatternGetBool(pattern, object, 0, &value) != FcResultMatch) {
    145         return missing;
    146     }
    147     return value;
    148 }
    149 
    150 static int get_int(FcPattern* pattern, const char object[], int missing) {
    151     int value;
    152     if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
    153         return missing;
    154     }
    155     return value;
    156 }
    157 
    158 static const char* get_string(FcPattern* pattern, const char object[], const char* missing = "") {
    159     FcChar8* value;
    160     if (FcPatternGetString(pattern, object, 0, &value) != FcResultMatch) {
    161         return missing;
    162     }
    163     return (const char*)value;
    164 }
    165 
    166 static const FcMatrix* get_matrix(FcPattern* pattern, const char object[]) {
    167     FcMatrix* matrix;
    168     if (FcPatternGetMatrix(pattern, object, 0, &matrix) != FcResultMatch) {
    169         return nullptr;
    170     }
    171     return matrix;
    172 }
    173 
    174 enum SkWeakReturn {
    175     kIsWeak_WeakReturn,
    176     kIsStrong_WeakReturn,
    177     kNoId_WeakReturn
    178 };
    179 /** Ideally there  would exist a call like
    180  *  FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
    181  *
    182  *  However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
    183  *  Currently, the only reliable way of finding the weak bit is by its effect on matching.
    184  *  The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
    185  *  A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
    186  *  Note that the weak bit is stored on the element, not on the value it holds.
    187  */
    188 static SkWeakReturn is_weak(FcPattern* pattern, const char object[], int id) {
    189     FCLocker::AssertHeld();
    190 
    191     FcResult result;
    192 
    193     // Create a copy of the pattern with only the value 'pattern'['object'['id']] in it.
    194     // Internally, FontConfig pattern objects are linked lists, so faster to remove from head.
    195     SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr));
    196     SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
    197     FcBool hasId = true;
    198     for (int i = 0; hasId && i < id; ++i) {
    199         hasId = FcPatternRemove(minimal, object, 0);
    200     }
    201     if (!hasId) {
    202         return kNoId_WeakReturn;
    203     }
    204     FcValue value;
    205     result = FcPatternGet(minimal, object, 0, &value);
    206     if (result != FcResultMatch) {
    207         return kNoId_WeakReturn;
    208     }
    209     while (hasId) {
    210         hasId = FcPatternRemove(minimal, object, 1);
    211     }
    212 
    213     // Create a font set with two patterns.
    214     // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'.
    215     // 2. a different 'object' from minimal and a lang object with only 'matchlang'.
    216     SkAutoFcFontSet fontSet;
    217 
    218     SkAutoFcLangSet strongLangSet;
    219     FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang");
    220     SkAutoFcPattern strong(FcPatternDuplicate(minimal));
    221     FcPatternAddLangSet(strong, FC_LANG, strongLangSet);
    222 
    223     SkAutoFcLangSet weakLangSet;
    224     FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang");
    225     SkAutoFcPattern weak;
    226     FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring");
    227     FcPatternAddLangSet(weak, FC_LANG, weakLangSet);
    228 
    229     FcFontSetAdd(fontSet, strong.release());
    230     FcFontSetAdd(fontSet, weak.release());
    231 
    232     // Add 'matchlang' to the copy of the pattern.
    233     FcPatternAddLangSet(minimal, FC_LANG, weakLangSet);
    234 
    235     // Run a match against the copy of the pattern.
    236     // If the 'id' was weak, then we should match the pattern with 'matchlang'.
    237     // If the 'id' was strong, then we should match the pattern with 'nomatchlang'.
    238 
    239     // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
    240     // However, there appears to be no way to match/sort without it.
    241     SkAutoFcConfig config;
    242     FcFontSet* fontSets[1] = { fontSet };
    243     SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSets),
    244                                          minimal, &result));
    245 
    246     FcLangSet* matchLangSet;
    247     FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet);
    248     return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchlang")
    249                         ? kIsWeak_WeakReturn : kIsStrong_WeakReturn;
    250 }
    251 
    252 /** Removes weak elements from either FC_FAMILY or FC_POSTSCRIPT_NAME objects in the property.
    253  *  This can be quite expensive, and should not be used more than once per font lookup.
    254  *  This removes all of the weak elements after the last strong element.
    255  */
    256 static void remove_weak(FcPattern* pattern, const char object[]) {
    257     FCLocker::AssertHeld();
    258 
    259     SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, nullptr));
    260     SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
    261 
    262     int lastStrongId = -1;
    263     int numIds;
    264     SkWeakReturn result;
    265     for (int id = 0; ; ++id) {
    266         result = is_weak(minimal, object, 0);
    267         if (kNoId_WeakReturn == result) {
    268             numIds = id;
    269             break;
    270         }
    271         if (kIsStrong_WeakReturn == result) {
    272             lastStrongId = id;
    273         }
    274         SkAssertResult(FcPatternRemove(minimal, object, 0));
    275     }
    276 
    277     // If they were all weak, then leave the pattern alone.
    278     if (lastStrongId < 0) {
    279         return;
    280     }
    281 
    282     // Remove everything after the last strong.
    283     for (int id = lastStrongId + 1; id < numIds; ++id) {
    284         SkAssertResult(FcPatternRemove(pattern, object, lastStrongId + 1));
    285     }
    286 }
    287 
    288 static int map_range(SkFixed value,
    289                      SkFixed old_min, SkFixed old_max,
    290                      SkFixed new_min, SkFixed new_max)
    291 {
    292     SkASSERT(old_min < old_max);
    293     SkASSERT(new_min <= new_max);
    294     return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
    295 }
    296 
    297 struct MapRanges {
    298     SkFixed old_val;
    299     SkFixed new_val;
    300 };
    301 
    302 static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) {
    303     // -Inf to [0]
    304     if (val < ranges[0].old_val) {
    305         return ranges[0].new_val;
    306     }
    307 
    308     // Linear from [i] to [i+1]
    309     for (int i = 0; i < rangesCount - 1; ++i) {
    310         if (val < ranges[i+1].old_val) {
    311             return map_range(val, ranges[i].old_val, ranges[i+1].old_val,
    312                                   ranges[i].new_val, ranges[i+1].new_val);
    313         }
    314     }
    315 
    316     // From [n] to +Inf
    317     // if (fcweight < Inf)
    318     return ranges[rangesCount-1].new_val;
    319 }
    320 
    321 static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
    322     return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount));
    323 }
    324 
    325 template<int n> struct SkTFixed {
    326     static_assert(-32768 <= n && n <= 32767, "SkTFixed_n_not_in_range");
    327     static const SkFixed value = static_cast<SkFixed>(n << 16);
    328 };
    329 
    330 static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
    331     typedef SkFontStyle SkFS;
    332 
    333     static const MapRanges weightRanges[] = {
    334         { SkTFixed<FC_WEIGHT_THIN>::value,       SkTFixed<SkFS::kThin_Weight>::value },
    335         { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value },
    336         { SkTFixed<FC_WEIGHT_LIGHT>::value,      SkTFixed<SkFS::kLight_Weight>::value },
    337         { SkTFixed<FC_WEIGHT_REGULAR>::value,    SkTFixed<SkFS::kNormal_Weight>::value },
    338         { SkTFixed<FC_WEIGHT_MEDIUM>::value,     SkTFixed<SkFS::kMedium_Weight>::value },
    339         { SkTFixed<FC_WEIGHT_DEMIBOLD>::value,   SkTFixed<SkFS::kSemiBold_Weight>::value },
    340         { SkTFixed<FC_WEIGHT_BOLD>::value,       SkTFixed<SkFS::kBold_Weight>::value },
    341         { SkTFixed<FC_WEIGHT_EXTRABOLD>::value,  SkTFixed<SkFS::kExtraBold_Weight>::value },
    342         { SkTFixed<FC_WEIGHT_BLACK>::value,      SkTFixed<SkFS::kBlack_Weight>::value },
    343         { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<SkFS::kExtraBlack_Weight>::value },
    344     };
    345     int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
    346                             weightRanges, SK_ARRAY_COUNT(weightRanges));
    347 
    348     static const MapRanges widthRanges[] = {
    349         { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value },
    350         { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value },
    351         { SkTFixed<FC_WIDTH_CONDENSED>::value,      SkTFixed<SkFS::kCondensed_Width>::value },
    352         { SkTFixed<FC_WIDTH_SEMICONDENSED>::value,  SkTFixed<SkFS::kSemiCondensed_Width>::value },
    353         { SkTFixed<FC_WIDTH_NORMAL>::value,         SkTFixed<SkFS::kNormal_Width>::value },
    354         { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value,   SkTFixed<SkFS::kSemiExpanded_Width>::value },
    355         { SkTFixed<FC_WIDTH_EXPANDED>::value,       SkTFixed<SkFS::kExpanded_Width>::value },
    356         { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value,  SkTFixed<SkFS::kExtraExpanded_Width>::value },
    357         { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value,  SkTFixed<SkFS::kUltraExpanded_Width>::value },
    358     };
    359     int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
    360                            widthRanges, SK_ARRAY_COUNT(widthRanges));
    361 
    362     SkFS::Slant slant = SkFS::kUpright_Slant;
    363     switch (get_int(pattern, FC_SLANT, FC_SLANT_ROMAN)) {
    364         case FC_SLANT_ROMAN:   slant = SkFS::kUpright_Slant; break;
    365         case FC_SLANT_ITALIC : slant = SkFS::kItalic_Slant ; break;
    366         case FC_SLANT_OBLIQUE: slant = SkFS::kOblique_Slant; break;
    367         default: SkASSERT(false); break;
    368     }
    369 
    370     return SkFontStyle(weight, width, slant);
    371 }
    372 
    373 static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
    374     FCLocker::AssertHeld();
    375 
    376     typedef SkFontStyle SkFS;
    377 
    378     static const MapRanges weightRanges[] = {
    379         { SkTFixed<SkFS::kThin_Weight>::value,       SkTFixed<FC_WEIGHT_THIN>::value },
    380         { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value },
    381         { SkTFixed<SkFS::kLight_Weight>::value,      SkTFixed<FC_WEIGHT_LIGHT>::value },
    382         { SkTFixed<SkFS::kNormal_Weight>::value,     SkTFixed<FC_WEIGHT_REGULAR>::value },
    383         { SkTFixed<SkFS::kMedium_Weight>::value,     SkTFixed<FC_WEIGHT_MEDIUM>::value },
    384         { SkTFixed<SkFS::kSemiBold_Weight>::value,   SkTFixed<FC_WEIGHT_DEMIBOLD>::value },
    385         { SkTFixed<SkFS::kBold_Weight>::value,       SkTFixed<FC_WEIGHT_BOLD>::value },
    386         { SkTFixed<SkFS::kExtraBold_Weight>::value,  SkTFixed<FC_WEIGHT_EXTRABOLD>::value },
    387         { SkTFixed<SkFS::kBlack_Weight>::value,      SkTFixed<FC_WEIGHT_BLACK>::value },
    388         { SkTFixed<SkFS::kExtraBlack_Weight>::value, SkTFixed<FC_WEIGHT_EXTRABLACK>::value },
    389     };
    390     int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges));
    391 
    392     static const MapRanges widthRanges[] = {
    393         { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value },
    394         { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value },
    395         { SkTFixed<SkFS::kCondensed_Width>::value,      SkTFixed<FC_WIDTH_CONDENSED>::value },
    396         { SkTFixed<SkFS::kSemiCondensed_Width>::value,  SkTFixed<FC_WIDTH_SEMICONDENSED>::value },
    397         { SkTFixed<SkFS::kNormal_Width>::value,         SkTFixed<FC_WIDTH_NORMAL>::value },
    398         { SkTFixed<SkFS::kSemiExpanded_Width>::value,   SkTFixed<FC_WIDTH_SEMIEXPANDED>::value },
    399         { SkTFixed<SkFS::kExpanded_Width>::value,       SkTFixed<FC_WIDTH_EXPANDED>::value },
    400         { SkTFixed<SkFS::kExtraExpanded_Width>::value,  SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value },
    401         { SkTFixed<SkFS::kUltraExpanded_Width>::value,  SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value },
    402     };
    403     int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
    404 
    405     int slant = FC_SLANT_ROMAN;
    406     switch (style.slant()) {
    407         case SkFS::kUpright_Slant: slant = FC_SLANT_ROMAN  ; break;
    408         case SkFS::kItalic_Slant : slant = FC_SLANT_ITALIC ; break;
    409         case SkFS::kOblique_Slant: slant = FC_SLANT_OBLIQUE; break;
    410         default: SkASSERT(false); break;
    411     }
    412 
    413     FcPatternAddInteger(pattern, FC_WEIGHT, weight);
    414     FcPatternAddInteger(pattern, FC_WIDTH , width);
    415     FcPatternAddInteger(pattern, FC_SLANT , slant);
    416 }
    417 
    418 class SkTypeface_stream : public SkTypeface_FreeType {
    419 public:
    420     /** @param data takes ownership of the font data.*/
    421     SkTypeface_stream(std::unique_ptr<SkFontData> data,
    422                       SkString familyName, const SkFontStyle& style, bool fixedWidth)
    423         : INHERITED(style, fixedWidth)
    424         , fFamilyName(std::move(familyName))
    425         , fData(std::move(data))
    426     { }
    427 
    428     void onGetFamilyName(SkString* familyName) const override {
    429         *familyName = fFamilyName;
    430     }
    431 
    432     void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
    433         *serialize = true;
    434     }
    435 
    436     SkStreamAsset* onOpenStream(int* ttcIndex) const override {
    437         *ttcIndex = fData->getIndex();
    438         return fData->getStream()->duplicate().release();
    439     }
    440 
    441     std::unique_ptr<SkFontData> onMakeFontData() const override {
    442         return skstd::make_unique<SkFontData>(*fData);
    443     }
    444 
    445 private:
    446     SkString fFamilyName;
    447     const std::unique_ptr<const SkFontData> fData;
    448 
    449     typedef SkTypeface_FreeType INHERITED;
    450 };
    451 
    452 class SkTypeface_fontconfig : public SkTypeface_FreeType {
    453 public:
    454     /** @param pattern takes ownership of the reference. */
    455     static SkTypeface_fontconfig* Create(FcPattern* pattern) {
    456         return new SkTypeface_fontconfig(pattern);
    457     }
    458     mutable SkAutoFcPattern fPattern;
    459 
    460     void onGetFamilyName(SkString* familyName) const override {
    461         *familyName = get_string(fPattern, FC_FAMILY);
    462     }
    463 
    464     void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
    465         FCLocker lock;
    466         desc->setFamilyName(get_string(fPattern, FC_FAMILY));
    467         desc->setFullName(get_string(fPattern, FC_FULLNAME));
    468         desc->setPostscriptName(get_string(fPattern, FC_POSTSCRIPT_NAME));
    469         desc->setStyle(this->fontStyle());
    470         *serialize = false;
    471     }
    472 
    473     SkStreamAsset* onOpenStream(int* ttcIndex) const override {
    474         FCLocker lock;
    475         *ttcIndex = get_int(fPattern, FC_INDEX, 0);
    476         return SkStream::MakeFromFile(get_string(fPattern, FC_FILE)).release();
    477     }
    478 
    479     void onFilterRec(SkScalerContextRec* rec) const override {
    480         const FcMatrix* fcMatrix = get_matrix(fPattern, FC_MATRIX);
    481         if (fcMatrix) {
    482             // fPost2x2 is column-major, left handed (y down).
    483             // FcMatrix is column-major, right handed (y up).
    484             SkMatrix fm;
    485             fm.setAll(fcMatrix->xx,-fcMatrix->xy, 0,
    486                      -fcMatrix->yx, fcMatrix->yy, 0,
    487                       0           , 0           , 1);
    488 
    489             SkMatrix sm;
    490             rec->getMatrixFrom2x2(&sm);
    491 
    492             sm.preConcat(fm);
    493             rec->fPost2x2[0][0] = sm.getScaleX();
    494             rec->fPost2x2[0][1] = sm.getSkewX();
    495             rec->fPost2x2[1][0] = sm.getSkewY();
    496             rec->fPost2x2[1][1] = sm.getScaleY();
    497         }
    498         if (get_bool(fPattern, FC_EMBOLDEN)) {
    499             rec->fFlags |= SkScalerContext::kEmbolden_Flag;
    500         }
    501         this->INHERITED::onFilterRec(rec);
    502     }
    503 
    504     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
    505         std::unique_ptr<SkAdvancedTypefaceMetrics> info =
    506             this->INHERITED::onGetAdvancedMetrics();
    507 
    508         // Simulated fonts shouldn't be considered to be of the type of their data.
    509         if (get_matrix(fPattern, FC_MATRIX) || get_bool(fPattern, FC_EMBOLDEN)) {
    510             info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
    511         }
    512         return info;
    513     }
    514 
    515     ~SkTypeface_fontconfig() override {
    516         // Hold the lock while unrefing the pattern.
    517         FCLocker lock;
    518         fPattern.reset();
    519     }
    520 
    521 private:
    522     /** @param pattern takes ownership of the reference. */
    523     SkTypeface_fontconfig(FcPattern* pattern)
    524         : INHERITED(skfontstyle_from_fcpattern(pattern),
    525                     FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL))
    526         , fPattern(pattern)
    527     { }
    528 
    529     typedef SkTypeface_FreeType INHERITED;
    530 };
    531 
    532 class SkFontMgr_fontconfig : public SkFontMgr {
    533     mutable SkAutoFcConfig fFC;
    534     sk_sp<SkDataTable> fFamilyNames;
    535     SkTypeface_FreeType::Scanner fScanner;
    536 
    537     class StyleSet : public SkFontStyleSet {
    538     public:
    539         /** @param parent does not take ownership of the reference.
    540          *  @param fontSet takes ownership of the reference.
    541          */
    542         StyleSet(const SkFontMgr_fontconfig* parent, FcFontSet* fontSet)
    543             : fFontMgr(SkRef(parent)), fFontSet(fontSet)
    544         { }
    545 
    546         ~StyleSet() override {
    547             // Hold the lock while unrefing the font set.
    548             FCLocker lock;
    549             fFontSet.reset();
    550         }
    551 
    552         int count() override { return fFontSet->nfont; }
    553 
    554         void getStyle(int index, SkFontStyle* style, SkString* styleName) override {
    555             if (index < 0 || fFontSet->nfont <= index) {
    556                 return;
    557             }
    558 
    559             FCLocker lock;
    560             if (style) {
    561                 *style = skfontstyle_from_fcpattern(fFontSet->fonts[index]);
    562             }
    563             if (styleName) {
    564                 *styleName = get_string(fFontSet->fonts[index], FC_STYLE);
    565             }
    566         }
    567 
    568         SkTypeface* createTypeface(int index) override {
    569             FCLocker lock;
    570 
    571             FcPattern* match = fFontSet->fonts[index];
    572             return fFontMgr->createTypefaceFromFcPattern(match);
    573         }
    574 
    575         SkTypeface* matchStyle(const SkFontStyle& style) override {
    576             FCLocker lock;
    577 
    578             SkAutoFcPattern pattern;
    579             fcpattern_from_skfontstyle(style, pattern);
    580             FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern);
    581             FcDefaultSubstitute(pattern);
    582 
    583             FcResult result;
    584             FcFontSet* fontSets[1] = { fFontSet };
    585             SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC,
    586                                                  fontSets, SK_ARRAY_COUNT(fontSets),
    587                                                  pattern, &result));
    588             if (nullptr == match) {
    589                 return nullptr;
    590             }
    591 
    592             return fFontMgr->createTypefaceFromFcPattern(match);
    593         }
    594 
    595     private:
    596         sk_sp<const SkFontMgr_fontconfig> fFontMgr;
    597         SkAutoFcFontSet fFontSet;
    598     };
    599 
    600     static bool FindName(const SkTDArray<const char*>& list, const char* str) {
    601         int count = list.count();
    602         for (int i = 0; i < count; ++i) {
    603             if (!strcmp(list[i], str)) {
    604                 return true;
    605             }
    606         }
    607         return false;
    608     }
    609 
    610     static sk_sp<SkDataTable> GetFamilyNames(FcConfig* fcconfig) {
    611         FCLocker lock;
    612 
    613         SkTDArray<const char*> names;
    614         SkTDArray<size_t> sizes;
    615 
    616         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
    617         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
    618             // Return value of FcConfigGetFonts must not be destroyed.
    619             FcFontSet* allFonts(FcConfigGetFonts(fcconfig, fcNameSet[setIndex]));
    620             if (nullptr == allFonts) {
    621                 continue;
    622             }
    623 
    624             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
    625                 FcPattern* current = allFonts->fonts[fontIndex];
    626                 for (int id = 0; ; ++id) {
    627                     FcChar8* fcFamilyName;
    628                     FcResult result = FcPatternGetString(current, FC_FAMILY, id, &fcFamilyName);
    629                     if (FcResultNoId == result) {
    630                         break;
    631                     }
    632                     if (FcResultMatch != result) {
    633                         continue;
    634                     }
    635                     const char* familyName = reinterpret_cast<const char*>(fcFamilyName);
    636                     if (familyName && !FindName(names, familyName)) {
    637                         *names.append() = familyName;
    638                         *sizes.append() = strlen(familyName) + 1;
    639                     }
    640                 }
    641             }
    642         }
    643 
    644         return SkDataTable::MakeCopyArrays((void const *const *)names.begin(),
    645                                            sizes.begin(), names.count());
    646     }
    647 
    648     static bool FindByFcPattern(SkTypeface* cached, void* ctx) {
    649         SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
    650         FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
    651         return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
    652     }
    653 
    654     mutable SkMutex fTFCacheMutex;
    655     mutable SkTypefaceCache fTFCache;
    656     /** Creates a typeface using a typeface cache.
    657      *  @param pattern a complete pattern from FcFontRenderPrepare.
    658      */
    659     SkTypeface* createTypefaceFromFcPattern(FcPattern* pattern) const {
    660         FCLocker::AssertHeld();
    661         SkAutoMutexAcquire ama(fTFCacheMutex);
    662         SkTypeface* face = fTFCache.findByProcAndRef(FindByFcPattern, pattern);
    663         if (nullptr == face) {
    664             FcPatternReference(pattern);
    665             face = SkTypeface_fontconfig::Create(pattern);
    666             if (face) {
    667                 // Cannot hold the lock when calling add; an evicted typeface may need to lock.
    668                 FCLocker::Suspend suspend;
    669                 fTFCache.add(face);
    670             }
    671         }
    672         return face;
    673     }
    674 
    675 public:
    676     /** Takes control of the reference to 'config'. */
    677     explicit SkFontMgr_fontconfig(FcConfig* config)
    678         : fFC(config ? config : FcInitLoadConfigAndFonts())
    679         , fFamilyNames(GetFamilyNames(fFC)) { }
    680 
    681     ~SkFontMgr_fontconfig() override {
    682         // Hold the lock while unrefing the config.
    683         FCLocker lock;
    684         fFC.reset();
    685     }
    686 
    687 protected:
    688     int onCountFamilies() const override {
    689         return fFamilyNames->count();
    690     }
    691 
    692     void onGetFamilyName(int index, SkString* familyName) const override {
    693         familyName->set(fFamilyNames->atStr(index));
    694     }
    695 
    696     SkFontStyleSet* onCreateStyleSet(int index) const override {
    697         return this->onMatchFamily(fFamilyNames->atStr(index));
    698     }
    699 
    700     /** True if any string object value in the font is the same
    701      *         as a string object value in the pattern.
    702      */
    703     static bool AnyMatching(FcPattern* font, FcPattern* pattern, const char* object) {
    704         FcChar8* fontString;
    705         FcChar8* patternString;
    706         FcResult result;
    707         // Set an arbitrary limit on the number of pattern object values to consider.
    708         // TODO: re-write this to avoid N*M
    709         static const int maxId = 16;
    710         for (int patternId = 0; patternId < maxId; ++patternId) {
    711             result = FcPatternGetString(pattern, object, patternId, &patternString);
    712             if (FcResultNoId == result) {
    713                 break;
    714             }
    715             if (FcResultMatch != result) {
    716                 continue;
    717             }
    718             for (int fontId = 0; fontId < maxId; ++fontId) {
    719                 result = FcPatternGetString(font, object, fontId, &fontString);
    720                 if (FcResultNoId == result) {
    721                     break;
    722                 }
    723                 if (FcResultMatch != result) {
    724                     continue;
    725                 }
    726                 if (0 == FcStrCmpIgnoreCase(patternString, fontString)) {
    727                     return true;
    728                 }
    729             }
    730         }
    731         return false;
    732     }
    733 
    734     static bool FontAccessible(FcPattern* font) {
    735         // FontConfig can return fonts which are unreadable.
    736         const char* filename = get_string(font, FC_FILE, nullptr);
    737         if (nullptr == filename) {
    738             return false;
    739         }
    740         return sk_exists(filename, kRead_SkFILE_Flag);
    741     }
    742 
    743     static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) {
    744         return AnyMatching(font, pattern, FC_FAMILY);
    745     }
    746 
    747     static bool FontContainsCharacter(FcPattern* font, uint32_t character) {
    748         FcResult result;
    749         FcCharSet* matchCharSet;
    750         for (int charSetId = 0; ; ++charSetId) {
    751             result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet);
    752             if (FcResultNoId == result) {
    753                 break;
    754             }
    755             if (FcResultMatch != result) {
    756                 continue;
    757             }
    758             if (FcCharSetHasChar(matchCharSet, character)) {
    759                 return true;
    760             }
    761         }
    762         return false;
    763     }
    764 
    765     SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
    766         if (!familyName) {
    767             return nullptr;
    768         }
    769         FCLocker lock;
    770 
    771         SkAutoFcPattern pattern;
    772         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
    773         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
    774         FcDefaultSubstitute(pattern);
    775 
    776         FcPattern* matchPattern;
    777         SkAutoFcPattern strongPattern(nullptr);
    778         if (familyName) {
    779             strongPattern.reset(FcPatternDuplicate(pattern));
    780             remove_weak(strongPattern, FC_FAMILY);
    781             matchPattern = strongPattern;
    782         } else {
    783             matchPattern = pattern;
    784         }
    785 
    786         SkAutoFcFontSet matches;
    787         // TODO: Some families have 'duplicates' due to symbolic links.
    788         // The patterns are exactly the same except for the FC_FILE.
    789         // It should be possible to collapse these patterns by normalizing.
    790         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
    791         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
    792             // Return value of FcConfigGetFonts must not be destroyed.
    793             FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex]));
    794             if (nullptr == allFonts) {
    795                 continue;
    796             }
    797 
    798             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
    799                 FcPattern* font = allFonts->fonts[fontIndex];
    800                 if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) {
    801                     FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font));
    802                 }
    803             }
    804         }
    805 
    806         return new StyleSet(this, matches.release());
    807     }
    808 
    809     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
    810                                            const SkFontStyle& style) const override
    811     {
    812         FCLocker lock;
    813 
    814         SkAutoFcPattern pattern;
    815         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
    816         fcpattern_from_skfontstyle(style, pattern);
    817         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
    818         FcDefaultSubstitute(pattern);
    819 
    820         // We really want to match strong (prefered) and same (acceptable) only here.
    821         // If a family name was specified, assume that any weak matches after the last strong match
    822         // are weak (default) and ignore them.
    823         // The reason for is that after substitution the pattern for 'sans-serif' looks like
    824         // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults.
    825         // So it is possible to have weakly matching but preferred names.
    826         // In aliases, bindings are weak by default, so this is easy and common.
    827         // If no family name was specified, we'll probably only get weak matches, but that's ok.
    828         FcPattern* matchPattern;
    829         SkAutoFcPattern strongPattern(nullptr);
    830         if (familyName) {
    831             strongPattern.reset(FcPatternDuplicate(pattern));
    832             remove_weak(strongPattern, FC_FAMILY);
    833             matchPattern = strongPattern;
    834         } else {
    835             matchPattern = pattern;
    836         }
    837 
    838         FcResult result;
    839         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
    840         if (nullptr == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) {
    841             return nullptr;
    842         }
    843 
    844         return createTypefaceFromFcPattern(font);
    845     }
    846 
    847     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
    848                                                     const SkFontStyle& style,
    849                                                     const char* bcp47[],
    850                                                     int bcp47Count,
    851                                                     SkUnichar character) const override
    852     {
    853         FCLocker lock;
    854 
    855         SkAutoFcPattern pattern;
    856         if (familyName) {
    857             FcValue familyNameValue;
    858             familyNameValue.type = FcTypeString;
    859             familyNameValue.u.s = reinterpret_cast<const FcChar8*>(familyName);
    860             FcPatternAddWeak(pattern, FC_FAMILY, familyNameValue, FcFalse);
    861         }
    862         fcpattern_from_skfontstyle(style, pattern);
    863 
    864         SkAutoFcCharSet charSet;
    865         FcCharSetAddChar(charSet, character);
    866         FcPatternAddCharSet(pattern, FC_CHARSET, charSet);
    867 
    868         if (bcp47Count > 0) {
    869             SkASSERT(bcp47);
    870             SkAutoFcLangSet langSet;
    871             for (int i = bcp47Count; i --> 0;) {
    872                 FcLangSetAdd(langSet, (const FcChar8*)bcp47[i]);
    873             }
    874             FcPatternAddLangSet(pattern, FC_LANG, langSet);
    875         }
    876 
    877         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
    878         FcDefaultSubstitute(pattern);
    879 
    880         FcResult result;
    881         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
    882         if (nullptr == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) {
    883             return nullptr;
    884         }
    885 
    886         return createTypefaceFromFcPattern(font);
    887     }
    888 
    889     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
    890                                          const SkFontStyle& style) const override
    891     {
    892         //TODO: should the SkTypeface_fontconfig know its family?
    893         const SkTypeface_fontconfig* fcTypeface =
    894                 static_cast<const SkTypeface_fontconfig*>(typeface);
    895         return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style);
    896     }
    897 
    898     sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
    899                                             int ttcIndex) const override {
    900         const size_t length = stream->getLength();
    901         if (length <= 0 || (1u << 30) < length) {
    902             return nullptr;
    903         }
    904 
    905         SkString name;
    906         SkFontStyle style;
    907         bool isFixedWidth = false;
    908         if (!fScanner.scanFont(stream.get(), ttcIndex, &name, &style, &isFixedWidth, nullptr)) {
    909             return nullptr;
    910         }
    911 
    912         auto data = skstd::make_unique<SkFontData>(std::move(stream), ttcIndex, nullptr, 0);
    913         return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name),
    914                                                        style, isFixedWidth));
    915     }
    916 
    917     sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
    918                                            const SkFontArguments& args) const override {
    919         using Scanner = SkTypeface_FreeType::Scanner;
    920         bool isFixedPitch;
    921         SkFontStyle style;
    922         SkString name;
    923         Scanner::AxisDefinitions axisDefinitions;
    924         if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(),
    925                                &name, &style, &isFixedPitch, &axisDefinitions))
    926         {
    927             return nullptr;
    928         }
    929 
    930         SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
    931         Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(),
    932                                    axisValues, name);
    933 
    934         auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(),
    935                                                    axisValues.get(), axisDefinitions.count());
    936         return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(data), std::move(name),
    937                                                        style, isFixedPitch));
    938     }
    939 
    940     sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override {
    941         return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
    942     }
    943 
    944     sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
    945         return this->makeFromStream(SkStream::MakeFromFile(path), ttcIndex);
    946     }
    947 
    948     sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData> fontData) const override {
    949         SkStreamAsset* stream(fontData->getStream());
    950         const size_t length = stream->getLength();
    951         if (length <= 0 || (1u << 30) < length) {
    952             return nullptr;
    953         }
    954 
    955         const int ttcIndex = fontData->getIndex();
    956         SkString name;
    957         SkFontStyle style;
    958         bool isFixedWidth = false;
    959         if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedWidth, nullptr)) {
    960             return nullptr;
    961         }
    962 
    963         return sk_sp<SkTypeface>(new SkTypeface_stream(std::move(fontData), std::move(name),
    964                                                        style, isFixedWidth));
    965     }
    966 
    967     sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override {
    968         sk_sp<SkTypeface> typeface(this->matchFamilyStyle(familyName, style));
    969         if (typeface) {
    970             return typeface;
    971         }
    972 
    973         return sk_sp<SkTypeface>(this->matchFamilyStyle(nullptr, style));
    974     }
    975 };
    976 
    977 SK_API sk_sp<SkFontMgr> SkFontMgr_New_FontConfig(FcConfig* fc) {
    978     return sk_make_sp<SkFontMgr_fontconfig>(fc);
    979 }
    980