[pango/glyph-extents-fixes: 4/5] Use harfbuzz metrics for cairo fonts




commit 047bfaf6012207df2803f51617a165beced7612f
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Oct 19 15:12:56 2021 -0400

    Use harfbuzz metrics for cairo fonts
    
    Without this, we end up with differences in
    metrics of empty runs.

 pango/pangocairo-font.c | 51 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 14 deletions(-)
---
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index 35380571..dacc61ab 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -784,40 +784,60 @@ struct _PangoCairoFontGlyphExtentsCacheEntry
 static gboolean
 _pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_priv)
 {
-  cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv);
-  cairo_font_extents_t font_extents;
-
-  if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
-    return FALSE;
+  hb_font_extents_t extents;
 
-  cairo_scaled_font_extents (scaled_font, &font_extents);
+  hb_font_get_h_extents (pango_font_get_hb_font (PANGO_FONT (cf_priv->cfont)),
+                         &extents);
 
   cf_priv->font_extents.x = 0;
   cf_priv->font_extents.width = 0;
-  cf_priv->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent);
+  cf_priv->font_extents.height = extents.ascender - extents.descender;
+
   switch (cf_priv->gravity)
     {
       default:
       case PANGO_GRAVITY_AUTO:
       case PANGO_GRAVITY_SOUTH:
-        cf_priv->font_extents.y = - pango_units_from_double (font_extents.ascent);
+        cf_priv->font_extents.y = - extents.ascender;
         break;
       case PANGO_GRAVITY_NORTH:
-        cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent);
+        cf_priv->font_extents.y = extents.descender;
         break;
       case PANGO_GRAVITY_EAST:
       case PANGO_GRAVITY_WEST:
         {
-          int ascent = pango_units_from_double (font_extents.ascent + font_extents.descent) / 2;
+          int ascent = cf_priv->font_extents.height / 2;
           if (cf_priv->is_hinted)
             ascent = PANGO_UNITS_ROUND (ascent);
           cf_priv->font_extents.y = - ascent;
         }
+       break;
     }
 
-  cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
-  /* Make sure all cache entries are invalid initially */
-  cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */
+  if (cf_priv->is_hinted)
+    {
+      if (cf_priv->font_extents.y < 0)
+        cf_priv->font_extents.y = PANGO_UNITS_ROUND (cf_priv->font_extents.y - PANGO_SCALE/2);
+      else
+        cf_priv->font_extents.y = PANGO_UNITS_ROUND (cf_priv->font_extents.y + PANGO_SCALE/2);
+      if (cf_priv->font_extents.height < 0)
+        cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height - PANGO_SCALE/2);
+      else
+        cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height + PANGO_SCALE/2);
+    }
+
+  if (PANGO_GRAVITY_IS_IMPROPER (cf_priv->gravity))
+    {
+      cf_priv->font_extents.y = - cf_priv->font_extents.y;
+      cf_priv->font_extents.height = - cf_priv->font_extents.height;
+    }
+
+  if (!cf_priv->glyph_extents_cache)
+    {
+      cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
+      /* Make sure all cache entries are invalid initially */
+      cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */
+    }
 
   return TRUE;
 }
@@ -841,7 +861,10 @@ compute_glyph_extents (PangoCairoFontPrivate  *cf_priv,
                                   &cairo_glyph, 1, &extents);
 
   entry->glyph = glyph;
-  entry->width = pango_units_from_double (extents.x_advance);
+  if (PANGO_GRAVITY_IS_VERTICAL (cf_priv->gravity))
+    entry->width = pango_units_from_double (extents.y_advance);
+  else
+    entry->width = pango_units_from_double (extents.x_advance);
   entry->ink_rect.x = pango_units_from_double (extents.x_bearing);
   entry->ink_rect.y = pango_units_from_double (extents.y_bearing);
   entry->ink_rect.width = pango_units_from_double (extents.width);


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