From 1be132731d31c3752b275735e5dbe1f60d1988c3 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 25 Dec 2023 15:38:15 +0800 Subject: [PATCH] Apply TTF advance width rounding to uninstructed glyphs * src/sfnt.c (sfnt_scale_metrics): * src/sfntfont.c (sfntfont_get_glyph_outline): Round advance and floor lbearing scaling glyph metrics. (sfntfont_measure_pcm): Don't round or truncate metrics which have already been. --- src/sfnt.c | 17 ++++++++++------- src/sfntfont.c | 11 ++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/sfnt.c b/src/sfnt.c index d945342c264..b67377ad064 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -5656,18 +5656,21 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size, return 0; } -/* Scale the specified glyph metrics by FACTOR. - Set METRICS->lbearing and METRICS->advance to their current - values times factor. */ +/* Scale the specified glyph metrics by FACTOR. Set METRICS->lbearing + and METRICS->advance to their current values times factor; take the + floor of the left bearing and round the advance width. */ MAYBE_UNUSED TEST_STATIC void sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics, sfnt_fixed factor) { - metrics->lbearing - = sfnt_mul_fixed (metrics->lbearing * 65536, factor); - metrics->advance - = sfnt_mul_fixed (metrics->advance * 65536, factor); + sfnt_fixed lbearing, advance; + + lbearing = sfnt_mul_fixed (metrics->lbearing * 65536, factor); + advance = sfnt_mul_fixed (metrics->advance * 65536, factor); + + metrics->lbearing = sfnt_floor_fixed (lbearing); + metrics->advance = sfnt_round_fixed (advance); } /* Calculate the factor used to convert em space to device space for a diff --git a/src/sfntfont.c b/src/sfntfont.c index 078fe6083a6..c626e76b52b 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c @@ -2304,7 +2304,8 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, instruction code or glyph variation. The left side bearing is the distance from the origin point to the left most point on the X axis. */ - temp.lbearing = outline->xmin - outline->origin; + temp.lbearing + = SFNT_FLOOR_FIXED (outline->xmin - outline->origin); } } } @@ -3497,12 +3498,12 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, if (!outline) return 1; - /* Round the left side bearing down. */ - pcm->lbearing = SFNT_FLOOR_FIXED (metrics.lbearing) / 65536; + /* The left side bearing has already been floored. */ + pcm->lbearing = metrics.lbearing / 65536; pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) / 65536; - /* Round the advance, ascent and descent upwards. */ - pcm->width = SFNT_CEIL_FIXED (metrics.advance) / 65536; + /* The advance is already rounded; ceil the ascent and descent. */ + pcm->width = metrics.advance / 65536; pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) / 65536; pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) / 65536; -- 2.39.2