summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/pangofc-font.c109
1 files changed, 86 insertions, 23 deletions
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 0bb25ba5..247ea1a0 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -45,6 +45,9 @@
#include "pango-layout.h"
#include "pango-impl-utils.h"
+#include <ft2build.h>
+#include FT_MULTIPLE_MASTERS_H
+
#include <harfbuzz/hb-ot.h>
enum {
@@ -901,36 +904,89 @@ get_font_size (PangoFcFontKey *key)
}
static void
-parse_variations (const char *variations,
- hb_variation_t **hb_variations,
- guint *n_variations)
+set_variation (hb_variation_t *vars,
+ unsigned int n,
+ hb_variation_t *var)
{
- guint n;
- hb_variation_t *var;
int i;
- const char *p;
- n = 1;
- for (i = 0; variations[i]; i++)
+ for (i = 0; i < n; i++)
{
- if (variations[i] == ',')
- n++;
+ if (vars[i].tag == var->tag)
+ {
+ vars[i].value = var->value;
+ break;
+ }
}
+}
- var = g_new (hb_variation_t, n);
+static void
+parse_variations (hb_variation_t *vars,
+ unsigned int n,
+ const char *variations)
+{
+ hb_variation_t var;
+ const char *p;
p = variations;
- n = 0;
while (p && *p)
{
char *end = strchr (p, ',');
- if (hb_variation_from_string (p, end ? end - p: -1, &var[n]))
- n++;
+ if (hb_variation_from_string (p, end ? end - p: -1, &var))
+ set_variation (vars, n, &var);
p = end ? end + 1 : NULL;
}
+}
+
+#define FixedToFloat(f) (((float)(f))/65536.0)
+
+static gboolean
+get_font_variations (PangoFcFont *fc_font,
+ hb_variation_t **vars,
+ unsigned int *n)
+{
+ FT_Face ft_face;
+ FT_MM_Var *ft_mm_var;
+ int ret;
+ gboolean retval;
+
+ retval = FALSE;
+
+ ft_face = pango_fc_font_lock_face (fc_font);
+
+ ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
+ if (ret == 0)
+ {
+ FT_Fixed *coords;
+ unsigned int ret;
+
+ coords = g_new (FT_Fixed, ft_mm_var->num_axis);
+ ret = FT_Get_Var_Design_Coordinates (ft_face, ft_mm_var->num_axis, coords);
+ if (ret == 0)
+ {
+ hb_variation_t *v;
+ int i;
+
+ v = g_new (hb_variation_t, ft_mm_var->num_axis);
+
+ for (i = 0; i < ft_mm_var->num_axis; i++)
+ {
+ v[i].tag = ft_mm_var->axis[i].tag;
+ v[i].value = FixedToFloat (coords[i]);
+ }
+
+ *vars = v;
+ *n = ft_mm_var->num_axis;
+ retval = TRUE;
+ }
+ g_free (coords);
+
+ free (ft_mm_var);
+ }
- *hb_variations = var;
- *n_variations = n;
+ pango_fc_font_unlock_face (fc_font);
+
+ return retval;
}
static hb_font_t *
@@ -969,18 +1025,25 @@ pango_fc_font_create_hb_font (PangoFont *font)
hb_font_set_scale (hb_font,
size * PANGO_SCALE * x_scale,
size * PANGO_SCALE * y_scale);
+
if (key)
{
- const char *variations = pango_fc_font_key_get_variations (key);
- if (variations)
+ FcPattern *pattern = pango_fc_font_key_get_pattern (key);
+ const char *variations;
+ hb_variation_t *vars;
+ unsigned int n;
+
+ if (get_font_variations (fc_font, &vars, &n))
{
- guint n_variations;
- hb_variation_t *hb_variations;
+ if (FcPatternGetString (pattern, PANGO_FC_FONT_VARIATIONS, 0, (FcChar8 **)&variations) == FcResultMatch)
+ parse_variations (vars, n, variations);
- parse_variations (variations, &hb_variations, &n_variations);
- hb_font_set_variations (hb_font, hb_variations, n_variations);
+ variations = pango_fc_font_key_get_variations (key);
+ if (variations)
+ parse_variations (vars, n, variations);
- g_free (hb_variations);
+ hb_font_set_variations (hb_font, vars, n);
+ g_free (vars);
}
}