diff --git a/ChangeLog b/ChangeLog index 310703b9e..436ecffd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2013-05-22 Infinality + + [truetype] Adjust subpixel zp2 moves and tweak rules. + + These modifications fix thin diagonal stems in some legacy fonts. + + * src/truetype/ttinterp.c (Direct_Move_X): Remove unused macro. + (Move_Zp2_Point): Don't always disable x moves for subpixel rendering. + (Ins_SHP): Disable x moves here for subpixel rendering. + (Ins_SHPIX): Only disable x moves in compatibility mode. + Split out zp2 move reversals and reorder conditional respectively. + + * src/truetype/ttsubpix.c (SKIP_NONPIXEL_Y_MOVES_Rules): Fix oversight. + Only adjust Verdana clones for 17 ppem. + (SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions): Add Courier New. + (ALWAYS_SKIP_DELTAP_Rules): Found additional cases for Arial `s'. + 2013-05-20 Infinality [truetype] Simplify and improve subpixel function detection. diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 437db2294..0cd869d64 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -5825,12 +5825,7 @@ if ( CUR.GS.freeVector.x != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !CUR.ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp2.cur[point].x += dx; - + CUR.zp2.cur[point].x += dx; if ( touch ) CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -5887,6 +5882,13 @@ } } else +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* doesn't follow Cleartype spec but produces better result */ + if ( SUBPIXEL_HINTING && + CUR.ignore_x_mode ) + MOVE_Zp2_Point( point, 0, dy, TRUE ); + else +#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ MOVE_Zp2_Point( point, dx, dy, TRUE ); CUR.GS.loop--; @@ -6080,15 +6082,22 @@ if ( !CUR.face->sph_compatibility_mode && CUR.GS.freeVector.y != 0 ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) { MOVE_Zp2_Point( point, dx, dy, TRUE ); - /* don't allow reversals */ - goto Skip; - } + /* save new point */ + if ( CUR.GS.freeVector.y != 0 ) + { + B2 = CUR.zp2.cur[point].y; + + /* reverse any disallowed moves */ + if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && + ( B1 & 63 ) != 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + MOVE_Zp2_Point( point, -dx, -dy, TRUE ); + } + } else if ( CUR.face->sph_compatibility_mode ) { if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) @@ -6107,27 +6116,22 @@ ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); + MOVE_Zp2_Point( point, 0, dy, TRUE ); + + /* save new point */ + if ( CUR.GS.freeVector.y != 0 ) + { + B2 = CUR.zp2.cur[point].y; + + /* reverse any disallowed moves */ + if ( ( B1 & 63 ) == 0 && + ( B2 & 63 ) != 0 && + B1 != B2 ) + MOVE_Zp2_Point( point, 0, -dy, TRUE ); + } } - - /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) - B2 = CUR.zp2.cur[point].y; - else - B2 = CUR.zp2.cur[point].x; - - /* reverse any disallowed moves */ - if ( ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) || - ( CUR.face->sph_compatibility_mode && - CUR.GS.freeVector.y != 0 && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) ) - MOVE_Zp2_Point( point, -dx, -dy, TRUE ); + else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) + MOVE_Zp2_Point( point, dx, dy, TRUE ); } else MOVE_Zp2_Point( point, dx, dy, TRUE ); diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c index 8310b338d..28e0e587c 100644 --- a/src/truetype/ttsubpix.c +++ b/src/truetype/ttsubpix.c @@ -310,19 +310,19 @@ /* Skip Y moves that start with a point that is not on a Y pixel */ /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 5 +#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = { /* fix vwxyz thinness*/ - { "Consolas", 0, "", 0 }, { "-", 0, "N", 0 }, + { "Consolas", 0, "", 0 }, /* Fix thin middle stems */ - { "-Core MS Legacy Fonts", 0, "Regular/Bold Class", 0 }, + { "Core MS Legacy Fonts", 0, "Regular", 0 }, /* Cyrillic small letter I */ { "Legacy Sans Fonts", 0, "", 0 }, /* Fix artifacts with some Regular & Bold */ - { "Verdana Clones", 0, "", 0 }, + { "Verdana Clones", 17, "", 0 }, }; @@ -331,7 +331,8 @@ const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = { - { "-", 0, "", 0 }, + /* Fixes < and > */ + { "Courier New", 0, "Regular", 0 }, }; @@ -450,7 +451,7 @@ /* Skip DELTAP instructions if matched. */ -#define ALWAYS_SKIP_DELTAP_RULES_SIZE 18 +#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules [ALWAYS_SKIP_DELTAP_RULES_SIZE] = @@ -473,10 +474,15 @@ { "Arial", 10, "Regular", '6' }, { "Arial", 0, "Bold/BoldItalic Class", 'a' }, /* Make horizontal stems consistent with the rest */ - { "Arial", 24, "Bold", 's' }, - { "Arial", 25, "Bold", 's' }, { "Arial", 24, "Bold", 'a' }, { "Arial", 25, "Bold", 'a' }, + { "Arial", 24, "Bold", 's' }, + { "Arial", 25, "Bold", 's' }, + { "Arial", 34, "Bold", 's' }, + { "Arial", 35, "Bold", 's' }, + { "Arial", 36, "Bold", 's' }, + { "Arial", 25, "Regular", 's' }, + { "Arial", 26, "Regular", 's' }, };