ref: c61cad868b32e6c7f8e1f3bf89719c137e52eaf8
parent: 790b8dfbffad6bc25c3fca9b5f6feda8dece4661
author: Werner Lemberg <[email protected]>
date: Fri May 22 18:02:15 EDT 2015
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2015-05-20 Werner Lemberg <[email protected]>
+ [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 <[email protected]>
+
[truetype] Minor.
* src/truetype/ttinterp.h (SetSuperRound): Fix type of `GridPeriod'
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -35,6 +35,9 @@
(i.e., TTCs using CFFs subfonts instead of TTFs), where it may
have a significant difference.
+ - Fonts natively hinted for ClearType are now supported, properly
+ handling selector index 3 of the INSTCTRL bytecode instruction.
+
III. MISCELLANEOUS
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -153,14 +153,16 @@
loader->vadvance = advance_height;
#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 */
- if ( loader->exec && loader->exec->ignore_x_mode )
- sph_set_tweaks( loader, glyph_index );
+ /* This may not be the right place for this, but it works... */
+ /* Note that we have to unconditionally load the tweaks since */
+ /* 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 */
@@ -2256,7 +2258,7 @@
/* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale )
{
- FT_TRACE4(( "tt_loader_init: grayscale change,"
+ FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
" re-executing `prep' table\n" ));
exec->grayscale = grayscale;
@@ -2276,7 +2278,7 @@
return error;
}
- /* see whether the cvt program has disabled hinting */
+ /* check whether the cvt program has disabled hinting */
if ( exec->GS.instruct_control & 1 )
load_flags |= FT_LOAD_NO_HINTING;
@@ -2283,6 +2285,11 @@
/* load default graphics state -- if needed */
if ( exec->GS.instruct_control & 2 )
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 );
loader->exec = exec;
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4924,8 +4924,9 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
/* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
- if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode && FT_ABS( D ) == 64 )
+ if ( SUBPIXEL_HINTING &&
+ exc->ignore_x_mode &&
+ FT_ABS( D ) == 64 )
D += 1;
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -5152,13 +5153,15 @@
Ins_INSTCTRL( TT_ExecContext exc,
FT_Long* args )
{
- FT_Long K, L;
+ FT_Long K, L, Kf;
K = args[1];
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 )
exc->error = FT_THROW( Invalid_Reference );
@@ -5165,11 +5168,27 @@
return;
}
+ /* convert index to flag value */
+ Kf = 1 << ( K - 1 );
+
if ( L != 0 )
- L = K;
+ {
+ /* 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_BOOL(
- ( (FT_Byte)exc->GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
+ 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 &&
( args[0] & 1 ) != 0 &&
- exc->ignore_x_mode )
+ exc->subpixel )
{
- K = exc->rasterizer_version;
- FT_TRACE7(( "Setting rasterizer version %d\n",
- exc->rasterizer_version ));
+ if ( exc->ignore_x_mode )
+ {
+ /* 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
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -7322,7 +7348,6 @@
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
if ( SUBPIXEL_HINTING &&
- exc->ignore_x_mode &&
exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
{