From 8afdac3548ad39d0ba1eef9fcbcf807f83e7e7ea Mon Sep 17 00:00:00 2001 From: Alexei Podtelezhnikov Date: Sun, 22 Jun 2025 15:00:17 -0400 Subject: [PATCH] [truetype] Simplify twilight zone management (cont'd). A hard limit of 256 on the number of the twilight zone points is imposed. Microsoft fonts use 16 typically. This should be enough for various metric anchors, which si the primary purpose of the twilight zone. We also deduplicate the zone and place it only in the execution context structure. * src/sfnt/ttload.c (tt_face_load_maxp): Limit 'maxTwilightPoints'. * src/truetype/ttinterp.c (TT_Load_Context, TT_Run_Context): Do not tweak or handle the twilight zone. * src/truetype/ttobjs.c (tt_size_init_bytecodea, tt_size_done_bytecode, tt_size_run_prep): Updated to set the twilight zone in TT_ExecContext. * src/truetype/ttobjs.h (TT_Size): Remove 'twilight'. --- src/sfnt/ttload.c | 10 ++++++---- src/truetype/ttinterp.c | 21 --------------------- src/truetype/ttobjs.c | 18 ++++++------------ src/truetype/ttobjs.h | 2 -- 4 files changed, 12 insertions(+), 39 deletions(-) diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index f64ce8890..3e7b2ab54 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -806,15 +806,17 @@ if ( maxProfile->maxFunctionDefs < 64 ) maxProfile->maxFunctionDefs = 64; - /* we add 4 phantom points later */ - if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + /* Points in the twilight zone might be used to mark various */ + /* font metrics or other hinting anchors typically by the CV */ + /* program. Let's be reasonable about their number. */ + if ( maxProfile->maxTwilightPoints > 256 ) { FT_TRACE0(( "tt_face_load_maxp:" - " too much twilight points in `maxp' table;\n" )); + " too many twilight points in `maxp' table;\n" )); FT_TRACE0(( " " " some glyphs might be rendered incorrectly\n" )); - maxProfile->maxTwilightPoints = 0xFFFFU - 4; + maxProfile->maxTwilightPoints = 256; } } diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 45ce8374d..72df9954b 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -284,8 +284,6 @@ exec->tt_metrics = size->ttmetrics; exec->metrics = *size->metrics; - exec->twilight = size->twilight; - return FT_Err_Ok; } @@ -7410,29 +7408,10 @@ TT_Run_Context( TT_ExecContext exec, TT_Size size ) { - FT_ULong num_twilight_points; - - exec->zp0 = exec->pts; exec->zp1 = exec->pts; exec->zp2 = exec->pts; - /* We restrict the number of twilight points to a reasonable, */ - /* heuristic value to avoid slow execution of malformed bytecode. */ - num_twilight_points = FT_MAX( 30, - 2 * ( exec->pts.n_points + exec->cvtSize ) ); - if ( exec->twilight.n_points > num_twilight_points ) - { - if ( num_twilight_points > 0xFFFFU ) - num_twilight_points = 0xFFFFU; - - FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" )); - FT_TRACE5(( " from %d to the more reasonable value %ld\n", - exec->twilight.n_points, - num_twilight_points )); - exec->twilight.n_points = (FT_UShort)num_twilight_points; - } - /* Set up loop detectors. We restrict the number of LOOPCALL loops */ /* and the number of JMPR, JROT, and JROF calls with a negative */ /* argument to values that depend on various parameters like the */ diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index e83335ec2..5d37dbe07 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -951,8 +951,8 @@ size->GS = tt_default_graphics_state; /* all twilight points are originally zero */ - FT_ARRAY_ZERO( size->twilight.org, size->twilight.n_points ); - FT_ARRAY_ZERO( size->twilight.cur, size->twilight.n_points ); + FT_ARRAY_ZERO( exec->twilight.org, exec->twilight.n_points ); + FT_ARRAY_ZERO( exec->twilight.cur, exec->twilight.n_points ); /* clear storage area */ FT_ARRAY_ZERO( exec->storage, exec->storeSize ); @@ -1017,12 +1017,11 @@ FT_FREE( exec->stack ); FT_FREE( exec->FDefs ); + tt_glyphzone_done( memory, &exec->twilight ); + TT_Done_Context( exec ); size->context = NULL; } - - /* twilight zone */ - tt_glyphzone_done( memory, &size->twilight ); } @@ -1036,7 +1035,6 @@ TT_Face face = (TT_Face)size->root.face; FT_Memory memory = size->root.face->memory; - FT_UShort n_twilight; TT_MaxProfile* maxp = &face->max_profile; TT_ExecContext exec; @@ -1076,12 +1074,8 @@ /* reserve twilight zone and set GS before fpgm is executed, */ /* just in case, even though fpgm should not touch them */ - n_twilight = maxp->maxTwilightPoints; - - /* there are 4 phantom points (do we need this?) */ - n_twilight += 4; - - error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); + error = tt_glyphzone_new( memory, maxp->maxTwilightPoints, 0, + &exec->twilight ); if ( error ) goto Exit; diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 0155cd9fe..8a76c17dc 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -225,8 +225,6 @@ FT_BEGIN_HEADER TT_GraphicsState GS; - TT_GlyphZoneRec twilight; /* The instance's twilight zone */ - TT_ExecContext context; /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */