Index: src/ports/SkFontConfigInterface_direct.cpp |
=================================================================== |
--- src/ports/SkFontConfigInterface_direct.cpp (revision 8796) |
+++ src/ports/SkFontConfigInterface_direct.cpp (working copy) |
@@ -65,6 +65,19 @@ |
/////////////////////////////////////////////////////////////////////////////// |
+// Returns the string from the pattern, or NULL |
+static const char* get_name(FcPattern* pattern, const char field[], |
+ int index = 0) { |
+ const char* name; |
+ if (FcPatternGetString(pattern, field, index, |
+ (FcChar8**)&name) != FcResultMatch) { |
+ name = NULL; |
+ } |
+ return name; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
namespace { |
// Equivalence classes, used to match the Liberation and other fonts |
@@ -238,54 +251,54 @@ |
strcasecmp(family_cstr, "monospace") == 0; |
} |
+static bool valid_pattern(FcPattern* pattern) { |
+ FcBool is_scalable; |
+ if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch |
+ || !is_scalable) { |
+ return false; |
+ } |
+ |
+ // fontconfig can also return fonts which are unreadable |
+ const char* c_filename = get_name(pattern, FC_FILE); |
+ if (!c_filename) { |
+ return false; |
+ } |
+ if (access(c_filename, R_OK) != 0) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
// Find matching font from |font_set| for the given font family. |
FcPattern* MatchFont(FcFontSet* font_set, |
- FcChar8* post_config_family, |
+ const char* post_config_family, |
const std::string& family) { |
// Older versions of fontconfig have a bug where they cannot select |
// only scalable fonts so we have to manually filter the results. |
FcPattern* match = NULL; |
for (int i = 0; i < font_set->nfont; ++i) { |
FcPattern* current = font_set->fonts[i]; |
- FcBool is_scalable; |
- |
- if (FcPatternGetBool(current, FC_SCALABLE, 0, |
- &is_scalable) != FcResultMatch || |
- !is_scalable) { |
- continue; |
+ if (valid_pattern(current)) { |
+ match = current; |
+ break; |
} |
- |
- // fontconfig can also return fonts which are unreadable |
- FcChar8* c_filename; |
- if (FcPatternGetString(current, FC_FILE, 0, &c_filename) != FcResultMatch) |
- continue; |
- |
- if (access(reinterpret_cast<char*>(c_filename), R_OK) != 0) |
- continue; |
- |
- match = current; |
- break; |
} |
if (match && !IsFallbackFontAllowed(family)) { |
bool acceptable_substitute = false; |
for (int id = 0; id < 255; ++id) { |
- FcChar8* post_match_family; |
- if (FcPatternGetString(match, FC_FAMILY, id, &post_match_family) != |
- FcResultMatch) |
+ const char* post_match_family = get_name(match, FC_FAMILY, id); |
+ if (!post_match_family) |
break; |
acceptable_substitute = |
- (strcasecmp(reinterpret_cast<char*>(post_config_family), |
- reinterpret_cast<char*>(post_match_family)) == 0 || |
+ (strcasecmp(post_config_family, post_match_family) == 0 || |
// Workaround for Issue 12530: |
// requested family: "Bitstream Vera Sans" |
// post_config_family: "Arial" |
// post_match_family: "Bitstream Vera Sans" |
// -> We should treat this case as a good match. |
- strcasecmp(family.c_str(), |
- reinterpret_cast<char*>(post_match_family)) == 0) || |
- IsMetricCompatibleReplacement(family.c_str(), |
- reinterpret_cast<char*>(post_match_family)); |
+ strcasecmp(family.c_str(), post_match_family) == 0) || |
+ IsMetricCompatibleReplacement(family.c_str(), post_match_family); |
if (acceptable_substitute) |
break; |
} |
@@ -398,9 +411,12 @@ |
// -> BAD match |
// |
// However, we special-case fallback fonts; see IsFallbackFontAllowed(). |
- FcChar8* post_config_family; |
- FcPatternGetString(pattern, FC_FAMILY, 0, &post_config_family); |
+ const char* post_config_family = get_name(pattern, FC_FAMILY); |
+ if (!post_config_family) { |
+ return false; |
+ } |
+ |
FcResult result; |
FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); |
if (!font_set) { |
@@ -419,13 +435,14 @@ |
// From here out we just extract our results from 'match' |
- if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResultMatch) { |
+ post_config_family = get_name(match, FC_FAMILY); |
+ if (!post_config_family) { |
FcFontSetDestroy(font_set); |
return false; |
} |
- FcChar8* c_filename; |
- if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) { |
+ const char* c_filename = get_name(match, FC_FILE); |
+ if (!c_filename) { |
FcFontSetDestroy(font_set); |
return false; |
} |
@@ -440,10 +457,10 @@ |
if (outIdentity) { |
outIdentity->fTTCIndex = face_index; |
- outIdentity->fString.set((const char*)c_filename); |
+ outIdentity->fString.set(c_filename); |
} |
if (outFamilyName) { |
- outFamilyName->set((const char*)post_config_family); |
+ outFamilyName->set(post_config_family); |
} |
if (outStyle) { |
*outStyle = GetFontStyle(match); |
@@ -457,14 +474,6 @@ |
/////////////////////////////////////////////////////////////////////////////// |
-static const char* get_name(FcPattern* pattern, const char field[]) { |
- const char* name; |
- if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch) { |
- name = ""; |
- } |
- return name; |
-} |
- |
static bool find_name(const SkTDArray<const char*>& list, const char* str) { |
int count = list.count(); |
for (int i = 0; i < count; ++i) { |
@@ -492,7 +501,7 @@ |
for (int i = 0; i < fs->nfont; ++i) { |
FcPattern* match = fs->fonts[i]; |
const char* famName = get_name(match, FC_FAMILY); |
- if (!find_name(names, famName)) { |
+ if (famName && !find_name(names, famName)) { |
*names.append() = famName; |
*sizes.append() = strlen(famName) + 1; |
} |