diff options
Diffstat (limited to 'src/util/fontxlfd.c')
-rw-r--r-- | src/util/fontxlfd.c | 144 |
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++) |