Commit 081aba390a648fc10c7ae5e169861f2e9aae2aea

Alexei Podtelezhnikov 2013-01-12T22:36:37

[truetype] Kill very old vector normalization hacks. Back in the days, vector length calculations were not very accurate and the vector normalization function, Normalize, had to meticulously correct the errors for long vectors [commit b7ef2b096867]. It was no longer necessary after accurate CORDIC algorithms were adopted, but the code remained. It is time to kill it. * src/truetype/ttinterp.c (Normalize): Remove error compensation. (TT_VecLen): Remove any mention of old less accurate implementation.

diff --git a/ChangeLog b/ChangeLog
index 1d19688..4b35164 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2013-01-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Kill very old vector normalization hacks.
+
+	Back in the days, vector length calculations were not very accurate
+	and the vector normalization function, Normalize, had to meticulously
+	correct the errors for long vectors [commit b7ef2b096867]. It was no
+	longer necessary after accurate CORDIC algorithms were adopted, but
+	the code remained. It is time to kill it.
+
+	* src/truetype/ttinterp.c (Normalize): Remove error compensation.
+	(TT_VecLen): Remove any mention of old less accurate implementation.
+
 2013-01-11  Werner Lemberg  <wl@gnu.org>
 
 	Disable FT_CONFIG_OPTION_OLD_INTERNALS.
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 19fb66c..f862320 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1543,79 +1543,6 @@
 
 
   /* return length of given vector */
-
-#if 0
-
-  static FT_Int32
-  TT_VecLen( FT_Int32  x,
-             FT_Int32  y )
-  {
-    FT_Int32   m, hi1, hi2, hi;
-    FT_UInt32  l, lo1, lo2, lo;
-
-
-    /* compute x*x as 64-bit value */
-    lo = (FT_UInt32)( x & 0xFFFFU );
-    hi = x >> 16;
-
-    l  = lo * lo;
-    m  = hi * lo;
-    hi = hi * hi;
-
-    lo1 = l + (FT_UInt32)( m << 17 );
-    hi1 = hi + ( m >> 15 ) + ( lo1 < l );
-
-    /* compute y*y as 64-bit value */
-    lo = (FT_UInt32)( y & 0xFFFFU );
-    hi = y >> 16;
-
-    l  = lo * lo;
-    m  = hi * lo;
-    hi = hi * hi;
-
-    lo2 = l + (FT_UInt32)( m << 17 );
-    hi2 = hi + ( m >> 15 ) + ( lo2 < l );
-
-    /* add them to get 'x*x+y*y' as 64-bit value */
-    lo = lo1 + lo2;
-    hi = hi1 + hi2 + ( lo < lo1 );
-
-    /* compute the square root of this value */
-    {
-      FT_UInt32  root, rem, test_div;
-      FT_Int     count;
-
-
-      root = 0;
-
-      {
-        rem   = 0;
-        count = 32;
-        do
-        {
-          rem      = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
-          hi       = (  hi << 2 ) | (            lo >> 30 );
-          lo     <<= 2;
-          root   <<= 1;
-          test_div = ( root << 1 ) + 1;
-
-          if ( rem >= test_div )
-          {
-            rem  -= test_div;
-            root += 1;
-          }
-        } while ( --count );
-      }
-
-      return (FT_Int32)root;
-    }
-  }
-
-#else
-
-  /* this version uses FT_Vector_Length which computes the same value */
-  /* much, much faster..                                              */
-  /*                                                                  */
   static FT_F26Dot6
   TT_VecLen( FT_F26Dot6  X,
              FT_F26Dot6  Y )
@@ -1629,8 +1556,6 @@
     return FT_Vector_Length( &v );
   }
 
-#endif
-
 
   /*************************************************************************/
   /*                                                                       */
@@ -2718,7 +2643,6 @@
                       FT_UnitVector*  R )
   {
     FT_F26Dot6  W;
-    FT_Bool     S1, S2;
 
     FT_UNUSED_EXEC;
 
@@ -2728,80 +2652,18 @@
       Vx *= 0x100;
       Vy *= 0x100;
 
-      W = TT_VecLen( Vx, Vy );
-
-      if ( W == 0 )
+      if ( Vx == 0 && Vy == 0 )
       {
         /* XXX: UNDOCUMENTED! It seems that it is possible to try   */
         /*      to normalize the vector (0,0).  Return immediately. */
         return SUCCESS;
       }
-
-      R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
-      R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
-
-      return SUCCESS;
     }
 
     W = TT_VecLen( Vx, Vy );
 
-    Vx = TT_DivFix14( Vx, W );
-    Vy = TT_DivFix14( Vy, W );
-
-    W = Vx * Vx + Vy * Vy;
-
-    /* Now, we want that Sqrt( W ) = 0x4000 */
-    /* Or 0x10000000 <= W < 0x10004000      */
-
-    if ( Vx < 0 )
-    {
-      Vx = -Vx;
-      S1 = TRUE;
-    }
-    else
-      S1 = FALSE;
-
-    if ( Vy < 0 )
-    {
-      Vy = -Vy;
-      S2 = TRUE;
-    }
-    else
-      S2 = FALSE;
-
-    while ( W < 0x10000000L )
-    {
-      /* We need to increase W by a minimal amount */
-      if ( Vx < Vy )
-        Vx++;
-      else
-        Vy++;
-
-      W = Vx * Vx + Vy * Vy;
-    }
-
-    while ( W >= 0x10004000L )
-    {
-      /* We need to decrease W by a minimal amount */
-      if ( Vx < Vy )
-        Vx--;
-      else
-        Vy--;
-
-      W = Vx * Vx + Vy * Vy;
-    }
-
-    /* Note that in various cases, we can only  */
-    /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */
-
-    if ( S1 )
-      Vx = -Vx;
-
-    if ( S2 )
-      Vy = -Vy;
-
-    R->x = (FT_F2Dot14)Vx;   /* Type conversion */
-    R->y = (FT_F2Dot14)Vy;   /* Type conversion */
+    R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
+    R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
 
     return SUCCESS;
   }