[pango/visible-things-2: 5/16] Pass shape flags on to font funcs



commit 752c1b657757e3262a60f7ea6b3530cd00b52cfb
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 7 14:00:36 2019 -0400

    Pass shape flags on to font funcs
    
    This is needed to let shape flags influence
    glyph selection.

 pango/pangofc-shape.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 158 insertions(+), 2 deletions(-)
---
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index e9826ed3..7ba15ef9 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -70,6 +70,161 @@ release_buffer (hb_buffer_t *buffer, gboolean free_buffer)
     hb_buffer_destroy (buffer);
 }
 
+typedef struct
+{
+  PangoFont *font;
+  hb_font_t *parent;
+  PangoShapeFlags flags;
+} PangoHbShapeContext;
+
+static hb_bool_t
+pango_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  if (hb_font_get_glyph (context->parent, unicode, 0, 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_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  if (hb_font_get_glyph (context->parent,
+                         unicode, variation_selector, glyph))
+    return TRUE;
+
+  return FALSE;
+}
+
+static hb_bool_t
+pango_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;
+}
+
+static hb_position_t
+pango_hb_font_get_glyph_advance (hb_font_t      *font,
+                                 void           *font_data,
+                                 hb_codepoint_t  glyph,
+                                 void           *user_data G_GNUC_UNUSED)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  return hb_font_get_glyph_h_advance (context->parent, glyph);
+}
+
+static hb_bool_t
+pango_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  return hb_font_get_glyph_extents (context->parent, glyph, extents);
+}
+
+static hb_bool_t
+pango_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  return hb_font_get_glyph_h_origin (context->parent, glyph, x, y);
+}
+
+static hb_bool_t
+pango_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  return hb_font_get_glyph_v_origin (context->parent, glyph, x, y);
+}
+
+static hb_position_t
+pango_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)
+{
+  PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
+
+  return hb_font_get_glyph_h_kerning (context->parent, left_glyph, right_glyph);
+}
+
+static hb_font_t *
+pango_font_get_hb_font_for_flags (PangoFont           *font,
+                                  PangoShapeFlags      flags,
+                                  PangoHbShapeContext *context)
+{
+  hb_font_t *hb_font;
+  static hb_font_funcs_t *funcs;
+
+  hb_font = pango_font_get_hb_font (font);
+  if (flags == PANGO_SHAPE_NONE)
+    return hb_font_reference (hb_font);
+
+  if (G_UNLIKELY (!funcs))
+    {
+      funcs = hb_font_funcs_create ();
+      hb_font_funcs_set_nominal_glyph_func (funcs, pango_hb_font_get_nominal_glyph, NULL, NULL);
+      hb_font_funcs_set_variation_glyph_func (funcs, pango_hb_font_get_variation_glyph, NULL, NULL);
+      hb_font_funcs_set_glyph_h_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL);
+      hb_font_funcs_set_glyph_v_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL);
+      hb_font_funcs_set_glyph_h_origin_func (funcs, pango_hb_font_get_glyph_h_origin, NULL, NULL);
+      hb_font_funcs_set_glyph_v_origin_func (funcs, pango_hb_font_get_glyph_v_origin, NULL, NULL);
+      hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_hb_font_get_h_kerning, NULL, NULL);
+      hb_font_funcs_set_glyph_extents_func (funcs, pango_hb_font_get_glyph_extents, NULL, NULL);
+      hb_font_funcs_set_glyph_contour_point_func (funcs, pango_hb_font_get_glyph_contour_point, NULL, NULL);
+  }
+
+  context->font = font;
+  context->parent = hb_font;
+  context->flags = flags;
+
+  hb_font = hb_font_create_sub_font (hb_font);
+  hb_font_set_funcs (hb_font, funcs, context, NULL);
+
+  return hb_font;
+}
+
 void
 _pango_fc_shape (PangoFont           *font,
                 const char          *item_text,
@@ -80,6 +235,7 @@ _pango_fc_shape (PangoFont           *font,
                  PangoShapeFlags      flags,
                 PangoGlyphString    *glyphs)
 {
+  PangoHbShapeContext context;
   hb_font_t *hb_font;
   hb_buffer_t *hb_buffer;
   hb_direction_t hb_direction;
@@ -96,8 +252,7 @@ _pango_fc_shape (PangoFont           *font,
   g_return_if_fail (font != NULL);
   g_return_if_fail (analysis != NULL);
 
-  hb_font = pango_font_get_hb_font (font);
-
+  hb_font = pango_font_get_hb_font_for_flags (font, flags, &context);
   hb_buffer = acquire_buffer (&free_buffer);
 
   hb_direction = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity) ? HB_DIRECTION_TTB : HB_DIRECTION_LTR;
@@ -250,4 +405,5 @@ _pango_fc_shape (PangoFont           *font,
     }
 
   release_buffer (hb_buffer, free_buffer);
+  hb_font_destroy (hb_font);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]