summaryrefslogtreecommitdiff
path: root/src/util/fontxlfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/fontxlfd.c')
-rw-r--r--src/util/fontxlfd.c144
1 files changed, 95 insertions, 49 deletions
diff --git a/src/util/fontxlfd.c b/src/util/fontxlfd.c
index f1245f6..3a2c93d 100644
--- a/src/util/fontxlfd.c
+++ b/src/util/fontxlfd.c
@@ -27,6 +27,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
+/* $XFree86: xc/lib/font/util/fontxlfd.c,v 3.15 2002/05/31 18:45:50 dawes Exp $ */
/*
* Author: Keith Packard, MIT X Consortium
@@ -35,12 +36,11 @@ from The Open Group.
#include "fontmisc.h"
#include "fontstruct.h"
#include "fontxlfd.h"
+#include "fontutil.h"
#include <X11/Xos.h>
#include <math.h>
-#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
-#endif
-#if defined(X_NOT_STDC_ENV) || (defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV))
+#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV)
#define NO_LOCALE
#endif
#ifndef NO_LOCALE
@@ -50,9 +50,7 @@ from The Open Group.
#include <stdio.h> /* for sprintf() */
static char *
-GetInt(ptr, val)
- char *ptr;
- int *val;
+GetInt(char *ptr, int *val)
{
if (*ptr == '*') {
*val = -1;
@@ -75,9 +73,7 @@ static struct lconv *locale = 0;
static char *radix = ".", *plus = "+", *minus = "-";
static char *
-readreal(ptr, result)
-char *ptr;
-double *result;
+readreal(char *ptr, double *result)
{
char buffer[80], *p1, *p2;
@@ -112,26 +108,13 @@ double *result;
*p2 = 0;
/* Now we have something that strtod() can interpret... do it. */
-#ifndef X_NOT_STDC_ENV
*result = strtod(buffer, &p1);
/* Return NULL if failure, pointer past number if success */
return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer));
-#else
- for (p1 = buffer; isspace(*p1); p1++)
- ;
- if (sscanf(p1, "%lf", result) != 1)
- return (char *)0;
- while (!isspace(*p1))
- p1++;
- return ptr + (p1 - buffer);
-#endif
}
static char *
-xlfd_double_to_text(value, buffer, space_required)
-double value;
-char *buffer;
-int space_required;
+xlfd_double_to_text(double value, char *buffer, int space_required)
{
char formatbuf[40];
register char *p1;
@@ -204,24 +187,95 @@ int space_required;
}
double
-xlfd_round_double(x)
-double x;
+xlfd_round_double(double x)
{
- /* Utility for XLFD users to round numbers to XLFD_NDIGITS
- significant digits. How do you round to n significant digits on
- a binary machine? Let printf() do it for you. */
- char formatbuf[40], buffer[40];
-
- sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS);
- sprintf(buffer, formatbuf, x);
- return atof(buffer);
+ /* Utility for XLFD users to round numbers to XLFD_NDIGITS
+ 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(__x86_64__) || defined(__x86_64)
+#if !defined(__UNIXOS2__)
+#include <float.h>
+
+/* if we have IEEE 754 fp, we can round to binary digits... */
+
+#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53)
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402
+#endif
+
+/* convert # of decimal digits to # of binary digits */
+#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS * M_LN10 / M_LN2 + 0.5))
+
+ union conv_d {
+ double d;
+ unsigned char b[8];
+ } d;
+ int i,j,k,d_exp;
+
+ if (x == 0)
+ return 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) {
+
+ /*
+ * 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);
+
+ 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;
+ if (k & 0x100) j = 1;
+ else break;
+ }
+ if ((i==7) && ((d.b[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);
+ }
+
+ 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;
+
+ return d.d;
+ }
+ else
+#endif
+#endif /* !__UNIXOS2__ */
+#endif /* i386 || __i386__ */
+ {
+ /*
+ * If not IEEE 754: Let printf() do it for you.
+ */
+
+ char formatbuf[40], buffer[40];
+
+ sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS);
+ sprintf(buffer, formatbuf, x);
+ return atof(buffer);
+ }
}
static char *
-GetMatrix(ptr, vals, which)
-char *ptr;
-FontScalablePtr vals;
-int which;
+GetMatrix(char *ptr, FontScalablePtr vals, int which)
{
double *matrix;
@@ -298,10 +352,8 @@ int which;
}
-static void append_ranges(fname, nranges, ranges)
-char *fname;
-int nranges;
-fsRange *ranges;
+static void
+append_ranges(char *fname, int nranges, fsRange *ranges)
{
if (nranges)
{
@@ -325,10 +377,7 @@ fsRange *ranges;
}
Bool
-FontParseXLFDName(fname, vals, subst)
- char *fname;
- FontScalablePtr vals;
- int subst;
+FontParseXLFDName(char *fname, FontScalablePtr vals, int subst)
{
register char *ptr;
register char *ptr1,
@@ -532,15 +581,12 @@ FontParseXLFDName(fname, vals, subst)
return TRUE;
}
-fsRange *FontParseRanges(name, nranges)
-char *name;
-int *nranges;
+fsRange *FontParseRanges(char *name, int *nranges)
{
int n;
unsigned long l;
char *p1, *p2;
fsRange *result = (fsRange *)0;
- extern int add_range();
name = strchr(name, '-');
for (n = 1; name && n < 14; n++)