Merge branch 'SHZ_spec' into 'master'

* src/truetype/ttinterp.c (Ins_SHZ): Rewrite to specifications.

Closes #1422

See merge request freetype/freetype!427
This commit is contained in:
Alexei Podtelezhnikov 2026-04-26 08:37:55 -04:00
commit 887d6cb319

View file

@ -4924,7 +4924,7 @@
FT_F26Dot6* x,
FT_F26Dot6* y,
TT_GlyphZone zone,
FT_UShort* refp )
FT_UInt* refp )
{
TT_GlyphZoneRec zp;
FT_UShort p;
@ -4965,10 +4965,9 @@
/* See `ttinterp.h' for details on backward compatibility mode. */
static void
Move_Zp2_Point( TT_ExecContext exc,
FT_UShort point,
FT_UInt point,
FT_F26Dot6 dx,
FT_F26Dot6 dy,
FT_Bool touch )
FT_F26Dot6 dy )
{
if ( exc->GS.freeVector.x != 0 )
{
@ -4978,8 +4977,7 @@
#endif
exc->zp2.cur[point].x = ADD_LONG( exc->zp2.cur[point].x, dx );
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
if ( exc->GS.freeVector.y != 0 )
@ -4990,8 +4988,7 @@
#endif
exc->zp2.cur[point].y = ADD_LONG( exc->zp2.cur[point].y, dy );
if ( touch )
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
}
@ -5008,10 +5005,10 @@
{
FT_Long loop = exc->GS.loop;
TT_GlyphZoneRec zp;
FT_UShort refp;
FT_UInt refp;
FT_F26Dot6 dx, dy;
FT_UShort point;
FT_UInt point;
if ( exc->new_top < loop )
@ -5028,7 +5025,7 @@
while ( loop-- )
{
point = (FT_UShort)*(--args);
point = (FT_UInt)*(--args);
if ( BOUNDS( point, exc->zp2.n_points ) )
{
@ -5039,7 +5036,7 @@
}
}
else
Move_Zp2_Point( exc, point, dx, dy, TRUE );
Move_Zp2_Point( exc, point, dx, dy );
}
Fail:
@ -5062,11 +5059,10 @@
FT_Long* args )
{
TT_GlyphZoneRec zp;
FT_UShort refp;
FT_UInt refp, start, limit, i;
FT_F26Dot6 dx, dy;
FT_UShort contour, bounds;
FT_UShort start, limit, i;
contour = (FT_UShort)args[0];
@ -5082,6 +5078,9 @@
if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
return;
if ( zp.cur != exc->zp2.cur )
refp = ~0U; /* nan */
if ( contour == 0 )
start = 0;
else
@ -5095,8 +5094,8 @@
for ( i = start; i < limit; i++ )
{
if ( zp.cur != exc->zp2.cur || refp != i )
Move_Zp2_Point( exc, i, dx, dy, TRUE );
if ( refp != i )
Move_Zp2_Point( exc, i, dx, dy );
}
}
@ -5111,16 +5110,27 @@
Ins_SHZ( TT_ExecContext exc,
FT_Long* args )
{
FT_Vector* cur;
TT_GlyphZoneRec zp;
FT_UShort refp;
FT_F26Dot6 dx,
dy;
FT_UShort limit, i;
FT_UInt refp, i, limit;
FT_F26Dot6 dx, dy;
if ( BOUNDS( args[0], 2 ) )
/* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points, */
/* which must be subtracted. */
switch ( (FT_Int)args[0] )
{
case 0:
cur = exc->twilight.cur;
limit = exc->twilight.n_points;
break;
case 1:
cur = exc->pts.cur;
limit = exc->pts.n_points > 4U ? exc->pts.n_points - 4U : 0;
break;
default:
if ( exc->pedantic_hinting )
exc->error = FT_THROW( Invalid_Reference );
return;
@ -5129,22 +5139,34 @@
if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
return;
/* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
/* Twilight zone has no real contours, so use `n_points'. */
/* Normal zone's `n_points' includes phantoms, so must */
/* subtract them. */
if ( exc->GS.gep2 == 0 )
limit = exc->zp2.n_points;
else if ( exc->zp2.n_points > 4U )
limit = exc->zp2.n_points - 4U;
else
return;
if ( zp.cur != cur )
refp = ~0U; /* nan */
/* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
for ( i = 0; i < limit; i++ )
/* XXX: UNDOCUMENTED! SHZ doesn't touch the points. */
if ( dx )
{
if ( zp.cur != exc->zp2.cur || refp != i )
Move_Zp2_Point( exc, i, dx, dy, FALSE );
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
/* See `ttinterp.h' for details on backward compatibility mode. */
if ( !exc->backward_compatibility )
#endif
for ( i = 0; i < limit; i++ )
{
if ( refp != i )
cur[i].x = ADD_LONG( cur[i].x, dx );
}
}
if ( dy )
{
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
/* See `ttinterp.h' for details on backward compatibility mode. */
if ( exc->backward_compatibility != 0x7 )
#endif
for ( i = 0; i < limit; i++ )
{
if ( refp != i )
cur[i].y = ADD_LONG( cur[i].y, dy );
}
}
}
@ -5161,7 +5183,7 @@
{
FT_Long loop = exc->GS.loop;
FT_F26Dot6 dx, dy;
FT_UShort point;
FT_UInt point;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
FT_Bool in_twilight = FT_BOOL( exc->GS.gep0 == 0 ||
exc->GS.gep1 == 0 ||
@ -5183,7 +5205,7 @@
while ( loop-- )
{
point = (FT_UShort)*(--args);
point = (FT_UInt)*(--args);
if ( BOUNDS( point, exc->zp2.n_points ) )
{
@ -5206,11 +5228,11 @@
( exc->backward_compatibility != 0x7 &&
( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) )
Move_Zp2_Point( exc, point, 0, dy, TRUE );
Move_Zp2_Point( exc, point, 0, dy );
}
else
#endif
Move_Zp2_Point( exc, point, dx, dy, TRUE );
Move_Zp2_Point( exc, point, dx, dy );
}
Fail: