summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-01-01 22:38:30 -0500
committerMatthias Clasen <mclasen@redhat.com>2022-01-28 09:03:03 -0500
commit7c07ffd678f7415479db251be49860b19a92bc37 (patch)
treef7f24951cfc49f8e5b7c6cd3252aa6907e31caa3
parentb6fb2dca779a4e0f29f9df1d36ded6b44dd5e28a (diff)
downloadpango-7c07ffd678f7415479db251be49860b19a92bc37.tar.gz
pango-list: Show variable faces
Add an '@' to the face name for variable faces. And various other improvements.
-rw-r--r--utils/meson.build3
-rw-r--r--utils/pango-list.c178
2 files changed, 145 insertions, 36 deletions
diff --git a/utils/meson.build b/utils/meson.build
index 6d06dbec..c76d35be 100644
--- a/utils/meson.build
+++ b/utils/meson.build
@@ -67,7 +67,8 @@ if cairo_dep.found()
pango_list_deps = [
pango_deps,
libpango_dep,
- libpangocairo_dep
+ libpangocairo_dep,
+ libpangoft2_dep
]
pango_list = executable('pango-list', pango_list_sources,
diff --git a/utils/pango-list.c b/utils/pango-list.c
index 82a5647c..31eebbd3 100644
--- a/utils/pango-list.c
+++ b/utils/pango-list.c
@@ -22,11 +22,42 @@
#include "config.h"
#include <pango/pangocairo.h>
+#include <pango/pangofc-hbfontmap.h>
+#include <pango/pangofc-font.h>
+#include <pango/pango-hbface-private.h>
#include <hb-ot.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include <locale.h>
+
+#if HB_VERSION_ATLEAST (3, 3, 0)
+static void
+get_axes_and_values (hb_font_t *font,
+ unsigned int n_axes,
+ hb_ot_var_axis_info_t *axes,
+ float *coords)
+{
+ const float *dcoords;
+ unsigned int length = n_axes;
+
+ hb_ot_var_get_axis_infos (hb_font_get_face (font), 0, &length, axes);
+
+ dcoords = hb_font_get_var_coords_design (font, &length);
+ if (dcoords)
+ memcpy (coords, dcoords, sizeof (float) * length);
+ else
+ {
+ for (int i = 0; i < n_axes; i++)
+ {
+ hb_ot_var_axis_info_t *axis = &axes[i];
+ coords[axis->axis_index] = axis->default_value;
+ }
+ }
+}
+
+#else
+
/* 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)
@@ -39,6 +70,31 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
return axis->default_value + r * (axis->max_value - axis->default_value);
}
+static void
+get_axes_and_values (hb_font_t *font,
+ unsigned int n_axes,
+ hb_ot_var_axis_info_t *axes,
+ float *coords)
+{
+ const int *ncoords;
+ unsigned int length = n_axes;
+
+ hb_ot_var_get_axis_infos (hb_font_get_face (font), 0, &length, axes);
+
+ ncoords = hb_font_get_var_coords_normalized (font, &length);
+
+ for (int i = 0; i < n_axes; i++)
+ {
+ hb_ot_var_axis_info_t *axis = &axes[i];
+ int idx = axis->axis_index;
+ if (ncoords)
+ coords[idx] = denorm_coord (axis, ncoords[idx]);
+ else
+ coords[idx] = axis->default_value;
+ }
+}
+#endif
+
int
main (int argc,
char **argv)
@@ -62,6 +118,9 @@ main (int argc,
int i, j;
int width;
GError *error = NULL;
+ hb_ot_var_axis_info_t axes[100];
+ float coords[100];
+ unsigned int n_axes;
g_set_prgname ("pango-list");
setlocale (LC_ALL, "");
@@ -85,7 +144,6 @@ main (int argc,
exit (0);
}
- /* Use PangoCairo to get default fontmap so it works on every platform. */
fontmap = pango_cairo_font_map_get_default ();
ctx = pango_font_map_create_context (fontmap);
@@ -125,25 +183,33 @@ main (int argc,
const char *face_name = pango_font_face_get_face_name (faces[j]);
gboolean is_synth = pango_font_face_is_synthesized (faces[j]);
const char *synth_str = is_synth ? "*" : "";
- width = MAX (width, strlen (synth_str) + strlen (face_name));
+ gboolean is_variable = pango_font_face_is_variable (faces[j]);
+ const char *variable_str = is_variable ? "@" : "";
+ width = MAX (width, strlen (synth_str) + strlen (variable_str) + strlen (face_name));
}
for (j = 0; j < n_faces; j++)
- {
- const char *face_name = pango_font_face_get_face_name (faces[j]);
- gboolean is_synth = pango_font_face_is_synthesized (faces[j]);
- const char *synth_str = is_synth ? "*" : "";
- PangoFontDescription *desc = pango_font_face_describe (faces[j]);
- char *desc_str = pango_font_description_to_string (desc);
+ {
+ const char *face_name = pango_font_face_get_face_name (faces[j]);
+ gboolean is_synth = pango_font_face_is_synthesized (faces[j]);
+ const char *synth_str = is_synth ? "*" : "";
+ gboolean is_variable = pango_font_face_is_variable (faces[j]);
+ const char *variable_str = is_variable ? "@" : "";
+ PangoFontDescription *desc;
+ char *desc_str;
+
+ desc = pango_font_face_describe (faces[j]);
+ desc_str = pango_font_description_to_string (desc);
- g_print (" %s%s: %*s%s\n", synth_str, face_name,
- width - (int)strlen (face_name) - (int)strlen (synth_str), "", desc_str);
+ g_print (" %s%s%s: %*s%s\n", synth_str, variable_str, face_name,
+ width - (int)strlen (face_name) - (int)strlen (synth_str) - (int)strlen (variable_str), "", desc_str);
+
+ pango_font_description_set_absolute_size (desc, 10 * PANGO_SCALE);
if (opt_metrics)
{
PangoFontMetrics *metrics;
- pango_font_description_set_absolute_size (desc, 10 * PANGO_SCALE);
metrics = pango_context_get_metrics (ctx, desc, pango_language_from_string ("en-us"));
g_print (" (a %d d %d h %d cw %d dw %d u %d %d s %d %d)\n",
pango_font_metrics_get_ascent (metrics),
@@ -163,41 +229,83 @@ main (int argc,
{
PangoFont *font;
hb_font_t *hb_font;
- const int *coords;
- unsigned int length;
+ int instance_id = -1;
- pango_font_description_set_absolute_size (desc, 10 * PANGO_SCALE);
+ /* set variations here, to make the fontmap prefer the variable family
+ * over a non-variable one.
+ */
+ pango_font_description_set_variations (desc, "@");
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)
+ if (PANGO_IS_HB_FONT (font))
+ {
+ PangoHbFace *hbface = (PangoHbFace *)faces[j];
+ instance_id = hbface->instance_id;
+ }
+ else if (PANGO_IS_FC_FONT (font))
{
- hb_face_t *hb_face = hb_font_get_face (hb_font);
- hb_ot_var_axis_info_t *axes;
- unsigned int n_axes;
- int i;
+ int index;
+ FcPattern *pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
+ FcPatternGetInteger (pattern, FC_INDEX, 0, (int *)&index);
+ instance_id = (index >> 16) - 1;
+ }
+
+ if (pango_font_face_is_variable (faces[j]))
+ {
+ if (instance_id >= 0)
+ g_print (" Instance %d\n", instance_id);
+ else if (instance_id == -1)
+ g_print (" Default Instance\n");
+ }
- axes = g_new (hb_ot_var_axis_info_t, length);
- n_axes = length;
+ n_axes = hb_ot_var_get_axis_count (hb_font_get_face (hb_font));
+ get_axes_and_values (hb_font, n_axes, axes, coords);
- hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
+ for (int i = 0; i < n_axes; i++)
+ {
+ char name[20];
+ unsigned int namelen = 20;
- for (i = 0; i < length; i++)
- {
- char name[20];
- unsigned int namelen = 20;
+ hb_ot_name_get_utf8 (hb_font_get_face (hb_font), axes[i].name_id, HB_LANGUAGE_INVALID, &namelen, name);
- 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,
+ coords[axes[i].axis_index],
+ axes[i].min_value,
+ axes[i].max_value,
+ axes[i].default_value);
+ }
+
+ g_object_unref (font);
+ }
+
+ if (opt_verbose)
+ {
+ if (PANGO_IS_HB_FACE (faces[j]))
+ {
+ PangoHbFace *hbface = (PangoHbFace *)faces[j];
+
+ if (hbface->file)
+ g_print (" %d %s\n", hbface->index, hbface->file);
+ }
+ else
+ {
+ PangoFont *font;
+
+ font = pango_context_load_font (ctx, desc);
+ if (PANGO_IS_FC_FONT (font))
+ {
+ FcPattern *pattern;
+ const char *file;
+ int index;
- 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);
+ pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
+ FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **)&file);
+ FcPatternGetInteger (pattern, FC_INDEX, 0, &index);
+ g_print (" %d %s\n", index, file);
}
- g_free (axes);
+ g_object_unref (font);
}
}