From 5dd9657fe8bc8d70d1119ed0dbd5de1545688239 Mon Sep 17 00:00:00 2001 From: Alexei Podtelezhnikov Date: Wed, 2 Jan 2013 23:45:14 -0500 Subject: [base] Use rounding in CORDIC iterations. * src/base/fttrigon.c (ft_trig_pseudo_rotate, ft_trig_pseudo_polarize): Improve accuracy by rounding. --- ChangeLog | 7 +++++++ src/base/fttrigon.c | 30 ++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd0cca4d6..e4a5dafc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-01-02 Alexei Podtelezhnikov + + [base] Use rounding in CORDIC iterations. + + * src/base/fttrigon.c (ft_trig_pseudo_rotate, + ft_trig_pseudo_polarize): Improve accuracy by rounding. + 2013-01-02 Alexei Podtelezhnikov [base] Reduce trigonometric algorithms. diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 4bcc7ab37..1ffbb48f4 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -192,7 +192,7 @@ FT_Angle theta ) { FT_Int i; - FT_Fixed x, y, xtemp; + FT_Fixed x, y, xtemp, b; const FT_Fixed *arctanptr; @@ -219,24 +219,23 @@ arctanptr = ft_trig_arctan_table; /* Pseudorotations, with right shifts */ - i = 1; - do + for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) { if ( theta < 0 ) { - xtemp = x + ( y >> i ); - y = y - ( x >> i ); + xtemp = x + ( ( y + b ) >> i ); + y = y - ( ( x + b ) >> i ); x = xtemp; theta += *arctanptr++; } else { - xtemp = x - ( y >> i ); - y = y + ( x >> i ); + xtemp = x - ( ( y + b ) >> i ); + y = y + ( ( x + b ) >> i ); x = xtemp; theta -= *arctanptr++; } - } while ( ++i < FT_TRIG_MAX_ITERS ); + } vec->x = x; vec->y = y; @@ -248,7 +247,7 @@ { FT_Angle theta; FT_Int i; - FT_Fixed x, y, xtemp; + FT_Fixed x, y, xtemp, b; const FT_Fixed *arctanptr; @@ -290,24 +289,23 @@ arctanptr = ft_trig_arctan_table; /* Pseudorotations, with right shifts */ - i = 1; - do + for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) { if ( y > 0 ) { - xtemp = x + ( y >> i ); - y = y - ( x >> i ); + xtemp = x + ( ( y + b ) >> i ); + y = y - ( ( x + b ) >> i ); x = xtemp; theta += *arctanptr++; } else { - xtemp = x - ( y >> i ); - y = y + ( x >> i ); + xtemp = x - ( ( y + b ) >> i ); + y = y + ( ( x + b ) >> i ); x = xtemp; theta -= *arctanptr++; } - } while ( ++i < FT_TRIG_MAX_ITERS ); + } /* round theta */ if ( theta >= 0 ) -- cgit v1.2.1