Chromium Code Reviews| Index: src/ports/SkFontMgr_fontconfig.cpp |
| diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp |
| index b54835d1be68d07e73e11d5531509d47c217b206..3b08ff4bb753df4bcc3ec7bb076ded56057a9712 100644 |
| --- a/src/ports/SkFontMgr_fontconfig.cpp |
| +++ b/src/ports/SkFontMgr_fontconfig.cpp |
| @@ -106,6 +106,7 @@ public: |
| SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, P> >(obj) {} |
| }; |
| +typedef SkAutoFc<FcCharSet, FcCharSetDestroy> SkAutoFcCharSet; |
| typedef SkAutoFc<FcConfig, FcConfigDestroy> SkAutoFcConfig; |
| typedef SkAutoFc<FcFontSet, FcFontSetDestroy> SkAutoFcFontSet; |
| typedef SkAutoFc<FcLangSet, FcLangSetDestroy> SkAutoFcLangSet; |
| @@ -650,17 +651,35 @@ protected: |
| return false; |
| } |
| - static bool ValidPattern(FcPattern* pattern) { |
| + static bool FontAccessible(FcPattern* font) { |
| // FontConfig can return fonts which are unreadable. |
| - const char* filename = get_string(pattern, FC_FILE, NULL); |
| + const char* filename = get_string(font, FC_FILE, NULL); |
| if (NULL == filename) { |
| return false; |
| } |
| return sk_exists(filename, kRead_SkFILE_Flag); |
| } |
| - static bool FontMatches(FcPattern* font, FcPattern* pattern) { |
| - return ValidPattern(font) && AnyMatching(font, pattern, FC_FAMILY); |
| + static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) { |
| + return AnyMatching(font, pattern, FC_FAMILY); |
| + } |
| + |
| + static bool FontContainsCharacter(FcPattern* font, uint32_t character) { |
| + FcResult result; |
| + FcCharSet* matchCharSet; |
| + for (int charSetId = 0; ; ++charSetId) { |
| + result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet); |
| + if (FcResultNoId == result) { |
| + break; |
| + } |
| + if (FcResultMatch != result) { |
|
mtklein
2014/08/28 21:32:23
// just a sanity check
bungeman-skia
2014/09/09 19:06:17
Acknowledged.
|
| + continue; |
| + } |
| + if (FcCharSetHasChar(matchCharSet, character)) { |
| + return true; |
| + } |
| + } |
| + return false; |
| } |
| virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE { |
| @@ -698,9 +717,9 @@ protected: |
| } |
| for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) { |
| - if (FontMatches(allFonts->fonts[fontIndex], matchPattern)) { |
| - FcFontSetAdd(matches, |
| - FcFontRenderPrepare(fFC, pattern, allFonts->fonts[fontIndex])); |
| + FcPattern* font = allFonts->fonts[fontIndex]; |
| + if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) { |
| + FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font)); |
| } |
| } |
| } |
| @@ -742,12 +761,49 @@ protected: |
| } |
| FcResult result; |
| - SkAutoFcPattern match(FcFontMatch(fFC, pattern, &result)); |
| - if (NULL == match || !FontMatches(match, matchPattern)) { |
| + SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); |
| + if (NULL == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) { |
| + return NULL; |
| + } |
| + |
| + return createTypefaceFromFcPattern(font); |
| + } |
| + |
| + virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
| + const SkFontStyle& style, |
| + const char bpc47[], |
|
mtklein
2014/08/28 21:32:23
/* may be NULL*/ ?
bungeman-skia
2014/09/09 19:06:17
This sort of comment needs to be over in SkFontMgr
|
| + uint32_t character) const SK_OVERRIDE |
| + { |
| + FCLocker lock; |
| + |
| + SkAutoFcPattern pattern(FcPatternCreate()); |
| + if (NULL == pattern) { |
|
mtklein
2014/08/28 21:32:23
add SkASSERT(pattern) ?
bungeman-skia
2014/09/09 19:06:17
Done.
|
| + return NULL; |
| + } |
| + |
| + FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| + fcpattern_from_skfontstyle(style, pattern); |
| + |
| + SkAutoFcCharSet charSet(FcCharSetCreate()); |
|
mtklein
2014/08/28 21:32:23
No null check?
bungeman-skia
2014/09/09 19:06:17
Done.
|
| + FcCharSetAddChar(charSet, character); |
| + FcPatternAddCharSet(pattern, FC_CHARSET, charSet); |
| + |
| + if (bpc47) { |
| + SkAutoFcLangSet langSet(FcLangSetCreate()); |
|
mtklein
2014/08/28 21:32:23
...
bungeman-skia
2014/09/09 19:06:17
Done.
|
| + FcLangSetAdd(langSet, (const FcChar8*)bpc47); |
| + FcPatternAddLangSet(pattern, FC_LANG, langSet); |
| + } |
| + |
| + FcConfigSubstitute(fFC, pattern, FcMatchPattern); |
| + FcDefaultSubstitute(pattern); |
| + |
| + FcResult result; |
| + SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); |
| + if (NULL == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) { |
| return NULL; |
| } |
| - return createTypefaceFromFcPattern(match); |
| + return createTypefaceFromFcPattern(font); |
| } |
| virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, |