diff --git a/ChangeLog b/ChangeLog index 2929e7c83..6b5c54c26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2015-05-20 Werner Lemberg + + [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 [truetype] Minor. diff --git a/docs/CHANGES b/docs/CHANGES index 999667ec0..e706e1f59 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -35,6 +35,9 @@ CHANGES BETWEEN 2.5.5 and 2.6 (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 diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index fd97009f7..ca0794472 100644 --- 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; @@ -2284,6 +2286,11 @@ 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; loader->instructions = exec->glyphIns; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 0e536af79..8ef752664 100644 --- 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,24 +5153,42 @@ 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 ); return; } - if ( L != 0 ) - L = K; + /* convert index to flag value */ + Kf = 1 << ( K - 1 ); - exc->GS.instruct_control = FT_BOOL( - ( (FT_Byte)exc->GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); + if ( L != 0 ) + { + /* 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 && ( 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 ) {