Commit d156cabcaed41beeed2fb92cff2a72302b726435

Werner Lemberg 2007-12-14T07:48:32

* src/cff/cffparse.c (cff_parse_real): Don't apply `power_ten' division too early; otherwise the most significant digit(s) of the final result are lost as the value is truncated to an integer. This fixes Savannah bug #21794 (where the patch has been posted too).

diff --git a/ChangeLog b/ChangeLog
index 3189f89..ab0f4c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-12-14  Werner Lemberg  <wl@gnu.org>
+
+	* src/cff/cffparse.c (cff_parse_real): Don't apply `power_ten'
+	division too early; otherwise the most significant digit(s) of the
+	final result are lost as the value is truncated to an integer.  This
+	fixes Savannah bug #21794 (where the patch has been posted too).
+
 2007-12-06  Fix  <4d876b82@gmail.com>
 
 	Pass options from one configure script to another as-is (not
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 41af6a3..15e0a5e 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -248,23 +248,6 @@
       power_ten += (FT_Int)exponent;
     }
 
-    /* raise to power of ten if needed */
-    while ( power_ten > 0 )
-    {
-      result = result * 10;
-      num    = num * 10;
-
-      power_ten--;
-    }
-
-    while ( power_ten < 0 )
-    {
-      result  = result / 10;
-      divider = divider * 10;
-
-      power_ten++;
-    }
-
     /* Move the integer part into the high 16 bits. */
     result <<= 16;
 
@@ -272,6 +255,24 @@
     if ( num )
       result |= FT_DivFix( num, divider );
 
+    /* apply power of 10 if needed */
+    if ( power_ten > 0 )
+    {
+      divider = 10; /* actually, this will be used as multiplier here */
+      while ( --power_ten > 0 )
+        divider = divider * 10;
+
+      result = FT_MulFix( divider << 16, result );
+    }
+    else if ( power_ten < 0 )
+    {
+      divider = 10;
+      while ( ++power_ten < 0 )
+        divider = divider * 10;
+
+      result = FT_DivFix( result, divider << 16 );
+    }
+
     if ( sign )
       result = -result;