summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2015-06-14 03:09:10 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2015-07-10 10:43:16 +0200
commit9f62fd8b374235b98a325b6a903d49b2f6bb4cf3 (patch)
treedbbf365c9ea4682da557543e9d24cca3301332cd /libass
parent044b619ac125178ebc65dce79b1101afce28eecc (diff)
downloadlibass-9f62fd8b374235b98a325b6a903d49b2f6bb4cf3.tar.bz2
libass-9f62fd8b374235b98a325b6a903d49b2f6bb4cf3.tar.xz
fontselect: improved face selection among a family
We want the best variant, but if it doesn't have the glyph coverage, we may also use another variant from the same family.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_fontselect.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 26fe579..8c96e61 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -452,6 +452,14 @@ static void font_info_dump(ASS_FontInfo *font_infos, size_t len)
}
#endif
+static int check_glyph(ASS_FontInfo *fi, uint32_t code)
+{
+ ASS_FontProvider *provider = fi->provider;
+ assert(provider && provider->funcs.check_glyph);
+
+ return provider->funcs.check_glyph(fi->priv, code);
+}
+
static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
const char *family, unsigned bold, unsigned italic,
int *index, char **postscript_name, int *uid,
@@ -484,22 +492,33 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
req.fullnames = &req_fullname;
req.fullnames[0] = family_trim;
- // match font
+ // Match font family name against font list
unsigned score_min = UINT_MAX;
for (int i = 0; i < priv->n_font; i++) {
unsigned score = font_info_similarity(&priv->font_infos[i], &req);
- // lowest possible score instantly matches
- if (score == 0) {
- idx = i;
- break;
- }
-
- // update idx if score is better
+ // Consider updating idx if score is better than current minimum
if (score < score_min) {
+ // Check if the font has the requested glyph.
+ // We are doing this here, for every font face, because
+ // coverage might differ between the variants of a font
+ // family. In practice, it is common that the regular
+ // style has the best coverage while bold/italic/etc
+ // variants cover less (e.g. FreeSans family).
+ // We want to be able to match even if the closest variant
+ // does not have the requested glyph, but another member
+ // of the family has the glyph.
+ if (!check_glyph(&priv->font_infos[i], code))
+ continue;
+
score_min = score;
idx = i;
}
+
+ // Lowest possible score instantly matches; this is typical
+ // for fullname matches, but can also occur with family matches.
+ if (score == 0)
+ break;
}
// free font name
@@ -510,15 +529,6 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
return NULL;
}
- // check glyph coverage
- ASS_FontProvider *provider = font_infos[idx].provider;
- if (!provider || !provider->funcs.check_glyph) {
- return NULL;
- }
- if (provider->funcs.check_glyph(font_infos[idx].priv, code) == 0) {
- return NULL;
- }
-
// successfully matched, set up return values
*postscript_name = font_infos[idx].postscript_name;
*index = font_infos[idx].index;