[pango/pango2: 170/178] Fix gravities for user fonts




commit ceb53e4cb96329e3e77e499df3162b22ec95bd9c
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jun 21 20:37:42 2022 -0700

    Fix gravities for user fonts
    
    This is enormous fiddling, and should be much simpler.

 pango/pango-hbfont.c    |  4 ++--
 pango/pango-userface.c  | 35 +++++++++++++++++++++++++++----
 pango/pango-userfont.c  | 34 +++++++++++++++++++++++-------
 pango/pangocairo-font.c | 55 ++++++++++++++++++++++++++++++++++---------------
 utils/userfont.c        |  8 +++----
 5 files changed, 101 insertions(+), 35 deletions(-)
---
diff --git a/pango/pango-hbfont.c b/pango/pango-hbfont.c
index d9fe88ccd..fd523a98c 100644
--- a/pango/pango-hbfont.c
+++ b/pango/pango-hbfont.c
@@ -681,9 +681,9 @@ pango_hb_font_get_glyph_extents (PangoFont      *font,
           m.yx = - face->transform->yx;
           m.xy = - face->transform->xy;
           m.yy = face->transform->yy;
-        }
 
-      pango_matrix_transform_rectangle (&m, &r);
+          pango_matrix_transform_rectangle (&m, &r);
+        }
 
       switch (font->gravity)
         {
diff --git a/pango/pango-userface.c b/pango/pango-userface.c
index 0a76cfdff..597674b69 100644
--- a/pango/pango-userface.c
+++ b/pango/pango-userface.c
@@ -120,6 +120,8 @@ default_shape_func (PangoUserFace       *face,
   gboolean is_color;
   hb_glyph_extents_t ext;
   hb_position_t dummy;
+  hb_font_t *hb_font;
+  hb_font_extents_t font_extents;
 
   n_chars = g_utf8_strlen (text, length);
 
@@ -127,11 +129,15 @@ default_shape_func (PangoUserFace       *face,
 
   last_cluster = -1;
 
+  hb_font = pango_font_get_hb_font (analysis->font);
+  hb_font_get_h_extents (hb_font, &font_extents);
+
   p = text;
   for (i = 0; i < n_chars; i++)
     {
       gunichar wc;
       PangoGlyph glyph;
+      PangoRectangle ink_rect;
       PangoRectangle logical_rect;
 
       wc = g_utf8_get_char (p);
@@ -145,16 +151,37 @@ default_shape_func (PangoUserFace       *face,
         glyph = PANGO_GET_UNKNOWN_GLYPH (wc);
 
       face->glyph_info_func (face, size, glyph, &ext, &dummy, &dummy, &is_color, face->user_data);
-      pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect);
+      pango_font_get_glyph_extents (analysis->font, glyph, &ink_rect, &logical_rect);
 
       glyphs->glyphs[i].glyph = glyph;
 
       glyphs->glyphs[i].attr.is_cluster_start = cluster != last_cluster;
       glyphs->glyphs[i].attr.is_color = is_color;
 
-      glyphs->glyphs[i].geometry.x_offset = 0;
-      glyphs->glyphs[i].geometry.y_offset = 0;
-      glyphs->glyphs[i].geometry.width = logical_rect.width;
+      if (analysis->gravity == PANGO_GRAVITY_EAST)
+        {
+          glyphs->glyphs[i].geometry.x_offset = font_extents.ascender;
+          glyphs->glyphs[i].geometry.y_offset = - logical_rect.y - (logical_rect.height - ink_rect.height) / 
2;
+          glyphs->glyphs[i].geometry.width = logical_rect.width;
+        }
+      else if (analysis->gravity == PANGO_GRAVITY_WEST)
+        {
+          glyphs->glyphs[i].geometry.x_offset = font_extents.descender;
+          glyphs->glyphs[i].geometry.y_offset = logical_rect.y + (logical_rect.height - ink_rect.height) / 2;
+          glyphs->glyphs[i].geometry.width = logical_rect.width;
+        }
+      else if (analysis->gravity == PANGO_GRAVITY_SOUTH)
+        {
+          glyphs->glyphs[i].geometry.x_offset = 0;
+          glyphs->glyphs[i].geometry.y_offset = 0;
+          glyphs->glyphs[i].geometry.width = logical_rect.width;
+        }
+      else if (analysis->gravity == PANGO_GRAVITY_NORTH)
+        {
+          glyphs->glyphs[i].geometry.x_offset = 0;
+          glyphs->glyphs[i].geometry.y_offset = 0;
+          glyphs->glyphs[i].geometry.width = - logical_rect.width;
+        }
 
       glyphs->log_clusters[i] = cluster;
       last_cluster = cluster;
diff --git a/pango/pango-userfont.c b/pango/pango-userfont.c
index 5bbd80984..d88babeed 100644
--- a/pango/pango-userfont.c
+++ b/pango/pango-userfont.c
@@ -160,8 +160,6 @@ pango_user_font_get_glyph_extents (PangoFont      *font,
       hb_font_get_h_extents (hb_font, &extents);
 
       logical_rect->x = 0;
-      logical_rect->y = - extents.ascender;
-      logical_rect->width = h_advance;
       logical_rect->height = extents.ascender - extents.descender;
 
       switch (font->gravity)
@@ -266,11 +264,21 @@ glyph_extents_func (hb_font_t *hb_font, void *font_data,
   hb_position_t h_advance, v_advance;
   gboolean is_color;
 
-  return face->glyph_info_func (face, size, glyph,
-                                extents,
-                                &h_advance, &v_advance,
-                                &is_color,
-                                face->user_data);
+  face->glyph_info_func (face, size, glyph,
+                         extents,
+                         &h_advance, &v_advance,
+                         &is_color,
+                         face->user_data);
+
+  if (PANGO_GRAVITY_IS_IMPROPER (font->gravity))
+    {
+      extents->x_bearing = - extents->x_bearing;
+      extents->y_bearing = - extents->y_bearing;
+      extents->width = - extents->width;
+      extents->height = - extents->height;
+    }
+
+  return TRUE;
 }
 
 static hb_bool_t
@@ -281,8 +289,17 @@ font_extents_func (hb_font_t *hb_font, void *font_data,
   PangoFont *font = font_data;
   PangoUserFace *face = PANGO_USER_FACE (font->face);
   int size = font->size * font->dpi / 72.;
+  gboolean ret;
+
+  ret = face->font_info_func (face, size, extents, face->user_data);
+
+  if (PANGO_GRAVITY_IS_IMPROPER (font->gravity))
+    {
+      extents->ascender = - extents->ascender;
+      extents->descender = - extents->descender;
+    }
 
-  return face->font_info_func (face, size, extents, face->user_data);
+  return ret;
 }
 
 static hb_font_t *
@@ -305,6 +322,7 @@ pango_user_font_create_hb_font (PangoFont *font)
   hb_font_funcs_set_glyph_h_advance_func (funcs, glyph_h_advance_func, NULL, NULL);
   hb_font_funcs_set_glyph_extents_func (funcs, glyph_extents_func, NULL, NULL);
   hb_font_funcs_set_font_h_extents_func (funcs, font_extents_func, NULL, NULL);
+  hb_font_funcs_set_font_v_extents_func (funcs, font_extents_func, NULL, NULL);
 
   hb_font_set_funcs (hb_font, funcs, font, NULL);
 
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index 432d0166e..d23d006a8 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -49,12 +49,6 @@
 
 #endif
 
-#define PANGO_CAIRO_FONT_PRIVATE(font)          \
-  ((PangoCairoFontPrivate *)                    \
-   (font == NULL ? NULL :                       \
-    G_STRUCT_MEMBER_P (font,                    \
-    PANGO_CAIRO_FONT_GET_IFACE(PANGO_CAIRO_FONT(font))->cf_priv_offset)))
-
 static PangoCairoFontPrivate * _pango_font_get_cairo_font_private (PangoFont *font);
 static cairo_scaled_font_t * _pango_font_get_scaled_font (PangoFont *font);
 static void _pango_cairo_font_private_initialize (PangoCairoFontPrivate      *cf_priv,
@@ -120,12 +114,12 @@ render_func (cairo_scaled_font_t  *scaled_font,
       return CAIRO_STATUS_USER_FONT_ERROR;
     }
 
-  extents->x_bearing = glyph_extents.x_bearing / (double) 1024;
-  extents->y_bearing = glyph_extents.y_bearing / (double) 1024;
-  extents->width = glyph_extents.width / (double) 1024;
-  extents->height = glyph_extents.height / (double) 1024;
-  extents->x_advance = h_advance / (double) 1024;
-  extents->y_advance = v_advance / (double) 1024;
+  extents->x_bearing = glyph_extents.x_bearing / 1024.;
+  extents->y_bearing = - glyph_extents.y_bearing / 1024.;
+  extents->width = glyph_extents.width / 1024.;
+  extents->height = - glyph_extents.height / 1024.;
+  extents->x_advance = h_advance / 1024.;
+  extents->y_advance = v_advance / 1024.;
 
   if (!face->render_func (face, font->size,
                           (hb_codepoint_t)glyph,
@@ -139,6 +133,31 @@ render_func (cairo_scaled_font_t  *scaled_font,
   return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_status_t
+init_func (cairo_scaled_font_t  *scaled_font,
+           cairo_t              *cr,
+           cairo_font_extents_t *extents)
+{
+  cairo_font_face_t *cairo_face;
+  PangoFont *font;
+  PangoUserFace *face;
+  hb_font_extents_t font_extents;
+
+  cairo_face = cairo_scaled_font_get_font_face (scaled_font);
+  font = cairo_font_face_get_user_data (cairo_face, &cairo_user_data);
+  face = (PangoUserFace *) pango_font_get_face (font);
+
+  face->font_info_func (face,
+                        pango_font_get_size (font),
+                        &font_extents,
+                        face->user_data);
+
+  extents->ascent = font_extents.ascender / (font_extents.ascender + font_extents.descender);
+  extents->descent = font_extents.descender / (font_extents.ascender + font_extents.descender);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
 static cairo_font_face_t *
 create_cairo_font_face_for_user_font (PangoFont *font)
 {
@@ -146,6 +165,7 @@ create_cairo_font_face_for_user_font (PangoFont *font)
 
   cairo_face = cairo_user_font_face_create ();
   cairo_font_face_set_user_data (cairo_face, &cairo_user_data, font, NULL);
+  cairo_user_font_face_set_init_func (cairo_face, init_func);
   cairo_user_font_face_set_render_color_glyph_func (cairo_face, render_func);
 
   return cairo_face;
@@ -602,7 +622,7 @@ _pango_font_get_cairo_font_private (PangoFont *font)
 {
   PangoCairoFontPrivate *cf_priv;
 
-  cf_priv = g_object_get_data (G_OBJECT (font), "pango-hb-font-cairo_private");
+  cf_priv = g_object_get_data (G_OBJECT (font), "pango-font-cairo_private");
   if (!cf_priv)
     {
       cairo_font_options_t *font_options;
@@ -654,7 +674,7 @@ _pango_font_get_cairo_font_private (PangoFont *font)
 
       cairo_font_options_destroy (font_options);
 
-      g_object_set_data_full (G_OBJECT (font), "pango-hb-font-cairo_private",
+      g_object_set_data_full (G_OBJECT (font), "pango-font-cairo_private",
                               cf_priv, free_cairo_font_private);
     }
 
@@ -687,9 +707,10 @@ _pango_cairo_font_private_initialize (PangoCairoFontPrivate      *cf_priv,
   /* first apply gravity rotation, then font_matrix, such that
    * vertical italic text comes out "correct".  we don't do anything
    * like baseline adjustment etc though.  should be specially
-   * handled when we support italic correction. */
-  cairo_matrix_init_rotate(&gravity_matrix,
-                           pango_gravity_to_rotation (cf_priv->gravity));
+   * handled when we support italic correction.
+   */
+  cairo_matrix_init_rotate (&gravity_matrix,
+                            pango_gravity_to_rotation (cf_priv->gravity));
   cairo_matrix_multiply (&cf_priv->data->font_matrix,
                          font_matrix,
                          &gravity_matrix);
diff --git a/utils/userfont.c b/utils/userfont.c
index f5fbf7954..a3491e0e3 100644
--- a/utils/userfont.c
+++ b/utils/userfont.c
@@ -91,9 +91,9 @@ glyph_info_cb (PangoUserFace      *face,
   test_scaled_font_glyph_t *glyphs = user_data;
 
   extents->x_bearing = 0;
-  extents->y_bearing = - 0.75 * size;
+  extents->y_bearing = 0.75 * size;
   extents->width = glyphs[glyph].width / 4.0 * size;
-  extents->height = size;
+  extents->height = - size;
 
   *h_advance = *v_advance = glyphs[glyph].width / 4.0 * size;
 
@@ -108,8 +108,8 @@ font_info_cb (PangoUserFace     *face,
               hb_font_extents_t *extents,
               gpointer           user_data)
 {
-  extents->ascender = - 0.75 * size;
-  extents->descender = 0.25 * size;
+  extents->ascender = 0.75 * size;
+  extents->descender = - 0.25 * size;
   extents->line_gap = 0;
 
   return TRUE;


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