| Index: src/fonts/SkFontMgr_fontconfig.cpp
|
| diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
|
| index bd4c8ddc1db2a275b51c4d0b586efadcbf183b0d..1d17111b79213820b68a046302383f47931a4c54 100644
|
| --- a/src/fonts/SkFontMgr_fontconfig.cpp
|
| +++ b/src/fonts/SkFontMgr_fontconfig.cpp
|
| @@ -12,12 +12,45 @@
|
| #include "SkMath.h"
|
| #include "SkString.h"
|
| #include "SkTDArray.h"
|
| +#include "SkThread.h"
|
|
|
| // for now we pull these in directly. eventually we will solely rely on the
|
| // SkFontConfigInterface instance.
|
| #include <fontconfig/fontconfig.h>
|
| #include <unistd.h>
|
|
|
| +namespace {
|
| +
|
| +// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
|
| +// See skia:1497 for background.
|
| +SK_DECLARE_STATIC_MUTEX(gFCMutex);
|
| +static bool gFCSafeToUse;
|
| +
|
| +struct FCLocker {
|
| + FCLocker() {
|
| + if (FcGetVersion() < 21091) { // We assume FcGetVersion() has always been thread safe.
|
| + gFCMutex.acquire();
|
| + fUnlock = true;
|
| + } else {
|
| + fUnlock = false;
|
| + }
|
| + gFCSafeToUse = true;
|
| + }
|
| +
|
| + ~FCLocker() {
|
| + gFCSafeToUse = false;
|
| + if (fUnlock) {
|
| + gFCMutex.release();
|
| + }
|
| + }
|
| +
|
| +private:
|
| + bool fUnlock;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +
|
| // Defined in SkFontHost_FreeType.cpp
|
| bool find_name_and_attributes(SkStream* stream, SkString* name,
|
| SkTypeface::Style* style, bool* isFixedWidth);
|
| @@ -40,6 +73,7 @@ static bool is_lower(char c) {
|
| }
|
|
|
| static int get_int(FcPattern* pattern, const char field[]) {
|
| + SkASSERT(gFCSafeToUse);
|
| int value;
|
| if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) {
|
| value = SK_MinS32;
|
| @@ -48,6 +82,7 @@ static int get_int(FcPattern* pattern, const char field[]) {
|
| }
|
|
|
| static const char* get_name(FcPattern* pattern, const char field[]) {
|
| + SkASSERT(gFCSafeToUse);
|
| const char* name;
|
| if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch) {
|
| name = "";
|
| @@ -56,6 +91,7 @@ static const char* get_name(FcPattern* pattern, const char field[]) {
|
| }
|
|
|
| static bool valid_pattern(FcPattern* pattern) {
|
| + SkASSERT(gFCSafeToUse);
|
| FcBool is_scalable;
|
| if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch || !is_scalable) {
|
| return false;
|
| @@ -208,6 +244,8 @@ protected:
|
| }
|
|
|
| virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
|
| + FCLocker lock;
|
| +
|
| FcPattern* pattern = FcPatternCreate();
|
|
|
| FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
|
| @@ -284,6 +322,7 @@ protected:
|
|
|
| virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
|
| unsigned styleBits) const SK_OVERRIDE {
|
| + FCLocker lock;
|
| return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName,
|
| (SkTypeface::Style)styleBits);
|
| }
|
|
|