[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'.
This commit is contained in:
Alexei Podtelezhnikov 2025-06-22 15:00:17 -04:00
parent 36ddd0cba1
commit 8afdac3548
4 changed files with 12 additions and 39 deletions

View file

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

View file

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

View file

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

View file

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