Chromium Code Reviews| 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" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // See skia:1497 for background. | |
| 20 | |
| 21 #if FC_VERSION < 21091 | |
|
bungeman-skia
2014/03/31 17:25:51
I'm not sure that it makes sense to use the versio
mtklein
2014/03/31 17:37:36
Duh, fixed.
| |
| 22 | |
| 23 // Fontconfig is not threadsafe. We sadly need to manually synchronize all Fc.. .() calls. | |
| 24 SK_DECLARE_STATIC_MUTEX(gFCMutex); | |
| 25 static bool gFCSafeToUse; | |
| 26 | |
| 27 struct FCLocker { | |
| 28 FCLocker() { gFCMutex.acquire(); gFCSafeToUse = true; } | |
| 29 ~FCLocker() { gFCSafeToUse = false; gFCMutex.release(); } | |
| 30 }; | |
| 31 | |
| 32 #else | |
| 33 | |
| 34 // Fontconfig is threadsafe. Noops for locking. | |
| 35 static const bool gFCSafeToUse = true; | |
| 36 struct FCLocker { | |
| 37 FCLocker() {} // Stifles unused variable warnings. | |
| 38 }; | |
| 39 | |
| 40 #endif | |
| 41 | |
| 42 } // namespace | |
| 15 | 43 |
| 16 // for now we pull these in directly. eventually we will solely rely on the | 44 // for now we pull these in directly. eventually we will solely rely on the |
| 17 // SkFontConfigInterface instance. | 45 // SkFontConfigInterface instance. |
| 18 #include <fontconfig/fontconfig.h> | 46 #include <fontconfig/fontconfig.h> |
| 19 #include <unistd.h> | 47 #include <unistd.h> |
| 20 | 48 |
| 21 // Defined in SkFontHost_FreeType.cpp | 49 // Defined in SkFontHost_FreeType.cpp |
| 22 bool find_name_and_attributes(SkStream* stream, SkString* name, | 50 bool find_name_and_attributes(SkStream* stream, SkString* name, |
| 23 SkTypeface::Style* style, bool* isFixedWidth); | 51 SkTypeface::Style* style, bool* isFixedWidth); |
| 24 | 52 |
| 25 // borrow this global from SkFontHost_fontconfig. eventually that file should | 53 // borrow this global from SkFontHost_fontconfig. eventually that file should |
| 26 // go away, and be replaced with this one. | 54 // go away, and be replaced with this one. |
| 27 extern SkFontConfigInterface* SkFontHost_fontconfig_ref_global(); | 55 extern SkFontConfigInterface* SkFontHost_fontconfig_ref_global(); |
| 28 static SkFontConfigInterface* RefFCI() { | 56 static SkFontConfigInterface* RefFCI() { |
| 29 return SkFontHost_fontconfig_ref_global(); | 57 return SkFontHost_fontconfig_ref_global(); |
| 30 } | 58 } |
| 31 | 59 |
| 32 // look for the last substring after a '/' and return that, or return null. | 60 // look for the last substring after a '/' and return that, or return null. |
| 33 static const char* find_just_name(const char* str) { | 61 static const char* find_just_name(const char* str) { |
| 34 const char* last = strrchr(str, '/'); | 62 const char* last = strrchr(str, '/'); |
| 35 return last ? last + 1 : NULL; | 63 return last ? last + 1 : NULL; |
| 36 } | 64 } |
| 37 | 65 |
| 38 static bool is_lower(char c) { | 66 static bool is_lower(char c) { |
| 39 return c >= 'a' && c <= 'z'; | 67 return c >= 'a' && c <= 'z'; |
| 40 } | 68 } |
| 41 | 69 |
| 42 static int get_int(FcPattern* pattern, const char field[]) { | 70 static int get_int(FcPattern* pattern, const char field[]) { |
| 71 SkASSERT(gFCSafeToUse); | |
| 43 int value; | 72 int value; |
| 44 if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) { | 73 if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) { |
| 45 value = SK_MinS32; | 74 value = SK_MinS32; |
| 46 } | 75 } |
| 47 return value; | 76 return value; |
| 48 } | 77 } |
| 49 | 78 |
| 50 static const char* get_name(FcPattern* pattern, const char field[]) { | 79 static const char* get_name(FcPattern* pattern, const char field[]) { |
| 80 SkASSERT(gFCSafeToUse); | |
| 51 const char* name; | 81 const char* name; |
| 52 if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch ) { | 82 if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch ) { |
| 53 name = ""; | 83 name = ""; |
| 54 } | 84 } |
| 55 return name; | 85 return name; |
| 56 } | 86 } |
| 57 | 87 |
| 58 static bool valid_pattern(FcPattern* pattern) { | 88 static bool valid_pattern(FcPattern* pattern) { |
| 89 SkASSERT(gFCSafeToUse); | |
| 59 FcBool is_scalable; | 90 FcBool is_scalable; |
| 60 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch || !is_scalable) { | 91 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch || !is_scalable) { |
| 61 return false; | 92 return false; |
| 62 } | 93 } |
| 63 | 94 |
| 64 // fontconfig can also return fonts which are unreadable | 95 // fontconfig can also return fonts which are unreadable |
| 65 const char* c_filename = get_name(pattern, FC_FILE); | 96 const char* c_filename = get_name(pattern, FC_FILE); |
| 66 if (0 == *c_filename) { | 97 if (0 == *c_filename) { |
| 67 return false; | 98 return false; |
| 68 } | 99 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 | 232 |
| 202 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE { | 233 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE { |
| 203 familyName->set(fFamilyNames->atStr(index)); | 234 familyName->set(fFamilyNames->atStr(index)); |
| 204 } | 235 } |
| 205 | 236 |
| 206 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE { | 237 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE { |
| 207 return this->onMatchFamily(fFamilyNames->atStr(index)); | 238 return this->onMatchFamily(fFamilyNames->atStr(index)); |
| 208 } | 239 } |
| 209 | 240 |
| 210 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE { | 241 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE { |
| 242 FCLocker lock; | |
| 243 | |
| 211 FcPattern* pattern = FcPatternCreate(); | 244 FcPattern* pattern = FcPatternCreate(); |
| 212 | 245 |
| 213 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 246 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| 214 #if 0 | 247 #if 0 |
| 215 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 248 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); |
| 216 #endif | 249 #endif |
| 217 FcConfigSubstitute(NULL, pattern, FcMatchPattern); | 250 FcConfigSubstitute(NULL, pattern, FcMatchPattern); |
| 218 FcDefaultSubstitute(pattern); | 251 FcDefaultSubstitute(pattern); |
| 219 | 252 |
| 220 const char* post_config_family = get_name(pattern, FC_FAMILY); | 253 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; | 310 return face; |
| 278 } | 311 } |
| 279 | 312 |
| 280 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { | 313 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { |
| 281 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 314 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 282 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; | 315 return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; |
| 283 } | 316 } |
| 284 | 317 |
| 285 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 318 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
| 286 unsigned styleBits) const SK_OVER RIDE { | 319 unsigned styleBits) const SK_OVER RIDE { |
| 320 FCLocker lock; | |
| 287 return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName, | 321 return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName, |
| 288 (SkTypeface::Style)styleBits); | 322 (SkTypeface::Style)styleBits); |
| 289 } | 323 } |
| 290 }; | 324 }; |
| 291 | 325 |
| 292 SkFontMgr* SkFontMgr::Factory() { | 326 SkFontMgr* SkFontMgr::Factory() { |
| 293 SkFontConfigInterface* fci = RefFCI(); | 327 SkFontConfigInterface* fci = RefFCI(); |
| 294 return fci ? SkNEW_ARGS(SkFontMgr_fontconfig, (fci)) : NULL; | 328 return fci ? SkNEW_ARGS(SkFontMgr_fontconfig, (fci)) : NULL; |
| 295 } | 329 } |
| OLD | NEW |