[pango/wip/matthiasc/font-variations] wip: nonworking
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/wip/matthiasc/font-variations] wip: nonworking
- Date: Thu, 7 Sep 2017 11:50:52 +0000 (UTC)
commit 50aebebe07019a3b33b8e7a6f7b1ce5b60290acd
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Sep 5 23:21:38 2017 -0400
wip: nonworking
pango/fonts.c | 60 ++++++++++++++++++++++++++++-----
pango/pangocairo-fcfont.c | 80 ++++++++++++++++++++++++++++++++++++++++++-
pango/pangocairo-font.c | 17 ++++++++-
pango/pangocairo-private.h | 5 ++-
pango/pangofc-fontmap.c | 16 ++++++++-
pango/pangofc-fontmap.h | 2 +
pango/pangofc-shape.c | 42 +++++++++++++++++++++++
7 files changed, 207 insertions(+), 15 deletions(-)
---
diff --git a/pango/fonts.c b/pango/fonts.c
index 71a0e00..a6d48c6 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -56,6 +56,7 @@ struct _PangoFontDescription
guint16 mask;
guint static_family : 1;
+ guint static_variations : 1;
guint size_is_absolute : 1;
int size;
@@ -77,6 +78,7 @@ static const PangoFontDescription pfd_defaults = {
0, /* mask */
0, /* static_family */
+ 0, /* static_variations*/
FALSE, /* size_is_absolute */
0, /* size */
@@ -483,18 +485,39 @@ pango_font_description_get_gravity (const PangoFontDescription *desc)
}
void
-pango_font_description_set_variations (PangoFontDescription *desc,
- const char *variations)
+pango_font_description_set_variations_static (PangoFontDescription *desc,
+ const char *variations)
{
g_return_if_fail (desc != NULL);
- g_free (desc->variations);
- desc->variations = g_strdup (variations);
+ if (desc->variations == variations)
+ return;
+
+ if (desc->variations && !desc->static_variations)
+ g_free (desc->variations);
- if (variations != NULL)
- desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+ if (variations)
+ {
+ desc->variations = (char *)variations;
+ desc->static_variations = TRUE;
+ desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+ }
else
- desc->mask &= ~PANGO_FONT_MASK_VARIATIONS;
+ {
+ desc->variations = pfd_defaults.variations;
+ desc->static_variations = pfd_defaults.static_variations;
+ desc->mask &= ~PANGO_FONT_MASK_VARIATIONS;
+ }
+}
+void
+pango_font_description_set_variations (PangoFontDescription *desc,
+ const char *variations)
+{
+ g_return_if_fail (desc != NULL);
+
+ pango_font_description_set_variations_static (desc, g_strdup (variations));
+ if (variations)
+ desc->static_variations = FALSE;
}
const char *
@@ -567,6 +590,7 @@ pango_font_description_merge (PangoFontDescription *desc,
gboolean replace_existing)
{
gboolean family_merged;
+ gboolean variations_merged;
g_return_if_fail (desc != NULL);
@@ -574,6 +598,7 @@ pango_font_description_merge (PangoFontDescription *desc,
return;
family_merged = desc_to_merge->family_name && (replace_existing || !desc->family_name);
+ variations_merged = desc_to_merge->variations && (replace_existing || !desc->variations);
pango_font_description_merge_static (desc, desc_to_merge, replace_existing);
@@ -582,6 +607,12 @@ pango_font_description_merge (PangoFontDescription *desc,
desc->family_name = g_strdup (desc->family_name);
desc->static_family = FALSE;
}
+
+ if (variations_merged)
+ {
+ desc->variations = g_strdup (desc->variations);
+ desc->static_variations = FALSE;
+ }
}
/**
@@ -629,6 +660,8 @@ pango_font_description_merge_static (PangoFontDescription *desc,
}
if (new_mask & PANGO_FONT_MASK_GRAVITY)
desc->gravity = desc_to_merge->gravity;
+ if (new_mask & PANGO_FONT_MASK_VARIATIONS)
+ pango_font_description_set_variations_static (desc, desc_to_merge->variations);
desc->mask |= new_mask;
}
@@ -724,6 +757,7 @@ pango_font_description_copy (const PangoFontDescription *desc)
}
result->variations = g_strdup (result->variations);
+ result->static_variations = FALSE;
return result;
}
@@ -756,6 +790,10 @@ pango_font_description_copy_static (const PangoFontDescription *desc)
if (result->family_name)
result->static_family = TRUE;
+
+ if (result->variations)
+ result->static_variations = TRUE;
+
return result;
}
@@ -857,7 +895,8 @@ pango_font_description_free (PangoFontDescription *desc)
if (desc->family_name && !desc->static_family)
g_free (desc->family_name);
- g_free (desc->variations);
+ if (desc->variations && !desc->static_variations)
+ g_free (desc->variations);
g_slice_free (PangoFontDescription, desc);
}
@@ -1112,7 +1151,10 @@ parse_variations (const char *word,
char **variations)
{
if (word[0] != '@')
- return FALSE;
+ {
+ *variations = NULL;
+ return FALSE;
+ }
/* XXX: actually validate here */
*variations = g_strndup (word + 1, wordlen - 1);
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
index 30ecde4..f39a4d7 100644
--- a/pango/pangocairo-fcfont.c
+++ b/pango/pangocairo-fcfont.c
@@ -33,6 +33,9 @@
#include "pangofc-private.h"
#include "pango-impl-utils.h"
+#include <hb-ot.h>
+#include <freetype/ftmm.h>
+
#define PANGO_TYPE_CAIRO_FC_FONT (pango_cairo_fc_font_get_type ())
#define PANGO_CAIRO_FC_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT,
PangoCairoFcFont))
#define PANGO_CAIRO_FC_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_FC_FONT,
PangoCairoFcFontClass))
@@ -115,16 +118,88 @@ pango_cairo_fc_font_get_glyph_extents (PangoFont *font,
logical_rect);
}
+#define FloatToFixed(f) ((FT_Fixed)((f)*65536))
+
+gboolean
+parse_variation_settings (FT_MM_Var *amaster,
+ const char *settings,
+ FT_UInt *num_coords,
+ FT_Fixed **coords)
+{
+ int i;
+
+ *num_coords = amaster->num_axis;
+ *coords = g_new (FT_Fixed, amaster->num_axis);
+
+ for (i = 0; i < amaster->num_axis; i++)
+ {
+ FT_Var_Axis *axis = &amaster->axis[i];
+ char tag[5];
+ char *p;
+ FT_Fixed value = axis->def;
+
+ hb_tag_to_string (axis->tag, tag);
+ tag[4] = '\0';
+
+ p = strstr (settings, tag);
+ if (p && p[4] == '=')
+ {
+ char *end = NULL;
+ double dval;
+ dval = g_ascii_strtod (p + 5, &end);
+ if (end != NULL && *end != ',' && *end != '\0')
+ g_warning ("Failed to parse axis value for %s", tag);
+ else
+ value = FloatToFixed(dval);
+ }
+
+ *coords[i] = value;
+ }
+
+ return TRUE;
+}
+
+static void
+apply_font_variation (FT_Face ft_face,
+ const char *settings)
+{
+ FT_MM_Var *amaster = NULL;
+ FT_UInt num_coords;
+ FT_Fixed *coords;
+ FT_Error err;
+
+ if ((err = FT_Get_MM_Var (ft_face, &amaster)) != 0)
+ {
+ g_warning ("Failed to load font variation descriptor (%d)", err);
+ return;
+ }
+
+ if (parse_variation_settings (amaster, settings, &num_coords, &coords))
+ {
+ if ((err = FT_Set_MM_Design_Coordinates (ft_face, num_coords, coords)) != 0)
+ g_warning ("Failed to set font variation (%d)", err);
+ }
+
+ free (amaster);
+}
+
static FT_Face
pango_cairo_fc_font_lock_face (PangoFcFont *font)
{
PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font);
cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&cffont->cf_priv);
+ const char *settings = _pango_cairo_font_private_get_variation_settings (&cffont->cf_priv);
+ FT_Face ft_face;
if (G_UNLIKELY (!scaled_font))
return NULL;
- return cairo_ft_scaled_font_lock_face (scaled_font);
+ ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ if (settings)
+ apply_font_variation (ft_face, settings);
+
+ return ft_face;
}
static void
@@ -252,7 +327,8 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
get_gravity (pattern),
pango_fc_font_key_get_context_key (key),
pango_fc_font_key_get_matrix (key),
- &font_matrix);
+ &font_matrix,
+ pango_fc_font_key_get_variation (key));
((PangoFcFont *)(cffont))->is_hinted = _pango_cairo_font_private_is_metrics_hinted (&cffont->cf_priv);
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index b86f85b..8fb8746 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -55,6 +55,7 @@ _pango_cairo_font_private_scaled_font_data_destroy (PangoCairoFontPrivateScaledF
if (data)
{
cairo_font_options_destroy (data->options);
+ g_free (data->variation_settings);
g_slice_free (PangoCairoFontPrivateScaledFontData, data);
}
}
@@ -134,6 +135,15 @@ done:
return cf_priv->scaled_font;
}
+const char *
+_pango_cairo_font_private_get_variation_settings (PangoCairoFontPrivate *cf_priv)
+{
+ if (G_UNLIKELY (cf_priv->data == NULL))
+ return NULL;
+
+ return cf_priv->data->variation_settings;
+}
+
/**
* pango_cairo_font_get_scaled_font:
* @font: a #PangoFont from a #PangoCairoFontMap
@@ -589,14 +599,15 @@ _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv,
PangoGravity gravity,
const cairo_font_options_t *font_options,
const PangoMatrix *pango_ctm,
- const cairo_matrix_t *font_matrix)
+ const cairo_matrix_t *font_matrix,
+ const char *variation_settings)
{
cairo_matrix_t gravity_matrix;
cf_priv->cfont = cfont;
cf_priv->gravity = gravity;
- cf_priv->data = _pango_cairo_font_private_scaled_font_data_create ();
+ cf_priv->data = _pango_cairo_font_private_scaled_font_data_create ();
/* first apply gravity rotation, then font_matrix, such that
* vertical italic text comes out "correct". we don't do anything
@@ -619,6 +630,8 @@ _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv,
cairo_matrix_init_identity (&cf_priv->data->ctm);
cf_priv->data->options = cairo_font_options_copy (font_options);
+ cf_priv->data->variation_settings = g_strdup (variation_settings);
+
cf_priv->is_hinted = cairo_font_options_get_hint_metrics (font_options) != CAIRO_HINT_METRICS_OFF;
cf_priv->scaled_font = NULL;
diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h
index 704ae49..85cbf9e 100644
--- a/pango/pangocairo-private.h
+++ b/pango/pangocairo-private.h
@@ -70,6 +70,7 @@ struct _PangoCairoFontPrivateScaledFontData
cairo_matrix_t font_matrix;
cairo_matrix_t ctm;
cairo_font_options_t *options;
+ char *variation_settings;
};
struct _PangoCairoFontPrivate
@@ -112,9 +113,11 @@ void _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv,
PangoGravity gravity,
const cairo_font_options_t *font_options,
const PangoMatrix *pango_ctm,
- const cairo_matrix_t *font_matrix);
+ const cairo_matrix_t *font_matrix,
+ const char *variation_settings);
void _pango_cairo_font_private_finalize (PangoCairoFontPrivate *cf_priv);
cairo_scaled_font_t *_pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *cf_priv);
+const char *_pango_cairo_font_private_get_variation_settings (PangoCairoFontPrivate *cf_priv);
gboolean _pango_cairo_font_private_is_metrics_hinted (PangoCairoFontPrivate *cf_priv);
void _pango_cairo_font_private_get_glyph_extents (PangoCairoFontPrivate *cf_priv,
PangoGlyph glyph,
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 70e9ee7..da22463 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -364,6 +364,7 @@ struct _PangoFcFontKey {
FcPattern *pattern;
PangoMatrix matrix;
gpointer context_key;
+ char *variation;
};
static void
@@ -569,7 +570,8 @@ pango_fc_font_key_equal (const PangoFcFontKey *key_a,
const PangoFcFontKey *key_b)
{
if (key_a->pattern == key_b->pattern &&
- 0 == memcmp (&key_a->matrix, &key_b->matrix, 4 * sizeof (double)))
+ 0 == memcmp (&key_a->matrix, &key_b->matrix, 4 * sizeof (double)) &&
+ 0 == g_strcmp0 (key_a->variation, key_b->variation))
{
if (key_a->context_key && key_b->context_key)
return PANGO_FC_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap,
@@ -594,6 +596,9 @@ pango_fc_font_key_hash (const PangoFcFontKey *key)
hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,
key->context_key);
+ if (key->variation)
+ hash ^= g_str_hash (key->variation);
+
return (hash ^ GPOINTER_TO_UINT (key->pattern));
}
@@ -607,6 +612,8 @@ pango_fc_font_key_free (PangoFcFontKey *key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
+ g_free (key->variation);
+
g_slice_free (PangoFcFontKey, key);
}
@@ -624,6 +631,7 @@ pango_fc_font_key_copy (const PangoFcFontKey *old)
old->context_key);
else
key->context_key = NULL;
+ key->variation = g_strdup (old->variation);
return key;
}
@@ -638,6 +646,7 @@ pango_fc_font_key_init (PangoFcFontKey *key,
key->pattern = pattern;
key->matrix = *pango_fc_fontset_key_get_matrix (fontset_key);
key->context_key = pango_fc_fontset_key_get_context_key (fontset_key);
+ key->variation = g_strdup (pango_font_description_get_variations (pango_fc_fontset_key_get_description
(fontset_key)));
}
/* Public API */
@@ -690,6 +699,11 @@ pango_fc_font_key_get_context_key (const PangoFcFontKey *key)
return key->context_key;
}
+const char *
+pango_fc_font_key_get_variation (const PangoFcFontKey *key)
+{
+ return key->variation;
+}
/*
* PangoFcPatterns
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index 4dab083..24e303a 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -71,6 +71,8 @@ PANGO_AVAILABLE_IN_1_24
const PangoMatrix *pango_fc_font_key_get_matrix (const PangoFcFontKey *key);
PANGO_AVAILABLE_IN_1_24
gpointer pango_fc_font_key_get_context_key (const PangoFcFontKey *key);
+PANGO_AVAILABLE_IN_1_40
+const char *pango_fc_font_key_get_variation (const PangoFcFontKey *key);
#endif
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index 60f829f..1a82ffc 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -282,6 +282,38 @@ pango_fc_get_hb_font_funcs (void)
return funcs;
}
+static void
+parse_variations (const char *variations,
+ hb_variation_t **hb_variations,
+ guint *n_variations)
+{
+ guint n;
+ hb_variation_t *var;
+ int i;
+ const char *p;
+
+ n = 1;
+ for (i = 0; variations[i]; i++)
+ {
+ if (variations[i] == ',')
+ n++;
+ }
+
+ var = g_new (hb_variation_t, n);
+
+ p = variations;
+ n = 0;
+ while (p && *p)
+ {
+ char *end = strchr (p, ',');
+ if (hb_variation_from_string (p, end ? end - p: -1, &var[n]))
+ n++;
+ p = end ? end + 1 : NULL;
+ }
+
+ *hb_variations = var;
+ *n_variations = n;
+}
void
_pango_fc_shape (PangoFont *font,
@@ -310,6 +342,7 @@ _pango_fc_shape (PangoFont *font,
unsigned int num_features = 0;
double x_scale_inv, y_scale_inv;
PangoGlyphInfo *infos;
+ const char *variations;
g_return_if_fail (font != NULL);
g_return_if_fail (analysis != NULL);
@@ -350,6 +383,15 @@ _pango_fc_shape (PangoFont *font,
hb_font_set_ppem (hb_font,
fc_font->is_hinted ? ft_face->size->metrics.x_ppem : 0,
fc_font->is_hinted ? ft_face->size->metrics.y_ppem : 0);
+ variations = pango_fc_font_key_get_variation (key);
+ if (variations)
+ {
+ guint n_variations;
+ hb_variation_t *hb_variations;
+ parse_variations (variations, &hb_variations, &n_variations);
+ hb_font_set_variations (hb_font, hb_variations, n_variations);
+ g_free (hb_variations);
+ }
hb_buffer = acquire_buffer (&free_buffer);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]