diff options
author | Mike DePaulo <mikedep333@gmail.com> | 2015-02-28 07:31:25 -0500 |
---|---|---|
committer | Mike DePaulo <mikedep333@gmail.com> | 2015-02-28 18:11:34 -0500 |
commit | 360fe27b55c93c9c6c86895dbbf5db3efc66cc43 (patch) | |
tree | 01d8b3510d6a36ceba211168268d09658a8aa68b /freetype/src/base/fttrigon.c | |
parent | a769ab7159f0718e189f1aaa8b6a5a046c66c52c (diff) | |
download | vcxsrv-360fe27b55c93c9c6c86895dbbf5db3efc66cc43.tar.gz vcxsrv-360fe27b55c93c9c6c86895dbbf5db3efc66cc43.tar.bz2 vcxsrv-360fe27b55c93c9c6c86895dbbf5db3efc66cc43.zip |
Updated to freetype 2.5.5
Conflicts:
freetype/src/base/ftbdf.c
freetype/src/base/fttype1.c
freetype/src/pfr/pfrobjs.c
Diffstat (limited to 'freetype/src/base/fttrigon.c')
-rw-r--r-- | freetype/src/base/fttrigon.c | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/freetype/src/base/fttrigon.c b/freetype/src/base/fttrigon.c index 9e0af81b0..aa191fd2f 100644 --- a/freetype/src/base/fttrigon.c +++ b/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2005, 2012-2013 by */ +/* Copyright 2001-2005, 2012-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ #define FT_TRIG_MAX_ITERS 23 - static const FT_Fixed + static const FT_Angle ft_trig_arctan_table[] = { 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, @@ -60,17 +60,20 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_Int64 v; + FT_Int s = 1; - s = val; - val = FT_ABS( val ); + if ( val < 0 ) + { + val = -val; + s = -1; + } - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ + val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #else /* !FT_LONG64 */ @@ -79,38 +82,53 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + FT_Int s = 1; + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + if ( val < 0 ) + { + val = -val; + s = -1; + } + lo1 = val & 0x0000FFFFU; + hi1 = val >> 16; + lo2 = FT_TRIG_SCALE & 0x0000FFFFU; + hi2 = FT_TRIG_SCALE >> 16; - s = val; - val = FT_ABS( val ); + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ + hi += i1 >> 16; + i1 = i1 << 16; - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); - lo2 = ( k2 * v2 ) >> 16; - lo3 = FT_MAX( lo1, lo2 ); - lo1 += lo2; + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; + /* Check carry overflow of lo + 0x40000000 */ + lo += 0x40000000UL; + hi += ( lo < 0x40000000UL ); val = (FT_Fixed)hi; - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #endif /* !FT_LONG64 */ + /* undefined and never called for zero vector */ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { @@ -147,7 +165,7 @@ { FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -202,7 +220,7 @@ FT_Angle theta; FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -261,11 +279,12 @@ } } - /* round theta */ + /* round theta to acknowledge its error that mostly comes */ + /* from accumulated rounding errors in the arctan table */ if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); + theta = FT_PAD_ROUND( theta, 16 ); else - theta = -FT_PAD_ROUND( -theta, 32 ); + theta = -FT_PAD_ROUND( -theta, 16 ); vec->x = x; vec->y = theta; @@ -340,6 +359,9 @@ FT_Vector_Unit( FT_Vector* vec, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = FT_TRIG_SCALE >> 8; vec->y = 0; ft_trig_pseudo_rotate( vec, angle ); @@ -366,6 +388,9 @@ FT_Vector v; + if ( !vec ) + return; + v.x = vec->x; v.y = vec->y; @@ -403,6 +428,9 @@ FT_Vector v; + if ( !vec ) + return 0; + v = *vec; /* handle trivial cases */ @@ -439,6 +467,9 @@ FT_Vector v; + if ( !vec || !length || !angle ) + return; + v = *vec; if ( v.x == 0 && v.y == 0 ) @@ -449,8 +480,8 @@ v.x = ft_trig_downscale( v.x ); - *length = ( shift >= 0 ) ? ( v.x >> shift ) - : (FT_Fixed)( (FT_UInt32)v.x << -shift ); + *length = shift >= 0 ? ( v.x >> shift ) + : (FT_Fixed)( (FT_UInt32)v.x << -shift ); *angle = v.y; } @@ -462,6 +493,9 @@ FT_Fixed length, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = length; vec->y = 0; |