From ef04e4eb205612e73675972c937272ee10bdbb69 Mon Sep 17 00:00:00 2001 From: Alexei Podtelezhnikov Date: Sat, 17 Jan 2026 22:55:16 -0500 Subject: [PATCH] [base, smooth] Fortify direct rendering. This is a better fix for #1384, which is rather about signed overflow. * include/freetype/ftimage.h (FT_Span): Use unsigned position. * src/smooth/ftgrays.c (gray_sweep_direct): Sync with FT_Span. * src/smooth/ftsmooth.c (ft_smooth_render): Remove redundant shift. * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Readjust limits. --- include/freetype/ftimage.h | 2 +- src/base/ftobjs.c | 16 +++++----------- src/smooth/ftgrays.c | 4 ++-- src/smooth/ftsmooth.c | 6 ------ 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index b0a0172ef..a4dc724f3 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -875,7 +875,7 @@ FT_BEGIN_HEADER */ typedef struct FT_Span_ { - short x; + unsigned short x; unsigned short len; unsigned char coverage; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 1f28b759b..1293b254f 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -526,27 +526,21 @@ /* Flag the bounding box size unsuitable for rendering. */ /* FT_Renderer modules should check the return value. */ - /* The limit is based on the ppem value when available. */ + /* The limit is based on the ppem value when available. */ { FT_Face face = slot->face; - FT_Pos xlim = 0x7FFF; - FT_Pos ylim = 0x7FFF; + FT_Pos xlim = 0x8000; + FT_Pos ylim = 0x8000; -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - /* should fit 16-bit FT_Span after 3x implosion */ - if ( mode == FT_RENDER_MODE_LCD ) - xlim = 0x2AAA; -#endif - if ( face ) { xlim = FT_MIN( xlim, 10 * face->size->metrics.x_ppem ); ylim = FT_MIN( ylim, 10 * face->size->metrics.y_ppem ); } - if ( pbox.xMin < -xlim || pbox.xMax > xlim || - pbox.yMin < -ylim || pbox.yMax > ylim ) + if ( pbox.xMin < -xlim || pbox.xMax >= xlim || + pbox.yMin < -ylim || pbox.yMax >= ylim ) { FT_TRACE3(( "ft_glyphslot_preset_bitmap: [%ld %ld %ld %ld]\n", pbox.xMin, pbox.yMin, pbox.xMax, pbox.yMax )); diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 365fbad42..3c387aea0 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -1804,7 +1804,7 @@ typedef ptrdiff_t FT_PtrDist; FT_FILL_RULE( coverage, cover, fill ); span[n].coverage = (unsigned char)coverage; - span[n].x = (short)x; + span[n].x = (unsigned short)x; span[n].len = (unsigned short)( cell->x - x ); if ( ++n == FT_MAX_GRAY_SPANS ) @@ -1823,7 +1823,7 @@ typedef ptrdiff_t FT_PtrDist; FT_FILL_RULE( coverage, area, fill ); span[n].coverage = (unsigned char)coverage; - span[n].x = (short)cell->x; + span[n].x = (unsigned short)cell->x; span[n].len = 1; if ( ++n == FT_MAX_GRAY_SPANS ) diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 21a6eca00..b23be9906 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -494,12 +494,6 @@ else y_shift += 64 * (FT_Int)bitmap->rows; - if ( origin ) - { - x_shift += origin->x; - y_shift += origin->y; - } - /* translate outline to render it into the bitmap */ if ( x_shift || y_shift ) FT_Outline_Translate( outline, x_shift, y_shift );