summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2010-02-10 23:51:11 +0100
committerGrigori Goronzy <greg@blackbox>2010-02-12 01:45:14 +0100
commitf8b730a5f49614f280d328821960380cacea2d02 (patch)
tree0de6a1b123a622d94399c2e76e9cfed036dd09e4
parentf92c65f148a339e1861d6bb671cbbc2d968f19df (diff)
downloadlibass-f8b730a5f49614f280d328821960380cacea2d02.tar.bz2
libass-f8b730a5f49614f280d328821960380cacea2d02.tar.xz
fontconfig: consider fullname for matching fonts
Additionally match fonts via the fullname (or name for humans) and prefer these matches. Previously, libass matched against the family name only and this name can be completely different from the fullname (which is used by VSFilter!).
-rw-r--r--libass/ass_fontconfig.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index 9c9361c..7bc22f3 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -52,6 +52,47 @@ struct fc_instance {
#ifdef CONFIG_FONTCONFIG
/**
+ * \brief Case-insensitive match ASS/SSA font family against full name. (also
+ * known as "name for humans")
+ *
+ * \param lib library instance
+ * \param priv fontconfig instance
+ * \param family font family
+ * \return font set
+ */
+static FcFontSet *match_fullname(ASS_Library *lib, FCInstance *priv,
+ const char *family)
+{
+ FcFontSet *sets[2];
+ FcFontSet *result = FcFontSetCreate();
+ int nsets = 0;
+ int i, fi;
+
+ if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetSystem)))
+ nsets++;
+ if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetApplication)))
+ nsets++;
+
+ // Run over font sets and patterns and try to match against full name
+ for (i = 0; i < nsets; i++) {
+ FcFontSet *set = sets[i];
+ for (fi = 0; fi < set->nfont; fi++) {
+ FcPattern *pat = set->fonts[fi];
+ char *fullname;
+ int pi = 0;
+ while (FcPatternGetString(pat, FC_FULLNAME, pi++,
+ (FcChar8 **) &fullname) == FcResultMatch)
+ if (strcasecmp(fullname, family) == 0) {
+ FcFontSetAdd(result, FcPatternDuplicate(pat));
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+/**
* \brief Low-level font selection.
* \param priv private data
* \param family font family
@@ -74,7 +115,7 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
FcChar8 *r_family, *r_style, *r_file, *r_fullname;
FcBool r_outline, r_embolden;
FcCharSet *r_charset;
- FcFontSet *fset = NULL;
+ FcFontSet *ffullname = NULL, *fsorted = NULL, *fset = NULL;
int curf;
char *retval = NULL;
int family_cnt = 0;
@@ -126,10 +167,23 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
if (!rc)
goto error;
- fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
- if (!fset)
+ fsorted = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
+ ffullname = match_fullname(library, priv, family);
+ if (!fsorted || !ffullname)
goto error;
+ fset = FcFontSetCreate();
+ for (curf = 0; curf < ffullname->nfont; ++curf) {
+ FcPattern *curp = ffullname->fonts[curf];
+ FcPatternReference(curp);
+ FcFontSetAdd(fset, curp);
+ }
+ for (curf = 0; curf < fsorted->nfont; ++curf) {
+ FcPattern *curp = fsorted->fonts[curf];
+ FcPatternReference(curp);
+ FcFontSetAdd(fset, curp);
+ }
+
for (curf = 0; curf < fset->nfont; ++curf) {
FcPattern *curp = fset->fonts[curf];
@@ -215,6 +269,10 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
FcPatternDestroy(pat);
if (rpat)
FcPatternDestroy(rpat);
+ if (fsorted)
+ FcFontSetDestroy(fsorted);
+ if (ffullname)
+ FcFontSetDestroy(ffullname);
if (fset)
FcFontSetDestroy(fset);
return retval;