* src/truetype/ttinterp.c (Ins_DELTAP): Fix subpixel hinting.

Before this patch, it was impossible to ever call DELTAP[123] in
subpixel hinting mode as described in the ClearType whitepaper; it
only worked if in `compatibility mode'.  However, compatibility mode
essentially disables SHPIX, completely ruining hinting of
ttfautohint output, for example.

We now follow the whitepaper more closely so that DELTAP[123]
instructions for touched points in the non-subpixel direction are
executed.
This commit is contained in:
Werner Lemberg 2014-11-03 07:20:57 +01:00
parent 525d4876be
commit 706f752b5e
2 changed files with 30 additions and 25 deletions

View File

@ -1,3 +1,17 @@
2014-11-03 Werner Lemberg <wl@gnu.org>
* src/truetype/ttinterp.c (Ins_DELTAP): Fix subpixel hinting.
Before this patch, it was impossible to ever call DELTAP[123] in
subpixel hinting mode as described in the ClearType whitepaper; it
only worked if in `compatibility mode'. However, compatibility mode
essentially disables SHPIX, completely ruining hinting of
ttfautohint output, for example.
We now follow the whitepaper more closely so that DELTAP[123]
instructions for touched points in the non-subpixel direction are
executed.
2014-10-31 Alexei Podtelezhnikov <apodtele@gmail.com>
[smooth] Improve code readability.

View File

@ -7581,42 +7581,33 @@
/*
* Allow delta move if
*
* - not using ignore_x_mode rendering
* - glyph is specifically set to allow it
* - glyph is composite and freedom vector is not subpixel
* vector
* - not using ignore_x_mode rendering,
* - glyph is specifically set to allow it, or
* - glyph is composite and freedom vector is not in subpixel
* direction.
*/
if ( !CUR.ignore_x_mode ||
( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
CUR_Func_move( &CUR.zp0, A, B );
/* Otherwise apply subpixel hinting and */
/* compatibility mode rules */
else if ( CUR.ignore_x_mode )
/* Otherwise, apply subpixel hinting and compatibility mode */
/* rules, always skipping deltas in subpixel direction. */
else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
{
if ( CUR.GS.freeVector.y != 0 )
B1 = (FT_UShort)CUR.zp0.cur[A].y;
else
B1 = (FT_UShort)CUR.zp0.cur[A].x;
/* save the y value of the point now; compare after move */
B1 = (FT_UShort)CUR.zp0.cur[A].y;
#if 0
/* Standard Subpixel Hinting: Allow y move. */
/* This messes up dejavu and may not be needed... */
if ( !CUR.face->sph_compatibility_mode &&
CUR.GS.freeVector.y != 0 )
/* Standard subpixel hinting: Allow y move for y-touched */
/* points. This messes up DejaVu ... */
if ( !CUR.face->sph_compatibility_mode &&
( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
CUR_Func_move( &CUR.zp0, A, B );
else
#endif /* 0 */
/* Compatibility Mode: Allow x or y move if point touched in */
/* Y direction. */
if ( CUR.face->sph_compatibility_mode &&
!( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
/* compatibility mode */
else if ( CUR.face->sph_compatibility_mode &&
!( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
{
/* save the y value of the point now; compare after move */
B1 = (FT_UShort)CUR.zp0.cur[A].y;
if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
B = FT_PIX_ROUND( B1 + B ) - B1;