Apply font variations when loading fonts

Parse font variation settings and pass them on to
freetype when loading fonts.
This commit is contained in:
Matthias Clasen 2017-09-17 10:54:58 -04:00 committed by Behdad Esfahbod
parent a8ae2eafc8
commit 721b7ea0a7

View file

@ -3628,6 +3628,70 @@ cairo_ft_font_face_get_synthesize (cairo_font_face_t *font_face)
return ft->ft_options.synth_flags;
}
static void
cairo_ft_apply_variations (FT_Face face,
const char *variations)
{
FT_MM_Var *ft_mm_var;
FT_Error ret;
ret = FT_Get_MM_Var (face, &ft_mm_var);
if (ret == 0) {
FT_Fixed *coords;
unsigned int i;
const char *p;
coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis);
for (i = 0; i < ft_mm_var->num_axis; i++)
coords[i] = ft_mm_var->axis[i].def;
p = variations;
while (p && *p) {
char *start;
char *end, *end2;
FT_ULong tag;
double value;
while (_cairo_isspace (*p)) p++;
start = p;
end = strchr (p, ',');
if (end && (end - p < 6))
goto skip;
tag = FT_MAKE_TAG(p[0], p[1], p[2], p[3]);
p += 4;
while (_cairo_isspace (*p)) p++;
if (*p == '=') p++;
if (p - start < 5)
goto skip;
value = _cairo_strtod (p, &end2);
while (end2 && _cairo_isspace (*end2)) end2++;
if (end2 && (*end2 != ',' && *end2 != '\0'))
goto skip;
for (i = 0; i < ft_mm_var->num_axis; i++) {
if (ft_mm_var->axis[i].tag == tag) {
coords[i] = (FT_Fixed)(value*65536);
break;
}
}
skip:
p = end ? end + 1 : NULL;
}
FT_Set_Var_Design_Coordinates (face, ft_mm_var->num_axis, coords);
free (coords);
}
}
/**
* cairo_ft_scaled_font_lock_face:
* @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
@ -3636,7 +3700,8 @@ cairo_ft_font_face_get_synthesize (cairo_font_face_t *font_face)
* cairo_ft_font_face_create_for_ft_face()).
*
* cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
* backend font and scales it appropriately for the font. You must
* backend font and scales it appropriately for the font and applies OpenType
* font variations if applicable. You must
* release the face with cairo_ft_scaled_font_unlock_face()
* when you are done using it. Since the #FT_Face object can be
* shared between multiple #cairo_scaled_font_t objects, you must not
@ -3689,6 +3754,8 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
return NULL;
}
cairo_ft_apply_variations (face, scaled_font->base.options.variations);
/* Note: We deliberately release the unscaled font's mutex here,
* so that we are not holding a lock across two separate calls to
* cairo function, (which would give the application some