[truetype] Support selector index 3 of the INSTCTRL instruction.

This flag activates `native ClearType hinting', disabling backwards
compatibility mode as described in Greg Hitchcocks whitepaper.  In
other words, it enables unrestricted functionality of all TrueType
instructions in ClearType.

* src/truetype/ttgload.c (tt_get_metrics): Call `sph_set_tweaks'
unconditionally.
(tt_loader_init): Unset `ignore_x_mode' flag if bit 2 of
`GS.instruct_control' is active.

* src/truetype/ttinterp.c (Ins_INSTCTRL): Handle selector index 3.
(Ins_GETINFO): Updated.

* docs/CHANGES: Document it.
This commit is contained in:
Werner Lemberg 2015-05-22 22:02:15 +02:00
parent 790b8dfbff
commit c61cad868b
4 changed files with 75 additions and 21 deletions

View File

@ -1,3 +1,22 @@
2015-05-20 Werner Lemberg <wl@gnu.org>
[truetype] Support selector index 3 of the INSTCTRL instruction.
This flag activates `native ClearType hinting', disabling backwards
compatibility mode as described in Greg Hitchcocks whitepaper. In
other words, it enables unrestricted functionality of all TrueType
instructions in ClearType.
* src/truetype/ttgload.c (tt_get_metrics): Call `sph_set_tweaks'
unconditionally.
(tt_loader_init): Unset `ignore_x_mode' flag if bit 2 of
`GS.instruct_control' is active.
* src/truetype/ttinterp.c (Ins_INSTCTRL): Handle selector index 3.
(Ins_GETINFO): Updated.
* docs/CHANGES: Document it.
2015-05-20 Werner Lemberg <wl@gnu.org> 2015-05-20 Werner Lemberg <wl@gnu.org>
[truetype] Minor. [truetype] Minor.

View File

@ -35,6 +35,9 @@ CHANGES BETWEEN 2.5.5 and 2.6
(i.e., TTCs using CFFs subfonts instead of TTFs), where it may (i.e., TTCs using CFFs subfonts instead of TTFs), where it may
have a significant difference. have a significant difference.
- Fonts natively hinted for ClearType are now supported, properly
handling selector index 3 of the INSTCTRL bytecode instruction.
III. MISCELLANEOUS III. MISCELLANEOUS

View File

@ -153,14 +153,16 @@
loader->vadvance = advance_height; loader->vadvance = advance_height;
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
loader->exec )
{ {
if ( loader->exec ) loader->exec->sph_tweak_flags = 0;
loader->exec->sph_tweak_flags = 0;
/* this may not be the right place for this, but it works */ /* This may not be the right place for this, but it works... */
if ( loader->exec && loader->exec->ignore_x_mode ) /* Note that we have to unconditionally load the tweaks since */
sph_set_tweaks( loader, glyph_index ); /* it is possible that glyphs individually switch ClearType's */
/* backwards compatibility mode on and off. */
sph_set_tweaks( loader, glyph_index );
} }
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@ -2256,7 +2258,7 @@
/* requires a re-execution of the CVT program */ /* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale ) if ( grayscale != exec->grayscale )
{ {
FT_TRACE4(( "tt_loader_init: grayscale change," FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
" re-executing `prep' table\n" )); " re-executing `prep' table\n" ));
exec->grayscale = grayscale; exec->grayscale = grayscale;
@ -2276,7 +2278,7 @@
return error; return error;
} }
/* see whether the cvt program has disabled hinting */ /* check whether the cvt program has disabled hinting */
if ( exec->GS.instruct_control & 1 ) if ( exec->GS.instruct_control & 1 )
load_flags |= FT_LOAD_NO_HINTING; load_flags |= FT_LOAD_NO_HINTING;
@ -2284,6 +2286,11 @@
if ( exec->GS.instruct_control & 2 ) if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state; exec->GS = tt_default_graphics_state;
/* check whether we have a font hinted for ClearType -- */
/* note that this flag can also be modified in a glyph's bytecode */
if ( exec->GS.instruct_control & 4 )
exec->ignore_x_mode = 0;
exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
loader->exec = exec; loader->exec = exec;
loader->instructions = exec->glyphIns; loader->instructions = exec->glyphIns;

View File

@ -4924,8 +4924,9 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
if ( SUBPIXEL_HINTING && if ( SUBPIXEL_HINTING &&
exc->ignore_x_mode && FT_ABS( D ) == 64 ) exc->ignore_x_mode &&
FT_ABS( D ) == 64 )
D += 1; D += 1;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@ -5152,24 +5153,42 @@
Ins_INSTCTRL( TT_ExecContext exc, Ins_INSTCTRL( TT_ExecContext exc,
FT_Long* args ) FT_Long* args )
{ {
FT_Long K, L; FT_Long K, L, Kf;
K = args[1]; K = args[1];
L = args[0]; L = args[0];
if ( K < 1 || K > 2 ) /* selector values cannot be `OR'ed; */
/* they are indices starting with index 1, not flags */
if ( K < 1 || K > 3 )
{ {
if ( exc->pedantic_hinting ) if ( exc->pedantic_hinting )
exc->error = FT_THROW( Invalid_Reference ); exc->error = FT_THROW( Invalid_Reference );
return; return;
} }
if ( L != 0 ) /* convert index to flag value */
L = K; Kf = 1 << ( K - 1 );
exc->GS.instruct_control = FT_BOOL( if ( L != 0 )
( (FT_Byte)exc->GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); {
/* arguments to selectors look like flag values */
if ( L != Kf )
{
if ( exc->pedantic_hinting )
exc->error = FT_THROW( Invalid_Reference );
return;
}
}
exc->GS.instruct_control &= ~(FT_Byte)Kf;
exc->GS.instruct_control |= (FT_Byte)L;
/* INSTCTRL modifying flag 3 also has an effect */
/* outside of the CVT program */
if ( K == 3 )
exc->ignore_x_mode = FT_BOOL( L == 4 );
} }
@ -7284,11 +7303,18 @@
/* */ /* */
if ( SUBPIXEL_HINTING && if ( SUBPIXEL_HINTING &&
( args[0] & 1 ) != 0 && ( args[0] & 1 ) != 0 &&
exc->ignore_x_mode ) exc->subpixel )
{ {
K = exc->rasterizer_version; if ( exc->ignore_x_mode )
FT_TRACE7(( "Setting rasterizer version %d\n", {
exc->rasterizer_version )); /* if in ClearType backwards compatibility mode, */
/* we sometimes change the TrueType version dynamically */
K = exc->rasterizer_version;
FT_TRACE7(( "Setting rasterizer version %d\n",
exc->rasterizer_version ));
}
else
K = TT_INTERPRETER_VERSION_38;
} }
else else
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@ -7322,7 +7348,6 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING && if ( SUBPIXEL_HINTING &&
exc->ignore_x_mode &&
exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
{ {