Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:philacorns:backports
freetype2
gentoo-subpixel.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gentoo-subpixel.patch of Package freetype2
From http://www.infinality.net/fedora/linux/13/SRPMS/freetype-subpixel-2.3.12-3.fc13.src.rpm and modified to patch freetype 2.4.0 See http://www.infinality.net/blog/?p=67 and http://forums.gentoo.org/viewtopic-p-6350322.html#6350322 Added: freetype-2.3.0-enable-spr.patch freetype-2.2.1-enable-valid.patch freetype-2.2.1-memcpy-fix.patch #define FT_CONFIG_OPTION_SYSTEM_ZLIB in include/freetype/config/ftoption.h diff -Naur freetype-2.4.0-orig//include/freetype/config/ftoption.h freetype-2.4.0/include/freetype/config/ftoption.h --- freetype-2.4.0-orig//include/freetype/config/ftoption.h 2010-07-05 11:38:55.000000000 +0700 +++ freetype-2.4.0/include/freetype/config/ftoption.h 2010-07-14 17:46:36.000000000 +0700 @@ -93,7 +93,7 @@ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ /* */ -/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ +#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING /*************************************************************************/ @@ -185,7 +185,7 @@ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ +#define FT_CONFIG_OPTION_SYSTEM_ZLIB /*************************************************************************/ diff -Naur freetype-2.4.0-orig//include/freetype/freetype.h freetype-2.4.0/include/freetype/freetype.h --- freetype-2.4.0-orig//include/freetype/freetype.h 2010-07-13 02:27:14.000000000 +0700 +++ freetype-2.4.0/include/freetype/freetype.h 2010-07-14 17:34:15.000000000 +0700 @@ -2482,6 +2482,7 @@ #define FT_LOAD_MONOCHROME 0x1000 #define FT_LOAD_LINEAR_DESIGN 0x2000 #define FT_LOAD_NO_AUTOHINT 0x8000U +/*#define FT_LOAD_COMPATIBLE_WIDTHS 0x10000U*/ /* */ diff -Naur freetype-2.4.0-orig//include/freetype/internal/ftobjs.h freetype-2.4.0/include/freetype/internal/ftobjs.h --- freetype-2.4.0-orig//include/freetype/internal/ftobjs.h 2009-07-03 20:28:24.000000000 +0700 +++ freetype-2.4.0/include/freetype/internal/ftobjs.h 2010-07-14 17:34:15.000000000 +0700 @@ -81,6 +81,13 @@ #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) +#define FT_PIX_FLOOR_sph( x ) ( (x) & ~3 ) +#define FT_PIX_ROUND_sph( x ) FT_PIX_FLOOR_sph( (x) + 2 ) +#define FT_PIX_CEIL_sph( x ) FT_PIX_FLOOR_sph( (x) + 3 ) + +#define FT_PIX_FLOOR_sphn( x, n ) ( (x) & ~(64 / n - 1) ) +#define FT_PIX_ROUND_sphn( x, n ) FT_PIX_FLOOR_sph( (x) + 32 / n) +#define FT_PIX_CEIL_sphn( x, n ) FT_PIX_FLOOR_sph( (x) + 64 / n - 1) /* * Return the highest power of 2 that is <= value; this correspond to diff -Naur freetype-2.4.0-orig//modules.cfg freetype-2.4.0/modules.cfg --- freetype-2.4.0-orig//modules.cfg 2009-03-14 20:45:26.000000000 +0700 +++ freetype-2.4.0/modules.cfg 2010-07-14 17:34:15.000000000 +0700 @@ -110,7 +110,7 @@ AUX_MODULES += cache # TrueType GX/AAT table validation. Needs ftgxval.c below. -# AUX_MODULES += gxvalid +AUX_MODULES += gxvalid # Support for streams compressed with gzip (files with suffix .gz). # @@ -124,7 +124,7 @@ # OpenType table validation. Needs ftotval.c below. # -# AUX_MODULES += otvalid +AUX_MODULES += otvalid # Auxiliary PostScript driver component to share common code. # diff -Naur freetype-2.4.0-orig//src/psaux/psobjs.c freetype-2.4.0/src/psaux/psobjs.c --- freetype-2.4.0-orig//src/psaux/psobjs.c 2010-06-20 21:24:14.000000000 +0700 +++ freetype-2.4.0/src/psaux/psobjs.c 2010-07-14 17:34:15.000000000 +0700 @@ -183,6 +183,11 @@ return PSaux_Err_Invalid_Argument; } + if ( length < 0 ) { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return PSaux_Err_Invalid_Argument; + } + /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { diff -Naur freetype-2.4.0-orig//src/truetype/ttgload.c freetype-2.4.0/src/truetype/ttgload.c --- freetype-2.4.0-orig//src/truetype/ttgload.c 2010-06-29 15:27:12.000000000 +0700 +++ freetype-2.4.0/src/truetype/ttgload.c 2010-07-14 17:34:15.000000000 +0700 @@ -1659,7 +1659,6 @@ { FT_Pos advance = loader->linear; - /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ /* correctly support DynaLab fonts, which have an incorrect */ /* `advance_Width_Max' field! It is used, to my knowledge, */ @@ -1669,6 +1668,8 @@ ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) advance = face->horizontal.advance_Width_Max; + + /* we need to return the advance in font units in linearHoriAdvance, */ /* it will be scaled later by the base layer. */ glyph->linearHoriAdvance = advance; @@ -1683,13 +1684,20 @@ IS_HINTED( loader->load_flags ) ) { FT_Byte* widthp; + FT_Bool subpixel; + FT_Bool compatible_widths; + + subpixel = + FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != FT_RENDER_MODE_MONO ); + compatible_widths = FALSE; + /*FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != FT_LOAD_COMPATIBLE_WIDTHS )*/ widthp = tt_face_get_device_metrics( face, size->root.metrics.x_ppem, glyph_index ); - if ( widthp ) + if ( (!subpixel && widthp) || compatible_widths ) glyph->metrics.horiAdvance = *widthp << 6; } @@ -1883,7 +1891,8 @@ { TT_ExecContext exec; FT_Bool grayscale; - + FT_Bool subpixel; + FT_Bool compatible_widths; if ( !size->cvt_ready ) { @@ -1901,10 +1910,31 @@ grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); + subpixel = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); + + compatible_widths = FALSE; + /*FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_LOAD_COMPATIBLE_WIDTHS)*/; + TT_Load_Context( exec, face, size ); /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ + if ( compatible_widths != exec->compatible_widths ) + { + FT_UInt i; + + + exec->compatible_widths = compatible_widths; + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size ); + } + + + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) { FT_UInt i; @@ -1914,6 +1944,18 @@ for ( i = 0; i < size->cvt_size; i++ ) size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size ); + } + + if ( subpixel != exec->subpixel ) + { + FT_UInt i; + + + exec->subpixel = subpixel; + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); tt_size_run_prep( size ); } diff -Naur freetype-2.4.0-orig//src/truetype/ttinterp.c freetype-2.4.0/src/truetype/ttinterp.c --- freetype-2.4.0-orig//src/truetype/ttinterp.c 2010-07-08 12:23:01.000000000 +0700 +++ freetype-2.4.0/src/truetype/ttinterp.c 2010-07-14 17:34:15.000000000 +0700 @@ -168,6 +168,9 @@ #define CUR_Func_round( d, c ) \ CUR.func_round( EXEC_ARG_ d, c ) +#define CUR_Func_round_sphn( d, c ) \ + CUR.func_round_sphn( EXEC_ARG_ d, c ) + #define CUR_Func_read_cvt( index ) \ CUR.func_read_cvt( EXEC_ARG_ index ) @@ -1836,7 +1839,7 @@ #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING FT_ASSERT( !CUR.face->unpatented_hinting ); #endif - +if (CUR.skip_x == 0){ v = CUR.GS.freeVector.x; if ( v != 0 ) @@ -1847,7 +1850,8 @@ zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } - +} +if (CUR.skip_y == 0){ v = CUR.GS.freeVector.y; if ( v != 0 ) @@ -1859,6 +1863,7 @@ zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } + } /*************************************************************************/ @@ -1889,14 +1894,15 @@ #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING FT_ASSERT( !CUR.face->unpatented_hinting ); #endif - +if (CUR.skip_x == 0){ v = CUR.GS.freeVector.x; if ( v != 0 ) zone->org[point].x += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); - +} +if (CUR.skip_y==0){ v = CUR.GS.freeVector.y; if ( v != 0 ) @@ -1904,7 +1910,7 @@ v * 0x10000L, CUR.F_dot_P ); } - + } /*************************************************************************/ /* */ @@ -1922,9 +1928,10 @@ FT_F26Dot6 distance ) { FT_UNUSED_EXEC; - +if (CUR.skip_x == 0){ zone->cur[point].x += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; +} } @@ -1934,11 +1941,11 @@ FT_F26Dot6 distance ) { FT_UNUSED_EXEC; - +if (CUR.skip_y ==0){ zone->cur[point].y += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } - + } /*************************************************************************/ /* */ @@ -1956,8 +1963,9 @@ FT_F26Dot6 distance ) { FT_UNUSED_EXEC; - +if (CUR.skip_x == 0){ zone->org[point].x += distance; +} } @@ -1967,9 +1975,10 @@ FT_F26Dot6 distance ) { FT_UNUSED_EXEC; - +if (CUR.skip_y == 0){ zone->org[point].y += distance; } + } /*************************************************************************/ @@ -2063,6 +2072,32 @@ } + static FT_F26Dot6 + Round_To_Grid_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + if ( distance >= 0 ) + { + val = distance + compensation + 32 / CUR.grid_factor; + if ( distance && val > 0 ) + val &= ~(64 / CUR.grid_factor - 1); + else + val = 0; + } + else + { + val = -FT_PIX_ROUND_sphn( compensation - distance, CUR.grid_factor ); + if ( val > 0 ) + val = 0; + } + return val; + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2105,6 +2140,32 @@ } + static FT_F26Dot6 + Round_To_Half_Grid_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + if ( distance >= 0 ) + { + val = FT_PIX_FLOOR_sphn( distance + compensation, CUR.grid_factor ) + + 32 / CUR.grid_factor; + if ( distance && val < 0 ) + val = 0; + } + else + { + val = -( FT_PIX_FLOOR_sphn( compensation - distance, CUR.grid_factor ) + + 32 / CUR.grid_factor); + if ( val > 0 ) + val = 0; + } + + return val; + } + /*************************************************************************/ /* */ /* <Function> */ @@ -2148,6 +2209,31 @@ return val; } + static FT_F26Dot6 + Round_Down_To_Grid_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( distance && val > 0 ) + val &= ~(64 / CUR.grid_factor - 1); + else + val = 0; + } + else + { + val = -( ( compensation - distance ) & -(64 / CUR.grid_factor) ); + if ( val > 0 ) + val = 0; + } + + return val; + } /*************************************************************************/ /* */ @@ -2193,6 +2279,33 @@ } + + static FT_F26Dot6 + Round_Up_To_Grid_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + if ( distance >= 0 ) + { + val = distance + compensation + (64 / CUR.grid_factor - 1); + if ( distance && val > 0 ) + val &= ~(64 / CUR.grid_factor - 1); + else + val = 0; + } + else + { + val = - FT_PIX_CEIL_sphn( compensation - distance, CUR.grid_factor ); + if ( val > 0 ) + val = 0; + } + + return val; + } + /*************************************************************************/ /* */ /* <Function> */ @@ -2237,6 +2350,32 @@ } + + static FT_F26Dot6 + Round_To_Double_Grid_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + if ( distance >= 0 ) + { + val = distance + compensation + 16 / CUR.grid_factor; + if ( distance && val > 0 ) + val &= ~(32 / CUR.grid_factor - 1); + else + val = 0; + } + else + { + val = -FT_PAD_ROUND( compensation - distance, 32 / CUR.grid_factor ); + if ( val > 0 ) + val = 0; + } + + return val; + } /*************************************************************************/ /* */ /* <Function> */ @@ -2287,6 +2426,14 @@ } + + static FT_F26Dot6 + Round_Super_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + return distance; + } + /*************************************************************************/ /* */ /* <Function> */ @@ -2335,6 +2482,15 @@ } + + static FT_F26Dot6 + Round_Super_45_sphn( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + + return distance; + } + /*************************************************************************/ /* */ /* <Function> */ @@ -2357,30 +2513,37 @@ case TT_Round_To_Grid: CUR.func_round = (TT_Round_Func)Round_To_Grid; + CUR.func_round_sphn = (TT_Round_Func)Round_To_Grid_sphn; break; case TT_Round_Up_To_Grid: CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + CUR.func_round_sphn = (TT_Round_Func)Round_Up_To_Grid_sphn; break; case TT_Round_Down_To_Grid: CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + CUR.func_round_sphn = (TT_Round_Func)Round_Down_To_Grid_sphn; break; case TT_Round_To_Half_Grid: CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + CUR.func_round_sphn = (TT_Round_Func)Round_To_Half_Grid_sphn; break; case TT_Round_To_Double_Grid: CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + CUR.func_round_sphn = (TT_Round_Func)Round_To_Double_Grid_sphn; break; case TT_Round_Super: CUR.func_round = (TT_Round_Func)Round_Super; + CUR.func_round_sphn = (TT_Round_Func)Round_Super_sphn; break; case TT_Round_Super_45: CUR.func_round = (TT_Round_Func)Round_Super_45; + CUR.func_round_sphn = (TT_Round_Func)Round_Super_45_sphn; break; } } @@ -3031,44 +3194,52 @@ #define DO_RTHG \ CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; \ + CUR.func_round_sphn = (TT_Round_Func)Round_To_Half_Grid_sphn; #define DO_RTG \ CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; + CUR.func_round = (TT_Round_Func)Round_To_Grid; \ + CUR.func_round_sphn = (TT_Round_Func)Round_To_Grid_sphn; #define DO_RTDG \ CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; \ + CUR.func_round_sphn = (TT_Round_Func)Round_To_Double_Grid_sphn; #define DO_RUTG \ CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; \ + CUR.func_round_sphn = (TT_Round_Func)Round_Up_To_Grid_sphn; #define DO_RDTG \ CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; \ + CUR.func_round_sphn = (TT_Round_Func)Round_Down_To_Grid_sphn; #define DO_ROFF \ CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; + CUR.func_round = (TT_Round_Func)Round_None; \ + CUR.func_round_sphn = (TT_Round_Func)Round_None; #define DO_SROUND \ SET_SuperRound( 0x4000, args[0] ); \ CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; + CUR.func_round = (TT_Round_Func)Round_Super; \ + CUR.func_round_sphn = (TT_Round_Func)Round_Super_sphn; #define DO_S45ROUND \ SET_SuperRound( 0x2D41, args[0] ); \ CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; + CUR.func_round = (TT_Round_Func)Round_Super_45; \ + CUR.func_round_sphn = (TT_Round_Func)Round_Super_45_sphn; #define DO_SLOOP \ @@ -3296,7 +3467,9 @@ args[0] = 0; \ } \ else \ - args[0] = CUR.storage[I]; \ + /* Subpixel Hinting- Typeman Dstroke and Istroke, Vacuform Rounds */ \ + if (CUR.subpixel && (I == 24 || I == 22 || I == 8)) args[0] = 0; \ + else args[0] = CUR.storage[I]; \ } @@ -5153,6 +5326,9 @@ } } + /* Subpixel Hinting - Type 2 Vacuform Rounds - Arial Narrow */ + if (CUR.subpixel && FT_ABS(D) == 64) D += 1; + args[0] = D; } @@ -5632,14 +5808,15 @@ return; } #endif - +if (CUR.skip_x == 0){ if ( CUR.GS.freeVector.x != 0 ) { CUR.zp2.cur[point].x += dx; if ( touch ) CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } - +} +if (CUR.skip_y == 0){ if ( CUR.GS.freeVector.y != 0 ) { CUR.zp2.cur[point].y += dy; @@ -5647,7 +5824,7 @@ CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } - + } /*************************************************************************/ /* */ @@ -5862,7 +6039,18 @@ } } else - MOVE_Zp2_Point( point, dx, dy, TRUE ); + { + /* If freedom vector is Y, and point is touched, continue */ + if ( CUR.subpixel && CUR.GS.freeVector.y != 0 && CUR.iup_called == 0 + && ( ( CUR.pts.tags[point] & FT_CURVE_TAG_TOUCH_X ) != 0 + || ( CUR.pts.tags[point] & FT_CURVE_TAG_TOUCH_Y ) != 0 ) + ){ + MOVE_Zp2_Point( point, dx, dy, TRUE ); } + + else if ( !CUR.subpixel || CUR.is_composite ) + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + } CUR.GS.loop--; } @@ -5907,6 +6095,15 @@ distance = CUR_Func_project( CUR.zp1.cur + point, CUR.zp0.cur + CUR.GS.rp0 ); + /* Subpixel Hinting - make MSIRP respect CVT cutin */ + /* Fixes "k" issue with Arial */ + /* Using 0 instead of CUR.GS.control_value_cutin/grid_factor */ + /* fixes Helvetica Neue */ + if (CUR.subpixel && CUR.GS.freeVector.x != 0 + && FT_ABS(distance - args[1]) >= 0 ) + distance = args[1]; + + CUR_Func_move( &CUR.zp1, point, args[1] - distance ); CUR.GS.rp1 = CUR.GS.rp0; @@ -5945,7 +6142,10 @@ if ( ( CUR.opcode & 1 ) != 0 ) { cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); - distance = CUR_Func_round( cur_dist, + if (!CUR.subpixel || CUR.GS.freeVector.x == 0) + distance = CUR_Func_round( cur_dist, + CUR.tt_metrics.compensations[0] ) - cur_dist; + else distance = CUR_Func_round_sphn( cur_dist, CUR.tt_metrics.compensations[0] ) - cur_dist; } else @@ -6019,10 +6219,20 @@ if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ { - if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) - distance = org_dist; - distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); + if ( !CUR.subpixel || CUR.GS.freeVector.x == 0 ) + { + if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin) + distance = org_dist; + distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); + } + else + { + if ( FT_ABS( distance - org_dist ) + > CUR.GS.control_value_cutin / CUR.grid_factor) + distance = org_dist; + distance = CUR_Func_round_sphn( distance, CUR.tt_metrics.compensations[0] ); + } } CUR_Func_move( &CUR.zp0, point, distance - org_dist ); @@ -6106,9 +6316,15 @@ /* round flag */ if ( ( CUR.opcode & 4 ) != 0 ) - distance = CUR_Func_round( + { + if ( !CUR.subpixel || CUR.GS.freeVector.x == 0 ) + distance = CUR_Func_round( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + else distance = CUR_Func_round_sphn( org_dist, CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } else distance = ROUND_None( org_dist, @@ -6116,17 +6332,36 @@ /* minimum distance flag */ - if ( ( CUR.opcode & 8 ) != 0 ) - { - if ( org_dist >= 0 ) + /* Use 2/3 in x direction. Better results than documented 1/2 */ + if (CUR.GS.freeVector.x != 0 && CUR.subpixel ){ + if ( ( CUR.opcode & 8 ) != 0 ) { - if ( distance < CUR.GS.minimum_distance ) - distance = CUR.GS.minimum_distance; + if ( org_dist >= 0 ) + { + if ( distance < 2*CUR.GS.minimum_distance/3 ) + distance = 2*CUR.GS.minimum_distance/3; + } + else + { + if ( distance > -CUR.GS.minimum_distance/2 ) + distance = -CUR.GS.minimum_distance/2; + } } - else + } + else + { + if ( ( CUR.opcode & 8 ) != 0 ) { - if ( distance > -CUR.GS.minimum_distance ) - distance = -CUR.GS.minimum_distance; + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } } } @@ -6162,7 +6397,6 @@ cur_dist, org_dist; - point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( args[1] + 1 ); @@ -6223,41 +6457,84 @@ /* control value cutin and round */ - if ( ( CUR.opcode & 4 ) != 0 ) + if ( (!CUR.subpixel && ( CUR.opcode & 4 ) != 0) || CUR.subpixel ) { /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ /* refer to the same zone. */ - if ( CUR.GS.gep0 == CUR.GS.gep1 ) - if ( FT_ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) - cvt_dist = org_dist; + if ( (!CUR.subpixel && CUR.GS.gep0 == CUR.GS.gep1) || CUR.subpixel ) + { + if ( (CUR.subpixel && CUR.GS.freeVector.x == 0) || !CUR.subpixel ) + { + if ( FT_ABS(cvt_dist - org_dist) >= CUR.GS.control_value_cutin ) + cvt_dist = org_dist; + + distance = CUR_Func_round( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } - distance = CUR_Func_round( + else if (CUR.subpixel) + { + if ( FT_ABS(cvt_dist - org_dist) + >= CUR.GS.control_value_cutin / CUR.grid_factor ) + cvt_dist = org_dist; + + distance = CUR_Func_round_sphn( cvt_dist, CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } + + /* This fixes subpixel hinting italics (Verdana) but may be hacky */ + else + distance = ROUND_None( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } } - else + else if (!CUR.subpixel){ distance = ROUND_None( cvt_dist, CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } /* minimum distance test */ - - if ( ( CUR.opcode & 8 ) != 0 ) + if (CUR.GS.freeVector.x != 0 && CUR.subpixel) { - if ( org_dist >= 0 ) + if ( ( CUR.opcode & 8 ) != 0 ) { - if ( distance < CUR.GS.minimum_distance ) - distance = CUR.GS.minimum_distance; + if ( org_dist >= 0 ) + { + if ( distance < 2 * CUR.GS.minimum_distance / 3 ) + distance = 2 * CUR.GS.minimum_distance / 3; + } + else + { + if ( distance > -2 * CUR.GS.minimum_distance / 3 ) + distance = -2 * CUR.GS.minimum_distance / 3; + } + } - else + } + else + { + if ( ( CUR.opcode & 8 ) != 0 ) { - if ( distance > -CUR.GS.minimum_distance ) - distance = -CUR.GS.minimum_distance; + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } } + } - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); CUR.GS.rp1 = CUR.GS.rp0; @@ -6726,6 +7003,7 @@ FT_UNUSED_ARG; + CUR.iup_called = 1; /* ignore empty outlines */ if ( CUR.pts.n_contours == 0 ) @@ -6820,7 +7098,7 @@ FT_UShort A; FT_ULong C; FT_Long B; - + FT_Byte orig_round_state; #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING /* Delta hinting is covered by US Patent 5159668. */ @@ -6890,7 +7168,28 @@ B++; B = B * 64 / ( 1L << CUR.GS.delta_shift ); - CUR_Func_move( &CUR.zp0, A, B ); + /* This dirty hack fixes subpixel y-artifacts in trebuchet, */ + /* verdana bold, ms sans serif, due to bi-level deltas in y */ + /* direction, but breaks some glyphs (trebuchet e, times e, */ + /* arial bold S. Needs work. */ + + if (0 && CUR.GS.freeVector.y != 0 && CUR.subpixel ) + { + orig_round_state= CUR.GS.round_state; + COMPUTE_Round( TT_Round_Down_To_Grid ); + B = CUR_Func_round( B, CUR.tt_metrics.compensations[0] ); + COMPUTE_Round( orig_round_state ); + } + + /* Only allow deltas under certain conditions */ + if ( CUR.subpixel && CUR.GS.freeVector.y != 0 && CUR.iup_called == 0 + && (( CUR.pts.tags[A] & FT_CURVE_TAG_TOUCH_X ) != 0 + || ( CUR.pts.tags[A] & FT_CURVE_TAG_TOUCH_Y ) != 0 ) + ){ + CUR_Func_move(&CUR.zp0, A, B); } + else if ( !CUR.subpixel || CUR.is_composite ) + CUR_Func_move(&CUR.zp0, A, B); + } } else @@ -7015,9 +7314,9 @@ K = 0; - /* We return MS rasterizer version 1.7 for the font scaler. */ + /* We return MS rasterizer version 1.8 for the font scaler. */ if ( ( args[0] & 1 ) != 0 ) - K = 35; + K = 37; /* Has the glyph been rotated? */ if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) @@ -7031,6 +7330,27 @@ if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) K |= 1 << 12; + /* Are we hinting for subpixel? */ + if ( ( args[0] & 64 ) != 0 && CUR.subpixel ) + K |= 1 << 13; + + /* Are we hinting for compatible_widths? */ + if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ){ + K |= 1 << 14; + CUR.skip_x = 0; + } + else CUR.skip_x = 1; + CUR.skip_y = 0; + + /* Are we hinting for symmetrical_smoothing? */ + /*if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )*/ + /* Forcibly setting to 0 fixes PALATINO */ + K |= 0 << 15; + + /* Are we hinting for bgr? */ + if ( ( args[0] & 512 ) != 0 && CUR.bgr ) + K |= 1 << 16; + args[0] = K; } @@ -7404,6 +7724,13 @@ #ifdef TT_CONFIG_OPTION_STATIC_RASTER cur = *exc; #endif + if (CUR.subpixel) + /* 1/32 of a pixel in y direction */ + CUR.grid_factor = 32; + else + CUR.grid_factor = 1; + + CUR.iup_called = 0; /* set CVT functions */ CUR.tt_metrics.ratio = 0; diff -Naur freetype-2.4.0-orig//src/truetype/ttinterp.h freetype-2.4.0/src/truetype/ttinterp.h --- freetype-2.4.0-orig//src/truetype/ttinterp.h 2010-05-20 19:04:47.000000000 +0700 +++ freetype-2.4.0/src/truetype/ttinterp.h 2010-07-14 17:34:15.000000000 +0700 @@ -203,6 +203,7 @@ FT_Long F_dot_P; /* dot product of freedom and projection */ /* vectors */ TT_Round_Func func_round; /* current rounding function */ + TT_Round_Func func_round_sphn; /* subpixel rounding fuction */ TT_Project_Func func_project, /* current projection function */ func_dualproj, /* current dual proj. function */ @@ -215,7 +216,16 @@ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - FT_Bool grayscale; /* are we hinting for grayscale? */ + FT_Bool grayscale; /* are we hinting for grayscale? */ + FT_Bool subpixel; /* are we hinting for subpixel? */ + FT_Bool compatible_widths; /* are we using compatible widths?*/ + FT_Bool symmetrical_smoothing; /* symmetrical_smoothing ? */ + FT_Bool bgr; /* are we using bgr, not rgb? */ + + FT_Bool grid_factor; /* freedom vector resol (1 < 32) */ + FT_Bool iup_called; /* IUP[] been called for this glyph? */ + FT_Bool skip_x; /* Skip all x moves? */ + FT_Bool skip_y; /* Skip all y moves? */ } TT_ExecContextRec;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor