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, |