Commit 5dd9657fe8bc8d70d1119ed0dbd5de1545688239

Alexei Podtelezhnikov 2013-01-02T23:45:14

[base] Use rounding in CORDIC iterations. * src/base/fttrigon.c (ft_trig_pseudo_rotate, ft_trig_pseudo_polarize): Improve accuracy by rounding.

diff --git a/ChangeLog b/ChangeLog
index cd0cca4..e4a5daf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2013-01-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
+	[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  <apodtele@gmail.com>
+
 	[base] Reduce trigonometric algorithms.
 
 	After we get within 45 degrees by means of true 90-degree rotations,
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 4bcc7ab..1ffbb48 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 )