--- freetype-2.4.11/include/freetype/internal/ftcalc.h +++ freetype-2.4.11/include/freetype/internal/ftcalc.h @@ -156,6 +156,13 @@ FT_BEGIN_HEADER FT_Pos out_y ); + /* + * Return the most significant bit index. + */ + FT_BASE( FT_Int ) + FT_MSB( FT_UInt32 z ); + + #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) --- freetype-2.4.11/src/base/ftcalc.c +++ freetype-2.4.11/src/base/ftcalc.c @@ -103,6 +103,42 @@ } + FT_BASE_DEF ( FT_Int ) + FT_MSB( FT_UInt32 z ) + { + FT_Int shift = 0; + + /* determine msb bit index in `shift' */ + if ( z >= ( 1L << 16 ) ) + { + z >>= 16; + shift += 16; + } + if ( z >= ( 1L << 8 ) ) + { + z >>= 8; + shift += 8; + } + if ( z >= ( 1L << 4 ) ) + { + z >>= 4; + shift += 4; + } + if ( z >= ( 1L << 2 ) ) + { + z >>= 2; + shift += 2; + } + if ( z >= ( 1L << 1 ) ) + { + z >>= 1; + shift += 1; + } + + return shift; + } + + #ifdef FT_CONFIG_OPTION_OLD_INTERNALS /* documentation is in ftcalc.h */ --- freetype-2.4.11/src/base/ftoutln.c +++ freetype-2.4.11/src/base/ftoutln.c @@ -930,10 +930,15 @@ v_prev = points[last]; v_cur = v_first; - /* compute the incoming vector and its length */ + /* compute the incoming normalized vector */ in.x = v_cur.x - v_prev.x; in.y = v_cur.y - v_prev.y; l_in = FT_Vector_Length( &in ); + if ( l_in ) + { + in.x = FT_DivFix( in.x, l_in ); + in.y = FT_DivFix( in.y, l_in ); + } for ( n = first; n <= last; n++ ) { @@ -942,20 +947,27 @@ else v_next = v_first; - /* compute the outgoing vector and its length */ + /* compute the outgoing normalized vector */ out.x = v_next.x - v_cur.x; out.y = v_next.y - v_cur.y; l_out = FT_Vector_Length( &out ); + if ( l_out ) + { + out.x = FT_DivFix( out.x, l_out ); + out.y = FT_DivFix( out.y, l_out ); + } - d = l_in * l_out + in.x * out.x + in.y * out.y; + d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); /* shift only if turn is less then ~160 degrees */ - if ( 16 * d > l_in * l_out ) + if ( d > -0xF000L ) { + d = d + 0x10000L; + /* shift components are aligned along bisector */ /* and directed according to the outline orientation. */ - shift.x = l_out * in.y + l_in * out.y; - shift.y = l_out * in.x + l_in * out.x; + shift.x = in.y + out.y; + shift.y = in.x + out.x; if ( orientation == FT_ORIENTATION_TRUETYPE ) shift.x = -shift.x; @@ -963,18 +975,19 @@ shift.y = -shift.y; /* threshold strength to better handle collapsing segments */ - l = FT_MIN( l_in, l_out ); - q = out.x * in.y - out.y * in.x; + q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x ); if ( orientation == FT_ORIENTATION_TRUETYPE ) q = -q; - if ( FT_MulDiv( xstrength, q, l ) < d ) + l = FT_MIN( l_in, l_out ); + + if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) shift.x = FT_MulDiv( shift.x, xstrength, d ); else shift.x = FT_MulDiv( shift.x, l, q ); - if ( FT_MulDiv( ystrength, q, l ) < d ) + if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) shift.y = FT_MulDiv( shift.y, ystrength, d ); else shift.y = FT_MulDiv( shift.y, l, q ); @@ -1002,6 +1015,8 @@ FT_EXPORT_DEF( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ) { + FT_BBox cbox; + FT_Int xshift, yshift; FT_Vector* points; FT_Vector v_prev, v_cur; FT_Int c, n, first; @@ -1016,6 +1031,14 @@ /* cubic or quadratic curves, this test deals with the polygon */ /* only which is spanned up by the control points. */ + FT_Outline_Get_CBox( outline, &cbox ); + + xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; + xshift = FT_MAX( xshift, 0 ); + + yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; + yshift = FT_MAX( yshift, 0 ); + points = outline->points; first = 0; @@ -1029,7 +1052,8 @@ for ( n = first; n <= last; n++ ) { v_cur = points[n]; - area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ); + area += ( ( v_cur.y - v_prev.y ) >> yshift ) * + ( ( v_cur.x + v_prev.x ) >> xshift ); v_prev = v_cur; } --- freetype-2.4.11/src/base/fttrigon.c +++ freetype-2.4.11/src/base/fttrigon.c @@ -104,43 +104,14 @@ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { - FT_Fixed x, y, z; + FT_Fixed x, y; FT_Int shift; x = vec->x; y = vec->y; - z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); - shift = 0; - -#if 1 - /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) - { - z >>= 16; - shift += 16; - } - if ( z >= ( 1L << 8 ) ) - { - z >>= 8; - shift += 8; - } - if ( z >= ( 1L << 4 ) ) - { - z >>= 4; - shift += 4; - } - if ( z >= ( 1L << 2 ) ) - { - z >>= 2; - shift += 2; - } - if ( z >= ( 1L << 1 ) ) - { - z >>= 1; - shift += 1; - } + shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); if ( shift <= 27 ) { @@ -156,33 +127,6 @@ shift = -shift; } -#else /* 0 */ - - if ( z < ( 1L << 27 ) ) - { - do - { - shift++; - z <<= 1; - } while ( z < ( 1L << 27 ) ); - vec->x = x << shift; - vec->y = y << shift; - } - else if ( z > ( 1L << 28 ) ) - { - do - { - shift++; - z >>= 1; - } while ( z > ( 1L << 28 ) ); - - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - -#endif /* 0 */ - return shift; }