From 1c7c84a263af1e0688e2fedb3a98e2f10b55f0eb Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Mon, 22 Nov 2021 01:41:33 +0100 Subject: Introduce and use FLOOR and CEIL macros in Pango units This replaces the code that was trying to implement those via the ROUND macro. This avoids a potential issue with values that already were on whole units being rounded up to the next whole unit in the code that was implementing CEIL this way. --- pango/pango-types.h | 26 ++++++++++++++++++++++++++ pango/pangocairo-font.c | 8 ++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/pango/pango-types.h b/pango/pango-types.h index f18225ba..ed86f699 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -106,6 +106,32 @@ typedef guint32 PangoGlyph; * PANGO_PIXELS also behaves differently for +512 and -512. */ +/** + * PANGO_UNITS_FLOOR: + * @d: a dimension in Pango units. + * + * Rounds a dimension down to whole device units, but does not + * convert it to device units. + * + * Return value: rounded down dimension in Pango units. + * Since: 1.50 + */ +#define PANGO_UNITS_FLOOR(d) \ + ((d) & ~(PANGO_SCALE - 1)) + +/** + * PANGO_UNITS_CEIL: + * @d: a dimension in Pango units. + * + * Rounds a dimension up to whole device units, but does not + * convert it to device units. + * + * Return value: rounded up dimension in Pango units. + * Since: 1.50 + */ +#define PANGO_UNITS_CEIL(d) \ + (((d) + (PANGO_SCALE - 1)) & ~(PANGO_SCALE - 1)) + /** * PANGO_UNITS_ROUND: * @d: a dimension in Pango units. diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 597a320d..fb36d294 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -817,13 +817,13 @@ _pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_pr 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); + cf_priv->font_extents.y = PANGO_UNITS_FLOOR (cf_priv->font_extents.y); else - cf_priv->font_extents.y = PANGO_UNITS_ROUND (cf_priv->font_extents.y + PANGO_SCALE/2); + cf_priv->font_extents.y = PANGO_UNITS_CEIL (cf_priv->font_extents.y); if (cf_priv->font_extents.height < 0) - cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height - PANGO_SCALE/2); + cf_priv->font_extents.height = PANGO_UNITS_FLOOR (cf_priv->font_extents.height); else - cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height + PANGO_SCALE/2); + cf_priv->font_extents.height = PANGO_UNITS_CEIL (cf_priv->font_extents.height); } if (PANGO_GRAVITY_IS_IMPROPER (cf_priv->gravity)) -- cgit v1.2.1 From 303f79e14047d60c3ca41c24931c8cb6115433ae Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Mon, 22 Nov 2021 01:54:15 +0100 Subject: Calculate hinted font height based on the hinted extents The previous code was calculating the rounded up version of the difference between the unhinted ascender and uninted descender. This however would only result in the correct height if both unhinted extentss together only differ by less then an a Pango unit from their hinted counterparts. Otherwise the resulting height would be 1 unit too short. Fix this by using the difference between the hinted extents as height. Fixes: https://gitlab.gnome.org/GNOME/pango/-/issues/626 --- pango/pangocairo-font.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index fb36d294..c2bcc51b 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -821,9 +821,9 @@ _pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_pr else cf_priv->font_extents.y = PANGO_UNITS_CEIL (cf_priv->font_extents.y); if (cf_priv->font_extents.height < 0) - cf_priv->font_extents.height = PANGO_UNITS_FLOOR (cf_priv->font_extents.height); + cf_priv->font_extents.height = PANGO_UNITS_FLOOR (extents.ascender) - PANGO_UNITS_CEIL (extents.descender); else - cf_priv->font_extents.height = PANGO_UNITS_CEIL (cf_priv->font_extents.height); + cf_priv->font_extents.height = PANGO_UNITS_CEIL (extents.ascender) - PANGO_UNITS_FLOOR (extents.descender); } if (PANGO_GRAVITY_IS_IMPROPER (cf_priv->gravity)) -- cgit v1.2.1 From 8c51a367c7bcaf8c84f04ddee7651aedbfd8909b Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Mon, 22 Nov 2021 02:12:04 +0100 Subject: Test more font sizes in the empty line height test This would have caught the issue fixed in the previous commit, because the default font choice of "serif 12" happened to not be affected by it. Most other fonts or font sizes however were. --- tests/testmisc.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/tests/testmisc.c b/tests/testmisc.c index 555f0dce..1aa90948 100644 --- a/tests/testmisc.c +++ b/tests/testmisc.c @@ -634,9 +634,11 @@ test_empty_line_height (void) { PangoContext *context; PangoLayout *layout; + PangoFontDescription *description; PangoRectangle ext1, ext2, ext3; cairo_font_options_t *options; int hint; + int size; if (strcmp (G_OBJECT_TYPE_NAME (pango_cairo_font_map_get_default ()), "PangoCairoCoreTextFontMap") == 0) { @@ -645,33 +647,41 @@ test_empty_line_height (void) } context = pango_font_map_create_context (pango_cairo_font_map_get_default ()); + description = pango_font_description_new (); - for (hint = CAIRO_HINT_METRICS_OFF; hint <= CAIRO_HINT_METRICS_ON; hint++) + for (size = 10; size <= 20; size++) { - options = cairo_font_options_create (); - cairo_font_options_set_hint_metrics (options, hint); - pango_cairo_context_set_font_options (context, options); - cairo_font_options_destroy (options); + pango_font_description_set_size (description, size); - layout = pango_layout_new (context); + for (hint = CAIRO_HINT_METRICS_OFF; hint <= CAIRO_HINT_METRICS_ON; hint++) + { + options = cairo_font_options_create (); + cairo_font_options_set_hint_metrics (options, hint); + pango_cairo_context_set_font_options (context, options); + cairo_font_options_destroy (options); - pango_layout_get_extents (layout, NULL, &ext1); + layout = pango_layout_new (context); + pango_layout_set_font_description (layout, description); - pango_layout_set_text (layout, "a", 1); + pango_layout_get_extents (layout, NULL, &ext1); - pango_layout_get_extents (layout, NULL, &ext2); + pango_layout_set_text (layout, "a", 1); - g_assert_cmpint (ext1.height, ==, ext2.height); + pango_layout_get_extents (layout, NULL, &ext2); - pango_layout_set_text (layout, "Pg", 1); + g_assert_cmpint (ext1.height, ==, ext2.height); - pango_layout_get_extents (layout, NULL, &ext3); + pango_layout_set_text (layout, "Pg", 1); - g_assert_cmpint (ext2.height, ==, ext3.height); + pango_layout_get_extents (layout, NULL, &ext3); - g_object_unref (layout); + g_assert_cmpint (ext2.height, ==, ext3.height); + + g_object_unref (layout); + } } + pango_font_description_free (description); g_object_unref (context); } -- cgit v1.2.1