diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-10-31 01:50:21 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-10-31 01:50:21 +0000 |
commit | 7c710faa1edd58109c4ac1972ae5aca10f1be87f (patch) | |
tree | 4abd52c5ccda75dea45d82965b5d244dfd868ab7 /pango/pangocairo-font.c | |
parent | f33cbe522dbb5ccfff9e70ef108061813ed61cb8 (diff) | |
parent | ab776f328ba3540f6607ea0a9bc72a57b607b9ac (diff) | |
download | pango-7c710faa1edd58109c4ac1972ae5aca10f1be87f.tar.gz |
Merge branch 'glyph-extents-fixes' into 'main'
cairo: Produce meaningful logical glyph extents
See merge request GNOME/pango!490
Diffstat (limited to 'pango/pangocairo-font.c')
-rw-r--r-- | pango/pangocairo-font.c | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 69c375c3..503f863b 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -693,7 +693,7 @@ get_space_extents (PangoCairoFontPrivate *cf_priv, cairo_text_extents_t extents; c[0] = hexdigits[i]; - cairo_scaled_font_text_extents (cf_priv->scaled_font, c, &extents); + cairo_scaled_font_text_extents (_pango_cairo_font_private_get_scaled_font (cf_priv), c, &extents); hex_width += extents.width; } width = pango_units_from_double (hex_width / 16); @@ -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); - break; + cf_priv->font_extents.y = - extents.ascender; + break; case PANGO_GRAVITY_NORTH: - cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent); - break; + 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; - if (cf_priv->is_hinted) - ascent = PANGO_UNITS_ROUND (ascent); - cf_priv->font_extents.y = - ascent; - } + { + 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); @@ -904,6 +927,23 @@ _pango_cairo_font_private_get_glyph_extents (PangoCairoFontPrivate *cf_priv, if (logical_rect) { *logical_rect = cf_priv->font_extents; - logical_rect->width = entry->width; + switch (cf_priv->gravity) + { + case PANGO_GRAVITY_SOUTH: + logical_rect->width = entry->width; + break; + case PANGO_GRAVITY_EAST: + logical_rect->width = cf_priv->font_extents.height; + break; + case PANGO_GRAVITY_NORTH: + logical_rect->width = entry->width; + break; + case PANGO_GRAVITY_WEST: + logical_rect->width = - cf_priv->font_extents.height; + break; + case PANGO_GRAVITY_AUTO: + default: + g_assert_not_reached (); + } } } |