* 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).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
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;