| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2013 Google Inc. | 2  * Copyright 2013 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkFontMgr.h" | 8 #include "SkFontMgr.h" | 
| 9 #include "SkFontStyle.h" | 9 #include "SkFontStyle.h" | 
| 10 #include "SkFontConfigInterface.h" | 10 #include "SkFontConfigInterface.h" | 
| 11 #include "SkFontConfigTypeface.h" | 11 #include "SkFontConfigTypeface.h" | 
| 12 #include "SkMath.h" | 12 #include "SkMath.h" | 
| 13 #include "SkString.h" | 13 #include "SkString.h" | 
| 14 #include "SkTDArray.h" | 14 #include "SkTDArray.h" | 
|  | 15 #include "SkThread.h" | 
| 15 | 16 | 
| 16 // for now we pull these in directly. eventually we will solely rely on the | 17 // for now we pull these in directly. eventually we will solely rely on the | 
| 17 // SkFontConfigInterface instance. | 18 // SkFontConfigInterface instance. | 
| 18 #include <fontconfig/fontconfig.h> | 19 #include <fontconfig/fontconfig.h> | 
| 19 #include <unistd.h> | 20 #include <unistd.h> | 
| 20 | 21 | 
|  | 22 namespace { | 
|  | 23 | 
|  | 24 // Fontconfig is not threadsafe before 2.10.91.  Before that, we lock with a glo
     bal mutex. | 
|  | 25 // See skia:1497 for background. | 
|  | 26 SK_DECLARE_STATIC_MUTEX(gFCMutex); | 
|  | 27 static bool gFCSafeToUse; | 
|  | 28 | 
|  | 29 struct FCLocker { | 
|  | 30     FCLocker() { | 
|  | 31         if (FcGetVersion() < 21091) {  // We assume FcGetVersion() has always be
     en thread safe. | 
|  | 32             gFCMutex.acquire(); | 
|  | 33             fUnlock = true; | 
|  | 34         } else { | 
|  | 35             fUnlock = false; | 
|  | 36         } | 
|  | 37         gFCSafeToUse = true; | 
|  | 38     } | 
|  | 39 | 
|  | 40     ~FCLocker() { | 
|  | 41         gFCSafeToUse = false; | 
|  | 42         if (fUnlock) { | 
|  | 43             gFCMutex.release(); | 
|  | 44         } | 
|  | 45     } | 
|  | 46 | 
|  | 47 private: | 
|  | 48     bool fUnlock; | 
|  | 49 }; | 
|  | 50 | 
|  | 51 } // namespace | 
|  | 52 | 
|  | 53 | 
| 21 // Defined in SkFontHost_FreeType.cpp | 54 // Defined in SkFontHost_FreeType.cpp | 
| 22 bool find_name_and_attributes(SkStream* stream, SkString* name, | 55 bool find_name_and_attributes(SkStream* stream, SkString* name, | 
| 23                               SkTypeface::Style* style, bool* isFixedWidth); | 56                               SkTypeface::Style* style, bool* isFixedWidth); | 
| 24 | 57 | 
| 25 // borrow this global from SkFontHost_fontconfig. eventually that file should | 58 // borrow this global from SkFontHost_fontconfig. eventually that file should | 
| 26 // go away, and be replaced with this one. | 59 // go away, and be replaced with this one. | 
| 27 extern SkFontConfigInterface* SkFontHost_fontconfig_ref_global(); | 60 extern SkFontConfigInterface* SkFontHost_fontconfig_ref_global(); | 
| 28 static SkFontConfigInterface* RefFCI() { | 61 static SkFontConfigInterface* RefFCI() { | 
| 29     return SkFontHost_fontconfig_ref_global(); | 62     return SkFontHost_fontconfig_ref_global(); | 
| 30 } | 63 } | 
| 31 | 64 | 
| 32 // look for the last substring after a '/' and return that, or return null. | 65 // look for the last substring after a '/' and return that, or return null. | 
| 33 static const char* find_just_name(const char* str) { | 66 static const char* find_just_name(const char* str) { | 
| 34     const char* last = strrchr(str, '/'); | 67     const char* last = strrchr(str, '/'); | 
| 35     return last ? last + 1 : NULL; | 68     return last ? last + 1 : NULL; | 
| 36 } | 69 } | 
| 37 | 70 | 
| 38 static bool is_lower(char c) { | 71 static bool is_lower(char c) { | 
| 39     return c >= 'a' && c <= 'z'; | 72     return c >= 'a' && c <= 'z'; | 
| 40 } | 73 } | 
| 41 | 74 | 
| 42 static int get_int(FcPattern* pattern, const char field[]) { | 75 static int get_int(FcPattern* pattern, const char field[]) { | 
|  | 76     SkASSERT(gFCSafeToUse); | 
| 43     int value; | 77     int value; | 
| 44     if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) { | 78     if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) { | 
| 45         value = SK_MinS32; | 79         value = SK_MinS32; | 
| 46     } | 80     } | 
| 47     return value; | 81     return value; | 
| 48 } | 82 } | 
| 49 | 83 | 
| 50 static const char* get_name(FcPattern* pattern, const char field[]) { | 84 static const char* get_name(FcPattern* pattern, const char field[]) { | 
|  | 85     SkASSERT(gFCSafeToUse); | 
| 51     const char* name; | 86     const char* name; | 
| 52     if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch
     ) { | 87     if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch
     ) { | 
| 53         name = ""; | 88         name = ""; | 
| 54     } | 89     } | 
| 55     return name; | 90     return name; | 
| 56 } | 91 } | 
| 57 | 92 | 
| 58 static bool valid_pattern(FcPattern* pattern) { | 93 static bool valid_pattern(FcPattern* pattern) { | 
|  | 94     SkASSERT(gFCSafeToUse); | 
| 59     FcBool is_scalable; | 95     FcBool is_scalable; | 
| 60     if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch
      || !is_scalable) { | 96     if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch
      || !is_scalable) { | 
| 61         return false; | 97         return false; | 
| 62     } | 98     } | 
| 63 | 99 | 
| 64     // fontconfig can also return fonts which are unreadable | 100     // fontconfig can also return fonts which are unreadable | 
| 65     const char* c_filename = get_name(pattern, FC_FILE); | 101     const char* c_filename = get_name(pattern, FC_FILE); | 
| 66     if (0 == *c_filename) { | 102     if (0 == *c_filename) { | 
| 67         return false; | 103         return false; | 
| 68     } | 104     } | 
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 201 | 237 | 
| 202     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR
     IDE { | 238     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR
     IDE { | 
| 203         familyName->set(fFamilyNames->atStr(index)); | 239         familyName->set(fFamilyNames->atStr(index)); | 
| 204     } | 240     } | 
| 205 | 241 | 
| 206     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE { | 242     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE { | 
| 207         return this->onMatchFamily(fFamilyNames->atStr(index)); | 243         return this->onMatchFamily(fFamilyNames->atStr(index)); | 
| 208     } | 244     } | 
| 209 | 245 | 
| 210     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
     RIDE { | 246     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
     RIDE { | 
|  | 247         FCLocker lock; | 
|  | 248 | 
| 211         FcPattern* pattern = FcPatternCreate(); | 249         FcPattern* pattern = FcPatternCreate(); | 
| 212 | 250 | 
| 213         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 251         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 
| 214 #if 0 | 252 #if 0 | 
| 215         FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 253         FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 
| 216 #endif | 254 #endif | 
| 217         FcConfigSubstitute(NULL, pattern, FcMatchPattern); | 255         FcConfigSubstitute(NULL, pattern, FcMatchPattern); | 
| 218         FcDefaultSubstitute(pattern); | 256         FcDefaultSubstitute(pattern); | 
| 219 | 257 | 
| 220         const char* post_config_family = get_name(pattern, FC_FAMILY); | 258         const char* post_config_family = get_name(pattern, FC_FAMILY); | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 277         return face; | 315         return face; | 
| 278     } | 316     } | 
| 279 | 317 | 
| 280     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const 
     SK_OVERRIDE { | 318     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const 
     SK_OVERRIDE { | 
| 281         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 319         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 
| 282         return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; | 320         return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; | 
| 283     } | 321     } | 
| 284 | 322 | 
| 285     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 323     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 
| 286                                                unsigned styleBits) const SK_OVER
     RIDE { | 324                                                unsigned styleBits) const SK_OVER
     RIDE { | 
|  | 325         FCLocker lock; | 
| 287         return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName, | 326         return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName, | 
| 288                                                   (SkTypeface::Style)styleBits); | 327                                                   (SkTypeface::Style)styleBits); | 
| 289     } | 328     } | 
| 290 }; | 329 }; | 
| 291 | 330 | 
| 292 SkFontMgr* SkFontMgr::Factory() { | 331 SkFontMgr* SkFontMgr::Factory() { | 
| 293     SkFontConfigInterface* fci = RefFCI(); | 332     SkFontConfigInterface* fci = RefFCI(); | 
| 294     return fci ? SkNEW_ARGS(SkFontMgr_fontconfig, (fci)) : NULL; | 333     return fci ? SkNEW_ARGS(SkFontMgr_fontconfig, (fci)) : NULL; | 
| 295 } | 334 } | 
| OLD | NEW | 
|---|