diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | pango/pangofc-font.c | 109 | ||||
-rw-r--r-- | utils/pango-list.c | 58 |
3 files changed, 145 insertions, 23 deletions
@@ -10,6 +10,7 @@ Overview of changes in 1.44.0 - Add an attribute to suppress line breaking - cairo: Don't render hex boxes for space - Add an attribute to show invisible characters +- Stop quantizing glyph positions - Add tests for itemization and line breaking - Remove language and shape engine remnants - Rename meson options: gtk_doc, introspection 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); } } diff --git a/utils/pango-list.c b/utils/pango-list.c index c0f0d4ae..b3688233 100644 --- a/utils/pango-list.c +++ b/utils/pango-list.c @@ -22,18 +22,33 @@ #include "config.h" #include <pango/pangocairo.h> +#include <harfbuzz/hb-ot.h> #include <glib/gstdio.h> #include <stdlib.h> +/* FIXME: This doesn't work if the font has an avar table */ +static float +denorm_coord (hb_ot_var_axis_info_t *axis, int coord) +{ + float r = coord / 16384.0; + + if (coord < 0) + return axis->default_value + r * (axis->default_value - axis->min_value); + else + return axis->default_value + r * (axis->max_value - axis->default_value); +} + int main (int argc, char **argv) { gboolean opt_verbose = FALSE; gboolean opt_metrics = FALSE; + gboolean opt_variations = FALSE; GOptionEntry entries[] = { {"verbose", 0, 0, G_OPTION_ARG_NONE, &opt_verbose, "Print verbose information", NULL }, {"metrics", 0, 0, G_OPTION_ARG_NONE, &opt_metrics, "Print font metrics", NULL }, + {"variations", 0, 0, G_OPTION_ARG_NONE, &opt_variations, "Print font variations", NULL }, { NULL, } }; GOptionContext *context; @@ -133,6 +148,49 @@ main (int argc, pango_font_metrics_unref (metrics); } + if (opt_variations && + pango_font_family_is_variable (families[i])) + { + PangoFont *font; + hb_font_t *hb_font; + const int *coords; + unsigned int length; + + pango_font_description_set_absolute_size (desc, 10 * PANGO_SCALE); + + font = pango_context_load_font (ctx, desc); + hb_font = pango_font_get_hb_font (font); + coords = hb_font_get_var_coords_normalized (hb_font, &length); + if (coords) + { + hb_face_t *hb_face = hb_font_get_face (hb_font); + hb_ot_var_axis_info_t *axes; + unsigned int n_axes; + int i; + + axes = g_new (hb_ot_var_axis_info_t, length); + n_axes = length; + + hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes); + + for (i = 0; i < length; i++) + { + char name[20]; + unsigned int namelen = 20; + + hb_ot_name_get_utf8 (hb_face, axes[i].name_id, HB_LANGUAGE_INVALID, &namelen, name); + + g_print (" %s: %g (%g - %g, %g)\n", + name, + denorm_coord (&axes[i], coords[i]), + axes[i].min_value, + axes[i].max_value, + axes[i].default_value); + } + g_free (axes); + } + } + g_free (desc_str); pango_font_description_free (desc); } |