From 360988627257871592a70bfcc1b7c509d053f74d Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@linux.ie>
Date: Wed, 28 Jan 2009 21:41:44 +1000
Subject: [PATCH] xlfd: use the non-printf rounding method on all architectures.

On a RHEL4 ppc system, we were seeing different values returned from
this function on x86 and ppc, leading to misrendered fonts on the ppc machine.

Reimplementing the little endian code for big-endian, fixes the rendering for
me.

So make the code endian aware, and really everyone should have IEEE754,
I've singled out the VAX, which may end up with the same bug, but someone
else can care.
---
 configure.ac        |    3 +++
 src/util/fontxlfd.c |   32 ++++++++++++++++----------------
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/configure.ac b/configure.ac
index ab3b121..4d88232 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,9 @@ dnl If the first PKG_CHECK_MODULES appears inside a conditional, pkg-config
 dnl must first be located explicitly.
 PKG_PROG_PKG_CONFIG
 
+# Check endian
+AC_C_BIGENDIAN
+
 # Look for headers
 AC_CHECK_HEADERS([endian.h poll.h sys/poll.h])
 AC_CHECK_FUNCS([poll])
diff --git a/src/util/fontxlfd.c b/src/util/fontxlfd.c
index 4625540..58eaba2 100644
--- a/src/util/fontxlfd.c
+++ b/src/util/fontxlfd.c
@@ -196,12 +196,7 @@ xlfd_round_double(double x)
       significant digits.  How do you round to n significant digits on
       a binary machine?  */
 
-#if defined(i386) || defined(__i386__) || \
-    defined(ia64) || defined(__ia64__) || \
-    defined(__alpha__) || defined(__alpha) || \
-    defined(__hppa__) || \
-    defined(__amd64__) || defined(__amd64) || \
-    defined(sgi)
+#ifndef __vax__ 
 #include <float.h>
 
 /* if we have IEEE 754 fp, we can round to binary digits... */
@@ -229,40 +224,45 @@ xlfd_round_double(double x)
 
    /* do minor sanity check for IEEE 754 fp and correct byte order */
    d.d = 1.0;
-   if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) {
+#ifdef WORDS_BIGENDIAN
+#define GET_BYTE(d, i) (d.b[7-i])
+#else
+#define GET_BYTE(d, i) (d.b[i])
+#endif
+   if (sizeof(double) == 8 && GET_BYTE(d, 7) == 0x3f && GET_BYTE(d, 6) == 0xf0) {
 
       /*
        * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits
        */
 
       d.d = x;
-      d_exp = (d.b[7] << 4) | (d.b[6] >> 4);
+      d_exp = (GET_BYTE(d, 7) << 4) | (GET_BYTE(d, 6) >> 4);
 
       i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
       j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
       for (; i<7; i++) {
-	 k = d.b[i] + j;
-	 d.b[i] = k;
+	 k = GET_BYTE(d, i) + j;
+	 GET_BYTE(d, i) = k;
 	 if (k & 0x100) j = 1;
 	 else break;
       }
-      if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) {
+      if ((i==7) && ((GET_BYTE(d, 6) & 0xf0) != ((d_exp<<4) & 0xf0))) {
 	 /* mantissa overflow: increment exponent */
 	 d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1);
-	 d.b[7] = d_exp >> 4;
-	 d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4);
+	 GET_BYTE(d, 7) = d_exp >> 4;
+	 GET_BYTE(d, 6) = (GET_BYTE(d, 6) & 0x0f) | (d_exp << 4);
       }
 
       i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
       j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
-      d.b[i] &= ~(j-1);
-      for (;--i>=0;) d.b[i] = 0;
+      GET_BYTE(d, i) &= ~(j-1);
+      for (;--i>=0;) GET_BYTE(d, i) = 0;
 
       return d.d;
    }
    else
 #endif
-#endif /* i386 || __i386__ */
+#endif /* vax */
     {
 	/*
 	 * If not IEEE 754:  Let printf() do it for you.
-- 
1.6.0.6

