diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 44400fbe2..2ea09db1e 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -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: