[pango/hb-getters: 1/3] Move font setup code from the shaper
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/hb-getters: 1/3] Move font setup code from the shaper
- Date: Mon, 19 Nov 2018 18:38:45 +0000 (UTC)
commit b3d7b4992a7556d7243cdaa8755615c73d161af8
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Nov 19 11:47:42 2018 -0500
Move font setup code from the shaper
Move all the code that sets up the hb_font_t to
pango_fc_font_create_hb_font, and use it from
the shaper. This is the second step towards
taking over font management.
pango/pangofc-font.c | 320 +++++++++++++++++++++++++++++++++++++++++++++-
pango/pangofc-fontmap.c | 5 +-
pango/pangofc-shape.c | 333 ++++--------------------------------------------
3 files changed, 347 insertions(+), 311 deletions(-)
---
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index fffc6e2d..7bec790f 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -1068,13 +1068,327 @@ pango_fc_font_get_raw_extents (PangoFcFont *fcfont,
PANGO_FC_FONT_UNLOCK_FACE (fcfont);
}
+typedef struct _PangoFcHbContext {
+ FT_Face ft_face;
+ PangoFcFont *fc_font;
+ gboolean vertical;
+ double x_scale, y_scale; /* CTM scales. */
+} PangoFcHbContext;
+
+static hb_bool_t
+pango_fc_hb_font_get_nominal_glyph (hb_font_t *font, void *font_data,
+ hb_codepoint_t unicode,
+ hb_codepoint_t *glyph,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ PangoFcFont *fc_font = context->fc_font;
+
+ *glyph = pango_fc_font_get_glyph (fc_font, unicode);
+ if (G_LIKELY (*glyph))
+ return TRUE;
+
+ *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
+
+ /* We draw our own invalid-Unicode shape, so prevent HarfBuzz
+ * from using REPLACEMENT CHARACTER. */
+ if (unicode > 0x10FFFF)
+ return TRUE;
+
+ return FALSE;
+}
+
+static hb_bool_t
+pango_fc_hb_font_get_variation_glyph (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ FT_Face ft_face = context->ft_face;
+ unsigned int g;
+
+ g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
+
+ if (G_UNLIKELY (!g))
+ return FALSE;
+
+ *glyph = g;
+ return TRUE;
+}
+
+static hb_bool_t
+pango_fc_hb_font_get_glyph_contour_point (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y,
+ void *user_data G_GNUC_UNUSED)
+{
+ return FALSE;
+#if 0
+ FT_Face ft_face = (FT_Face) font_data;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ /* TODO: load_flags, embolden, etc */
+
+ if (HB_UNLIKELY (FT_Load_Glyph (ft_face, glyph, load_flags)))
+ return FALSE;
+
+ if (HB_UNLIKELY (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
+ return FALSE;
+
+ if (HB_UNLIKELY (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
+ return FALSE;
+
+ *x = ft_face->glyph->outline.points[point_index].x;
+ *y = ft_face->glyph->outline.points[point_index].y;
+
+ return TRUE;
+#endif
+}
+
+static hb_position_t
+pango_fc_hb_font_get_glyph_advance (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ PangoFcFont *fc_font = context->fc_font;
+ PangoRectangle logical;
+
+ pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, NULL, &logical);
+
+ return logical.width;
+}
+
+static hb_bool_t
+pango_fc_hb_font_get_glyph_extents (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ PangoFcFont *fc_font = context->fc_font;
+ PangoRectangle ink;
+
+ pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, &ink, NULL);
+
+ if (G_LIKELY (!context->vertical)) {
+ extents->x_bearing = ink.x;
+ extents->y_bearing = ink.y;
+ extents->width = ink.width;
+ extents->height = ink.height;
+ } else {
+ /* XXX */
+ extents->x_bearing = ink.x;
+ extents->y_bearing = ink.y;
+ extents->width = ink.height;
+ extents->height = ink.width;
+ }
+
+ return TRUE;
+}
+
+static hb_bool_t
+pango_fc_hb_font_get_glyph_h_origin (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ FT_Face ft_face = context->ft_face;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ if (!context->vertical) return TRUE;
+
+ if (FT_Load_Glyph (ft_face, glyph, load_flags))
+ return FALSE;
+
+ /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+ * have a Y growing upward. Hence the extra negations. */
+ *x = -PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX);
+ *y = +PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY));
+
+ return TRUE;
+}
+
+static hb_bool_t
+pango_fc_hb_font_get_glyph_v_origin (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ FT_Face ft_face = context->ft_face;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ /* pangocairo-fc configures font in vertical origin for vertical writing. */
+ if (context->vertical) return TRUE;
+
+ if (FT_Load_Glyph (ft_face, glyph, load_flags))
+ return FALSE;
+
+ /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+ * have a Y growing upward. Hence the extra negation. */
+ *x = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX);
+ *y = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY));
+
+ /* XXX */
+
+ return TRUE;
+}
+
+static hb_position_t
+pango_fc_hb_font_get_h_kerning (hb_font_t *font, void *font_data,
+ hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+ void *user_data G_GNUC_UNUSED)
+{
+ PangoFcHbContext *context = (PangoFcHbContext *) font_data;
+ FT_Face ft_face = context->ft_face;
+ FT_Vector kerning;
+
+ if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
+ return 0;
+
+ return PANGO_UNITS_26_6 (kerning.x * context->x_scale);
+}
+
+static hb_font_funcs_t *
+pango_fc_get_hb_font_funcs (void)
+{
+ static hb_font_funcs_t *funcs;
+
+ if (G_UNLIKELY (!funcs)) {
+ funcs = hb_font_funcs_create ();
+ hb_font_funcs_set_nominal_glyph_func (funcs, pango_fc_hb_font_get_nominal_glyph, NULL, NULL);
+ hb_font_funcs_set_variation_glyph_func (funcs, pango_fc_hb_font_get_variation_glyph, NULL, NULL);
+ hb_font_funcs_set_glyph_h_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_v_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_h_origin_func (funcs, pango_fc_hb_font_get_glyph_h_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_v_origin_func (funcs, pango_fc_hb_font_get_glyph_v_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_fc_hb_font_get_h_kerning, NULL, NULL);
+ /* Don't need v_kerning. */
+ hb_font_funcs_set_glyph_extents_func (funcs, pango_fc_hb_font_get_glyph_extents, NULL, NULL);
+ hb_font_funcs_set_glyph_contour_point_func (funcs, pango_fc_hb_font_get_glyph_contour_point, NULL, NULL);
+ /* Don't need glyph_name / glyph_from_name */
+ }
+
+ return funcs;
+}
+
+extern gpointer get_gravity_class (void);
+
+static PangoGravity
+pango_fc_font_key_get_gravity (PangoFcFontKey *key)
+{
+ FcPattern *pattern;
+ PangoGravity gravity = PANGO_GRAVITY_SOUTH;
+ FcChar8 *s;
+
+ pattern = pango_fc_font_key_get_pattern (key);
+ if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)&s) == FcResultMatch)
+ {
+ GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), (char *)s);
+ gravity = value->value;
+ }
+
+ return gravity;
+}
+
+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;
+}
+
static hb_font_t *
pango_fc_font_create_hb_font (PangoFont *font)
{
- PangoFcFont *fcfont = PANGO_FC_FONT (font);
+ PangoFcFont *fc_font = PANGO_FC_FONT (font);
+ PangoFcFontKey *key;
+ PangoFcHbContext context;
+ FT_Face ft_face;
hb_face_t *hb_face;
+ hb_font_t *hb_font;
+ double x_scale_inv, y_scale_inv;
+ PangoGravity gravity;
+
+ x_scale_inv = y_scale_inv = 1.0;
+ key = _pango_fc_font_get_font_key (fc_font);
+ if (key)
+ {
+ const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key);
+ pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv);
+ }
+ if (PANGO_GRAVITY_IS_IMPROPER (gravity))
+ {
+ x_scale_inv = -x_scale_inv;
+ y_scale_inv = -y_scale_inv;
+ }
- hb_face = pango_fc_font_map_get_hb_face (PANGO_FC_FONT_MAP (fcfont->fontmap), fcfont);
+ gravity = pango_fc_font_key_get_gravity (key);
+
+ context.x_scale = 1. / x_scale_inv;
+ context.y_scale = 1. / y_scale_inv;
+ context.ft_face = ft_face;
+ context.fc_font = fc_font;
+ context.vertical = PANGO_GRAVITY_IS_VERTICAL (gravity);
+
+ hb_face = pango_fc_font_map_get_hb_face (PANGO_FC_FONT_MAP (fc_font->fontmap), fc_font);
+ ft_face = pango_fc_font_map_get_ft_face (PANGO_FC_FONT_MAP (fc_font->fontmap), fc_font);
+ hb_font = hb_font_create (hb_face);
+ hb_font_set_funcs (hb_font,
+ pango_fc_get_hb_font_funcs (),
+ &context,
+ NULL);
+ hb_font_set_scale (hb_font,
+ +(((gint64) ft_face->size->metrics.x_scale * ft_face->units_per_EM) >> 12) *
context.x_scale,
+ -(((gint64) ft_face->size->metrics.y_scale * ft_face->units_per_EM) >> 12) *
context.y_scale);
+ 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);
+ if (key)
+ {
+ const char *variations = pango_fc_font_key_get_variations (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);
+ }
+ }
- return hb_font_create (hb_face);
+ return hb_font;
}
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 52adcc16..4bb5eb1f 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -264,7 +264,9 @@ static FcPattern *pango_fc_patterns_get_font_pattern (PangoFcPatterns *pat
static FcPattern *uniquify_pattern (PangoFcFontMap *fcfontmap,
FcPattern *pattern);
-static gpointer
+gpointer get_gravity_class (void);
+
+gpointer
get_gravity_class (void)
{
static GEnumClass *class = NULL; /* MT-safe */
@@ -301,6 +303,7 @@ pango_fc_font_face_data_free (PangoFcFontFaceData *data)
_pango_fc_cmap_cache_unref (data->cmap_cache);
hb_face_destroy (data->hb_face);
+ FT_Done_Face (data->ft_face);
g_slice_free (PangoFcFontFaceData, data);
}
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index 53269d73..656d8f7b 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -68,249 +68,6 @@ release_buffer (hb_buffer_t *buffer, gboolean free_buffer)
hb_buffer_destroy (buffer);
}
-typedef struct _PangoFcHbContext {
- FT_Face ft_face;
- PangoFcFont *fc_font;
- gboolean vertical;
- double x_scale, y_scale; /* CTM scales. */
-} PangoFcHbContext;
-
-static hb_bool_t
-pango_fc_hb_font_get_nominal_glyph (hb_font_t *font, void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- PangoFcFont *fc_font = context->fc_font;
-
- *glyph = pango_fc_font_get_glyph (fc_font, unicode);
- if (G_LIKELY (*glyph))
- return TRUE;
-
- *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
-
- /* We draw our own invalid-Unicode shape, so prevent HarfBuzz
- * from using REPLACEMENT CHARACTER. */
- if (unicode > 0x10FFFF)
- return TRUE;
-
- return FALSE;
-}
-
-static hb_bool_t
-pango_fc_hb_font_get_variation_glyph (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- FT_Face ft_face = context->ft_face;
- unsigned int g;
-
- g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
-
- if (G_UNLIKELY (!g))
- return FALSE;
-
- *glyph = g;
- return TRUE;
-}
-
-static hb_bool_t
-pango_fc_hb_font_get_glyph_contour_point (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph, unsigned int point_index,
- hb_position_t *x, hb_position_t *y,
- void *user_data G_GNUC_UNUSED)
-{
- return FALSE;
-#if 0
- FT_Face ft_face = (FT_Face) font_data;
- int load_flags = FT_LOAD_DEFAULT;
-
- /* TODO: load_flags, embolden, etc */
-
- if (HB_UNLIKELY (FT_Load_Glyph (ft_face, glyph, load_flags)))
- return FALSE;
-
- if (HB_UNLIKELY (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
- return FALSE;
-
- if (HB_UNLIKELY (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
- return FALSE;
-
- *x = ft_face->glyph->outline.points[point_index].x;
- *y = ft_face->glyph->outline.points[point_index].y;
-
- return TRUE;
-#endif
-}
-
-static hb_position_t
-pango_fc_hb_font_get_glyph_advance (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- PangoFcFont *fc_font = context->fc_font;
- PangoRectangle logical;
-
- pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, NULL, &logical);
-
- return logical.width;
-}
-
-static hb_bool_t
-pango_fc_hb_font_get_glyph_extents (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- PangoFcFont *fc_font = context->fc_font;
- PangoRectangle ink;
-
- pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, &ink, NULL);
-
- if (G_LIKELY (!context->vertical)) {
- extents->x_bearing = ink.x;
- extents->y_bearing = ink.y;
- extents->width = ink.width;
- extents->height = ink.height;
- } else {
- /* XXX */
- extents->x_bearing = ink.x;
- extents->y_bearing = ink.y;
- extents->width = ink.height;
- extents->height = ink.width;
- }
-
- return TRUE;
-}
-
-static hb_bool_t
-pango_fc_hb_font_get_glyph_h_origin (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- FT_Face ft_face = context->ft_face;
- int load_flags = FT_LOAD_DEFAULT;
-
- if (!context->vertical) return TRUE;
-
- if (FT_Load_Glyph (ft_face, glyph, load_flags))
- return FALSE;
-
- /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
- * have a Y growing upward. Hence the extra negations. */
- *x = -PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX);
- *y = +PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY));
-
- return TRUE;
-}
-
-static hb_bool_t
-pango_fc_hb_font_get_glyph_v_origin (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- FT_Face ft_face = context->ft_face;
- int load_flags = FT_LOAD_DEFAULT;
-
- /* pangocairo-fc configures font in vertical origin for vertical writing. */
- if (context->vertical) return TRUE;
-
- if (FT_Load_Glyph (ft_face, glyph, load_flags))
- return FALSE;
-
- /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
- * have a Y growing upward. Hence the extra negation. */
- *x = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX);
- *y = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY));
-
- /* XXX */
-
- return TRUE;
-}
-
-
-static hb_position_t
-pango_fc_hb_font_get_h_kerning (hb_font_t *font, void *font_data,
- hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
- void *user_data G_GNUC_UNUSED)
-{
- PangoFcHbContext *context = (PangoFcHbContext *) font_data;
- FT_Face ft_face = context->ft_face;
- FT_Vector kerning;
-
- if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
- return 0;
-
- return PANGO_UNITS_26_6 (kerning.x * context->x_scale);
-}
-
-static hb_font_funcs_t *
-pango_fc_get_hb_font_funcs (void)
-{
- static hb_font_funcs_t *funcs;
-
- if (G_UNLIKELY (!funcs)) {
- funcs = hb_font_funcs_create ();
- hb_font_funcs_set_nominal_glyph_func (funcs, pango_fc_hb_font_get_nominal_glyph, NULL, NULL);
- hb_font_funcs_set_variation_glyph_func (funcs, pango_fc_hb_font_get_variation_glyph, NULL, NULL);
- hb_font_funcs_set_glyph_h_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL);
- hb_font_funcs_set_glyph_v_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL);
- hb_font_funcs_set_glyph_h_origin_func (funcs, pango_fc_hb_font_get_glyph_h_origin, NULL, NULL);
- hb_font_funcs_set_glyph_v_origin_func (funcs, pango_fc_hb_font_get_glyph_v_origin, NULL, NULL);
- hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_fc_hb_font_get_h_kerning, NULL, NULL);
- /* Don't need v_kerning. */
- hb_font_funcs_set_glyph_extents_func (funcs, pango_fc_hb_font_get_glyph_extents, NULL, NULL);
- hb_font_funcs_set_glyph_contour_point_func (funcs, pango_fc_hb_font_get_glyph_contour_point, NULL, NULL);
- /* Don't need glyph_name / glyph_from_name */
- }
-
- 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,
const char *item_text,
@@ -320,11 +77,7 @@ _pango_fc_shape (PangoFont *font,
const char *paragraph_text,
unsigned int paragraph_length)
{
- PangoFcHbContext context;
PangoFcFont *fc_font;
- PangoFcFontKey *key;
- FT_Face ft_face;
- hb_face_t *hb_face;
hb_font_t *hb_font;
hb_buffer_t *hb_buffer;
hb_direction_t hb_direction;
@@ -336,64 +89,12 @@ _pango_fc_shape (PangoFont *font,
unsigned int item_offset = item_text - paragraph_text;
hb_feature_t features[32];
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);
- fc_font = PANGO_FC_FONT (font);
- ft_face = pango_fc_font_lock_face (fc_font);
- if (!ft_face)
- return;
-
- /* TODO: Cache hb_font? */
-
- x_scale_inv = y_scale_inv = 1.0;
- key = _pango_fc_font_get_font_key (fc_font);
- if (key)
- {
- const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key);
- pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv);
- }
- if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity))
- {
- x_scale_inv = -x_scale_inv;
- y_scale_inv = -y_scale_inv;
- }
- context.x_scale = 1. / x_scale_inv;
- context.y_scale = 1. / y_scale_inv;
- context.ft_face = ft_face;
- context.fc_font = fc_font;
- context.vertical = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity);
- hb_face = hb_ft_face_create_cached (ft_face);
- hb_font = hb_font_create (hb_face);
- hb_font_set_funcs (hb_font,
- pango_fc_get_hb_font_funcs (),
- &context,
- NULL);
- hb_font_set_scale (hb_font,
- +(((gint64) ft_face->size->metrics.x_scale * ft_face->units_per_EM) >> 12) *
context.x_scale,
- -(((gint64) ft_face->size->metrics.y_scale * ft_face->units_per_EM) >> 12) *
context.y_scale);
- 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);
-
- if (key)
- {
- variations = pango_fc_font_key_get_variations (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_font = pango_font_get_hb_font (font);
hb_buffer = acquire_buffer (&free_buffer);
@@ -416,6 +117,7 @@ _pango_fc_shape (PangoFont *font,
hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length);
/* Setup features from fontconfig pattern. */
+ fc_font = PANGO_FC_FONT (font);
if (fc_font->font_pattern)
{
char *s;
@@ -489,7 +191,7 @@ _pango_fc_shape (PangoFont *font,
}
hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL);
- if (context.vertical)
+ if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
for (i = 0; i < num_glyphs; i++)
{
/* 90 degrees rotation counter-clockwise. */
@@ -509,7 +211,26 @@ _pango_fc_shape (PangoFont *font,
if (fc_font->is_hinted)
{
- if (context.x_scale == 1.0 && context.y_scale == 1.0)
+ double x_scale_inv, y_scale_inv;
+ double x_scale, y_scale;
+ PangoFcFontKey *key;
+
+ x_scale_inv = y_scale_inv = 1.0;
+ key = _pango_fc_font_get_font_key (fc_font);
+ if (key)
+ {
+ const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key);
+ pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv);
+ }
+ if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity))
+ {
+ x_scale_inv = -x_scale_inv;
+ y_scale_inv = -y_scale_inv;
+ }
+ x_scale = 1. / x_scale_inv;
+ y_scale = 1. / y_scale_inv;
+
+ if (x_scale == 1.0 && y_scale == 1.0)
{
for (i = 0; i < num_glyphs; i++)
infos[i].geometry.width = PANGO_UNITS_ROUND (infos[i].geometry.width);
@@ -517,7 +238,7 @@ _pango_fc_shape (PangoFont *font,
else
{
#if 0
- if (context.vertical)
+ if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
{
/* XXX */
double tmp = x_scale;
@@ -526,8 +247,8 @@ _pango_fc_shape (PangoFont *font,
}
#endif
#define HINT(value, scale_inv, scale) (PANGO_UNITS_ROUND ((int) ((value) * scale)) * scale_inv)
-#define HINT_X(value) HINT ((value), context.x_scale, x_scale_inv)
-#define HINT_Y(value) HINT ((value), context.y_scale, y_scale_inv)
+#define HINT_X(value) HINT ((value), x_scale, x_scale_inv)
+#define HINT_Y(value) HINT ((value), y_scale, y_scale_inv)
for (i = 0; i < num_glyphs; i++)
{
infos[i].geometry.width = HINT_X (infos[i].geometry.width);
@@ -542,6 +263,4 @@ _pango_fc_shape (PangoFont *font,
release_buffer (hb_buffer, free_buffer);
hb_font_destroy (hb_font);
- hb_face_destroy (hb_face);
- pango_fc_font_unlock_face (fc_font);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]