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.
This commit is contained in:
Po Lu 2023-12-25 15:38:15 +08:00
parent 995dd36da1
commit 1be132731d
2 changed files with 16 additions and 12 deletions

View file

@ -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

View file

@ -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;