summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--pango/pangofc-font.c109
-rw-r--r--utils/pango-list.c58
3 files changed, 145 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index d03e54ad..403d0a25 100644
--- a/NEWS
+++ b/NEWS
@@ -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);
}