diff options
author | Grigori Goronzy <greg@blackbox> | 2010-02-10 23:51:11 +0100 |
---|---|---|
committer | Grigori Goronzy <greg@blackbox> | 2010-02-12 01:45:14 +0100 |
commit | f8b730a5f49614f280d328821960380cacea2d02 (patch) | |
tree | 0de6a1b123a622d94399c2e76e9cfed036dd09e4 | |
parent | f92c65f148a339e1861d6bb671cbbc2d968f19df (diff) | |
download | libass-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.c | 64 |
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; |