summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-03 22:44:09 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-03 22:44:09 +0000
commitb3467a4dd2f9d7c6473c1fcd22a31c2ac39a2d88 (patch)
treee2f55061517c5aaf3e87beca9c335bfcc9e530c1 /skia
parent378f3ac5cd7c0c170cf3e8e54aa627defcb590da (diff)
downloadchromium_src-b3467a4dd2f9d7c6473c1fcd22a31c2ac39a2d88.zip
chromium_src-b3467a4dd2f9d7c6473c1fcd22a31c2ac39a2d88.tar.gz
chromium_src-b3467a4dd2f9d7c6473c1fcd22a31c2ac39a2d88.tar.bz2
Linux: support css font-family fallback.
Currently we'll always take the first element of a font-family list and run with it, using fontconfig's fallback. This adds a, slightly hacky, test to see if the fontconfig result is good enough and, if not, reports the failure back into WebKit so that other font-family elements can be tried. This fixes LayoutTests/css2.1/t040103-escapes-01-b.html Review URL: http://codereview.chromium.org/12914 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6320 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ports/SkFontHost_fontconfig.cpp50
-rw-r--r--skia/sgl/SkTypeface.cpp3
2 files changed, 52 insertions, 1 deletions
diff --git a/skia/ports/SkFontHost_fontconfig.cpp b/skia/ports/SkFontHost_fontconfig.cpp
index f36bb2e..42cce0d 100644
--- a/skia/ports/SkFontHost_fontconfig.cpp
+++ b/skia/ports/SkFontHost_fontconfig.cpp
@@ -100,6 +100,7 @@ static FcPattern* FontMatch(const char* type, FcType vtype, const void* value,
va_start(ap, value);
FcPattern* pattern = FcPatternCreate();
+ bool family_requested = false;
for (;;) {
FcValue fcvalue;
@@ -116,6 +117,9 @@ static FcPattern* FontMatch(const char* type, FcType vtype, const void* value,
}
FcPatternAdd(pattern, type, fcvalue, 0);
+ if (vtype == FcTypeString && strcmp(type, FC_FAMILY) == 0)
+ family_requested = true;
+
type = va_arg(ap, const char *);
if (!type)
break;
@@ -128,10 +132,56 @@ static FcPattern* FontMatch(const char* type, FcType vtype, const void* value,
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
+ // Font matching:
+ // CSS often specifies a fallback list of families:
+ // font-family: a, b, c, serif;
+ // However, fontconfig will always do its best to find *a* font when asked
+ // for something so we need a way to tell if the match which it has found is
+ // "good enough" for us. Otherwise, we can return NULL which gets piped up
+ // and lets WebKit know to try the next CSS family name. However, fontconfig
+ // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
+ // wish to support that.
+ //
+ // Thus, if a specific family is requested we set @family_requested. Then we
+ // record two strings: the family name after config processing and the
+ // family name after resolving. If the two are equal, it's a good match.
+ //
+ // So consider the case where a user has mapped Arial to Helvetica in their
+ // config.
+ // requested family: "Arial"
+ // post_config_family: "Helvetica"
+ // post_match_family: "Helvetica"
+ // -> good match
+ //
+ // and for a missing font:
+ // requested family: "Monaco"
+ // post_config_family: "Monaco"
+ // post_match_family: "Times New Roman"
+ // -> BAD match
+ FcChar8* post_config_family;
+ FcPatternGetString(pattern, FC_FAMILY, 0, &post_config_family);
+
FcResult result;
FcPattern* match = FcFontMatch(0, pattern, &result);
+ if (!match) {
+ FcPatternDestroy(pattern);
+ return NULL;
+ }
+
+ FcChar8* post_match_family;
+ FcPatternGetString(match, FC_FAMILY, 0, &post_match_family);
+ const bool family_names_match =
+ !family_requested ?
+ true :
+ strcmp((char *) post_config_family, (char *) post_match_family) == 0;
+
FcPatternDestroy(pattern);
+ if (!family_names_match) {
+ FcPatternDestroy(match);
+ return NULL;
+ }
+
return match;
}
diff --git a/skia/sgl/SkTypeface.cpp b/skia/sgl/SkTypeface.cpp
index 9821c51..79cb631 100644
--- a/skia/sgl/SkTypeface.cpp
+++ b/skia/sgl/SkTypeface.cpp
@@ -26,7 +26,8 @@ bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb)
SkTypeface* SkTypeface::Create(const char name[], Style style)
{
SkTypeface* face = SkFontHost::FindTypeface(NULL, name, style);
- face->ref();
+ if (face)
+ face->ref();
return face;
}