fontxlfd.c revision 23a0898a
123a0898aSmrg/* $Xorg: fontxlfd.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ 223a0898aSmrg 323a0898aSmrg/* 423a0898aSmrg 523a0898aSmrgCopyright 1990, 1998 The Open Group 623a0898aSmrg 723a0898aSmrgPermission to use, copy, modify, distribute, and sell this software and its 823a0898aSmrgdocumentation for any purpose is hereby granted without fee, provided that 923a0898aSmrgthe above copyright notice appear in all copies and that both that 1023a0898aSmrgcopyright notice and this permission notice appear in supporting 1123a0898aSmrgdocumentation. 1223a0898aSmrg 1323a0898aSmrgThe above copyright notice and this permission notice shall be included 1423a0898aSmrgin all copies or substantial portions of the Software. 1523a0898aSmrg 1623a0898aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1723a0898aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1823a0898aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1923a0898aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 2023a0898aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2123a0898aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2223a0898aSmrgOTHER DEALINGS IN THE SOFTWARE. 2323a0898aSmrg 2423a0898aSmrgExcept as contained in this notice, the name of The Open Group shall 2523a0898aSmrgnot be used in advertising or otherwise to promote the sale, use or 2623a0898aSmrgother dealings in this Software without prior written authorization 2723a0898aSmrgfrom The Open Group. 2823a0898aSmrg 2923a0898aSmrg*/ 3023a0898aSmrg/* $XFree86: xc/lib/font/util/fontxlfd.c,v 3.16tsi Exp $ */ 3123a0898aSmrg 3223a0898aSmrg/* 3323a0898aSmrg * Author: Keith Packard, MIT X Consortium 3423a0898aSmrg */ 3523a0898aSmrg 3623a0898aSmrg#ifdef HAVE_CONFIG_H 3723a0898aSmrg#include <config.h> 3823a0898aSmrg#endif 3923a0898aSmrg#include <X11/fonts/fontmisc.h> 4023a0898aSmrg#include <X11/fonts/fontstruct.h> 4123a0898aSmrg#include <X11/fonts/fontxlfd.h> 4223a0898aSmrg#include <X11/fonts/fontutil.h> 4323a0898aSmrg#include <X11/Xos.h> 4423a0898aSmrg#include <math.h> 4523a0898aSmrg#include <stdlib.h> 4623a0898aSmrg#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) 4723a0898aSmrg#define NO_LOCALE 4823a0898aSmrg#endif 4923a0898aSmrg#ifndef NO_LOCALE 5023a0898aSmrg#include <locale.h> 5123a0898aSmrg#endif 5223a0898aSmrg#include <ctype.h> 5323a0898aSmrg#include <stdio.h> /* for sprintf() */ 5423a0898aSmrg 5523a0898aSmrgstatic char * 5623a0898aSmrgGetInt(char *ptr, int *val) 5723a0898aSmrg{ 5823a0898aSmrg if (*ptr == '*') { 5923a0898aSmrg *val = -1; 6023a0898aSmrg ptr++; 6123a0898aSmrg } else 6223a0898aSmrg for (*val = 0; *ptr >= '0' && *ptr <= '9';) 6323a0898aSmrg *val = *val * 10 + *ptr++ - '0'; 6423a0898aSmrg if (*ptr == '-') 6523a0898aSmrg return ptr; 6623a0898aSmrg return (char *) 0; 6723a0898aSmrg} 6823a0898aSmrg 6923a0898aSmrg#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8)) 7023a0898aSmrg#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8)) 7123a0898aSmrg 7223a0898aSmrg 7323a0898aSmrg#ifndef NO_LOCALE 7423a0898aSmrgstatic struct lconv *locale = 0; 7523a0898aSmrg#endif 7623a0898aSmrgstatic char *radix = ".", *plus = "+", *minus = "-"; 7723a0898aSmrg 7823a0898aSmrgstatic char * 7923a0898aSmrgreadreal(char *ptr, double *result) 8023a0898aSmrg{ 8123a0898aSmrg char buffer[80], *p1, *p2; 8223a0898aSmrg 8323a0898aSmrg#ifndef NO_LOCALE 8423a0898aSmrg /* Figure out what symbols apply in this locale */ 8523a0898aSmrg 8623a0898aSmrg if (!locale) 8723a0898aSmrg { 8823a0898aSmrg locale = localeconv(); 8923a0898aSmrg if (locale->decimal_point && *locale->decimal_point) 9023a0898aSmrg radix = locale->decimal_point; 9123a0898aSmrg if (locale->positive_sign && *locale->positive_sign) 9223a0898aSmrg plus = locale->positive_sign; 9323a0898aSmrg if (locale->negative_sign && *locale->negative_sign) 9423a0898aSmrg minus = locale->negative_sign; 9523a0898aSmrg } 9623a0898aSmrg#endif 9723a0898aSmrg /* Copy the first 80 chars of ptr into our local buffer, changing 9823a0898aSmrg symbols as needed. */ 9923a0898aSmrg for (p1 = ptr, p2 = buffer; 10023a0898aSmrg *p1 && (p2 - buffer) < sizeof(buffer) - 1; 10123a0898aSmrg p1++, p2++) 10223a0898aSmrg { 10323a0898aSmrg switch(*p1) 10423a0898aSmrg { 10523a0898aSmrg case '~': *p2 = *minus; break; 10623a0898aSmrg case '+': *p2 = *plus; break; 10723a0898aSmrg case '.': *p2 = *radix; break; 10823a0898aSmrg default: *p2 = *p1; 10923a0898aSmrg } 11023a0898aSmrg } 11123a0898aSmrg *p2 = 0; 11223a0898aSmrg 11323a0898aSmrg /* Now we have something that strtod() can interpret... do it. */ 11423a0898aSmrg *result = strtod(buffer, &p1); 11523a0898aSmrg /* Return NULL if failure, pointer past number if success */ 11623a0898aSmrg return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer)); 11723a0898aSmrg} 11823a0898aSmrg 11923a0898aSmrgstatic char * 12023a0898aSmrgxlfd_double_to_text(double value, char *buffer, int space_required) 12123a0898aSmrg{ 12223a0898aSmrg char formatbuf[40]; 12323a0898aSmrg register char *p1; 12423a0898aSmrg int ndigits, exponent; 12523a0898aSmrg 12623a0898aSmrg#ifndef NO_LOCALE 12723a0898aSmrg if (!locale) 12823a0898aSmrg { 12923a0898aSmrg locale = localeconv(); 13023a0898aSmrg if (locale->decimal_point && *locale->decimal_point) 13123a0898aSmrg radix = locale->decimal_point; 13223a0898aSmrg if (locale->positive_sign && *locale->positive_sign) 13323a0898aSmrg plus = locale->positive_sign; 13423a0898aSmrg if (locale->negative_sign && *locale->negative_sign) 13523a0898aSmrg minus = locale->negative_sign; 13623a0898aSmrg } 13723a0898aSmrg#endif 13823a0898aSmrg /* Compute a format to use to render the number */ 13923a0898aSmrg sprintf(formatbuf, "%%.%dle", XLFD_NDIGITS); 14023a0898aSmrg 14123a0898aSmrg if (space_required) 14223a0898aSmrg *buffer++ = ' '; 14323a0898aSmrg 14423a0898aSmrg /* Render the number using printf's idea of formatting */ 14523a0898aSmrg sprintf(buffer, formatbuf, value); 14623a0898aSmrg 14723a0898aSmrg /* Find and read the exponent value */ 14823a0898aSmrg for (p1 = buffer + strlen(buffer); 14923a0898aSmrg *p1-- != 'e' && p1[1] != 'E';); 15023a0898aSmrg exponent = atoi(p1 + 2); 15123a0898aSmrg if (value == 0.0) exponent = 0; 15223a0898aSmrg 15323a0898aSmrg /* Figure out how many digits are significant */ 15423a0898aSmrg while (p1 >= buffer && (!isdigit(*p1) || *p1 == '0')) p1--; 15523a0898aSmrg ndigits = 0; 15623a0898aSmrg while (p1 >= buffer) if (isdigit(*p1--)) ndigits++; 15723a0898aSmrg 15823a0898aSmrg /* Figure out notation to use */ 15923a0898aSmrg if (exponent >= XLFD_NDIGITS || ndigits - exponent > XLFD_NDIGITS + 1) 16023a0898aSmrg { 16123a0898aSmrg /* Scientific */ 16223a0898aSmrg sprintf(formatbuf, "%%.%dle", ndigits - 1); 16323a0898aSmrg sprintf(buffer, formatbuf, value); 16423a0898aSmrg } 16523a0898aSmrg else 16623a0898aSmrg { 16723a0898aSmrg /* Fixed */ 16823a0898aSmrg ndigits -= exponent + 1; 16923a0898aSmrg if (ndigits < 0) ndigits = 0; 17023a0898aSmrg sprintf(formatbuf, "%%.%dlf", ndigits); 17123a0898aSmrg sprintf(buffer, formatbuf, value); 17223a0898aSmrg if (exponent < 0) 17323a0898aSmrg { 17423a0898aSmrg p1 = buffer; 17523a0898aSmrg while (*p1 && *p1 != '0') p1++; 17623a0898aSmrg while (*p1++) p1[-1] = *p1; 17723a0898aSmrg } 17823a0898aSmrg } 17923a0898aSmrg 18023a0898aSmrg /* Last step, convert the locale-specific sign and radix characters 18123a0898aSmrg to our own. */ 18223a0898aSmrg for (p1 = buffer; *p1; p1++) 18323a0898aSmrg { 18423a0898aSmrg if (*p1 == *minus) *p1 = '~'; 18523a0898aSmrg else if (*p1 == *plus) *p1 = '+'; 18623a0898aSmrg else if (*p1 == *radix) *p1 = '.'; 18723a0898aSmrg } 18823a0898aSmrg 18923a0898aSmrg return buffer - space_required; 19023a0898aSmrg} 19123a0898aSmrg 19223a0898aSmrgdouble 19323a0898aSmrgxlfd_round_double(double x) 19423a0898aSmrg{ 19523a0898aSmrg /* Utility for XLFD users to round numbers to XLFD_NDIGITS 19623a0898aSmrg significant digits. How do you round to n significant digits on 19723a0898aSmrg a binary machine? */ 19823a0898aSmrg 19923a0898aSmrg#if defined(i386) || defined(__i386__) || \ 20023a0898aSmrg defined(ia64) || defined(__ia64__) || \ 20123a0898aSmrg defined(__alpha__) || defined(__alpha) || \ 20223a0898aSmrg defined(__hppa__) || \ 20323a0898aSmrg defined(__amd64__) || defined(__amd64) || \ 20423a0898aSmrg defined(sgi) 20523a0898aSmrg#if !defined(__UNIXOS2__) 20623a0898aSmrg#include <float.h> 20723a0898aSmrg 20823a0898aSmrg/* if we have IEEE 754 fp, we can round to binary digits... */ 20923a0898aSmrg 21023a0898aSmrg#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53) 21123a0898aSmrg 21223a0898aSmrg#ifndef M_LN2 21323a0898aSmrg#define M_LN2 0.69314718055994530942 21423a0898aSmrg#endif 21523a0898aSmrg#ifndef M_LN10 21623a0898aSmrg#define M_LN10 2.30258509299404568402 21723a0898aSmrg#endif 21823a0898aSmrg 21923a0898aSmrg/* convert # of decimal digits to # of binary digits */ 22023a0898aSmrg#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS * M_LN10 / M_LN2 + 0.5)) 22123a0898aSmrg 22223a0898aSmrg union conv_d { 22323a0898aSmrg double d; 22423a0898aSmrg unsigned char b[8]; 22523a0898aSmrg } d; 22623a0898aSmrg int i,j,k,d_exp; 22723a0898aSmrg 22823a0898aSmrg if (x == 0) 22923a0898aSmrg return x; 23023a0898aSmrg 23123a0898aSmrg /* do minor sanity check for IEEE 754 fp and correct byte order */ 23223a0898aSmrg d.d = 1.0; 23323a0898aSmrg if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) { 23423a0898aSmrg 23523a0898aSmrg /* 23623a0898aSmrg * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits 23723a0898aSmrg */ 23823a0898aSmrg 23923a0898aSmrg d.d = x; 24023a0898aSmrg d_exp = (d.b[7] << 4) | (d.b[6] >> 4); 24123a0898aSmrg 24223a0898aSmrg i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3; 24323a0898aSmrg j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07); 24423a0898aSmrg for (; i<7; i++) { 24523a0898aSmrg k = d.b[i] + j; 24623a0898aSmrg d.b[i] = k; 24723a0898aSmrg if (k & 0x100) j = 1; 24823a0898aSmrg else break; 24923a0898aSmrg } 25023a0898aSmrg if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) { 25123a0898aSmrg /* mantissa overflow: increment exponent */ 25223a0898aSmrg d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1); 25323a0898aSmrg d.b[7] = d_exp >> 4; 25423a0898aSmrg d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4); 25523a0898aSmrg } 25623a0898aSmrg 25723a0898aSmrg i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3; 25823a0898aSmrg j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07); 25923a0898aSmrg d.b[i] &= ~(j-1); 26023a0898aSmrg for (;--i>=0;) d.b[i] = 0; 26123a0898aSmrg 26223a0898aSmrg return d.d; 26323a0898aSmrg } 26423a0898aSmrg else 26523a0898aSmrg#endif 26623a0898aSmrg#endif /* !__UNIXOS2__ */ 26723a0898aSmrg#endif /* i386 || __i386__ */ 26823a0898aSmrg { 26923a0898aSmrg /* 27023a0898aSmrg * If not IEEE 754: Let printf() do it for you. 27123a0898aSmrg */ 27223a0898aSmrg 27323a0898aSmrg char formatbuf[40], buffer[40]; 27423a0898aSmrg 27523a0898aSmrg sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS); 27623a0898aSmrg sprintf(buffer, formatbuf, x); 27723a0898aSmrg return atof(buffer); 27823a0898aSmrg } 27923a0898aSmrg} 28023a0898aSmrg 28123a0898aSmrgstatic char * 28223a0898aSmrgGetMatrix(char *ptr, FontScalablePtr vals, int which) 28323a0898aSmrg{ 28423a0898aSmrg double *matrix; 28523a0898aSmrg 28623a0898aSmrg if (which == PIXELSIZE_MASK) 28723a0898aSmrg matrix = vals->pixel_matrix; 28823a0898aSmrg else if (which == POINTSIZE_MASK) 28923a0898aSmrg matrix = vals->point_matrix; 29023a0898aSmrg else return (char *)0; 29123a0898aSmrg 29223a0898aSmrg while (isspace(*ptr)) ptr++; 29323a0898aSmrg if (*ptr == '[') 29423a0898aSmrg { 29523a0898aSmrg /* This is a matrix containing real numbers. It would be nice 29623a0898aSmrg to use strtod() or sscanf() to read the numbers, but those 29723a0898aSmrg don't handle '~' for minus and we cannot force them to use a 29823a0898aSmrg "." for the radix. We'll have to do the hard work ourselves 29923a0898aSmrg (in readreal()). */ 30023a0898aSmrg 30123a0898aSmrg if ((ptr = readreal(++ptr, matrix + 0)) && 30223a0898aSmrg (ptr = readreal(ptr, matrix + 1)) && 30323a0898aSmrg (ptr = readreal(ptr, matrix + 2)) && 30423a0898aSmrg (ptr = readreal(ptr, matrix + 3))) 30523a0898aSmrg { 30623a0898aSmrg while (isspace(*ptr)) ptr++; 30723a0898aSmrg if (*ptr != ']') 30823a0898aSmrg ptr = (char *)0; 30923a0898aSmrg else 31023a0898aSmrg { 31123a0898aSmrg ptr++; 31223a0898aSmrg while (isspace(*ptr)) ptr++; 31323a0898aSmrg if (*ptr == '-') 31423a0898aSmrg { 31523a0898aSmrg if (which == POINTSIZE_MASK) 31623a0898aSmrg vals->values_supplied |= POINTSIZE_ARRAY; 31723a0898aSmrg else 31823a0898aSmrg vals->values_supplied |= PIXELSIZE_ARRAY; 31923a0898aSmrg } 32023a0898aSmrg else ptr = (char *)0; 32123a0898aSmrg } 32223a0898aSmrg } 32323a0898aSmrg } 32423a0898aSmrg else 32523a0898aSmrg { 32623a0898aSmrg int value; 32723a0898aSmrg if ((ptr = GetInt(ptr, &value))) 32823a0898aSmrg { 32923a0898aSmrg vals->values_supplied &= ~which; 33023a0898aSmrg if (value > 0) 33123a0898aSmrg { 33223a0898aSmrg matrix[3] = (double)value; 33323a0898aSmrg if (which == POINTSIZE_MASK) 33423a0898aSmrg { 33523a0898aSmrg matrix[3] /= 10.0; 33623a0898aSmrg vals->values_supplied |= POINTSIZE_SCALAR; 33723a0898aSmrg } 33823a0898aSmrg else 33923a0898aSmrg vals->values_supplied |= PIXELSIZE_SCALAR; 34023a0898aSmrg /* If we're concocting the pixelsize array from a scalar, 34123a0898aSmrg we will need to normalize element 0 for the pixel shape. 34223a0898aSmrg This is done in FontFileCompleteXLFD(). */ 34323a0898aSmrg matrix[0] = matrix[3]; 34423a0898aSmrg matrix[1] = matrix[2] = 0.0; 34523a0898aSmrg } 34623a0898aSmrg else if (value < 0) 34723a0898aSmrg { 34823a0898aSmrg if (which == POINTSIZE_MASK) 34923a0898aSmrg vals->values_supplied |= POINTSIZE_WILDCARD; 35023a0898aSmrg else 35123a0898aSmrg vals->values_supplied |= PIXELSIZE_WILDCARD; 35223a0898aSmrg } 35323a0898aSmrg } 35423a0898aSmrg } 35523a0898aSmrg return ptr; 35623a0898aSmrg} 35723a0898aSmrg 35823a0898aSmrg 35923a0898aSmrgstatic void 36023a0898aSmrgappend_ranges(char *fname, int nranges, fsRange *ranges) 36123a0898aSmrg{ 36223a0898aSmrg if (nranges) 36323a0898aSmrg { 36423a0898aSmrg int i; 36523a0898aSmrg 36623a0898aSmrg strcat(fname, "["); 36723a0898aSmrg for (i = 0; i < nranges && strlen(fname) < 1010; i++) 36823a0898aSmrg { 36923a0898aSmrg if (i) strcat(fname, " "); 37023a0898aSmrg sprintf(fname + strlen(fname), "%d", 37123a0898aSmrg minchar(ranges[i])); 37223a0898aSmrg if (ranges[i].min_char_low == 37323a0898aSmrg ranges[i].max_char_low && 37423a0898aSmrg ranges[i].min_char_high == 37523a0898aSmrg ranges[i].max_char_high) continue; 37623a0898aSmrg sprintf(fname + strlen(fname), "_%d", 37723a0898aSmrg maxchar(ranges[i])); 37823a0898aSmrg } 37923a0898aSmrg strcat(fname, "]"); 38023a0898aSmrg } 38123a0898aSmrg} 38223a0898aSmrg 38323a0898aSmrgBool 38423a0898aSmrgFontParseXLFDName(char *fname, FontScalablePtr vals, int subst) 38523a0898aSmrg{ 38623a0898aSmrg register char *ptr; 38723a0898aSmrg register char *ptr1, 38823a0898aSmrg *ptr2, 38923a0898aSmrg *ptr3, 39023a0898aSmrg *ptr4; 39123a0898aSmrg register char *ptr5; 39223a0898aSmrg FontScalableRec tmpvals; 39323a0898aSmrg char replaceChar = '0'; 39423a0898aSmrg char tmpBuf[1024]; 39523a0898aSmrg int spacingLen; 39623a0898aSmrg int l; 39723a0898aSmrg char *p; 39823a0898aSmrg 39923a0898aSmrg bzero(&tmpvals, sizeof(tmpvals)); 40023a0898aSmrg if (subst != FONT_XLFD_REPLACE_VALUE) 40123a0898aSmrg *vals = tmpvals; 40223a0898aSmrg 40323a0898aSmrg if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) || /* fndry */ 40423a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* family_name */ 40523a0898aSmrg !(ptr1 = ptr = strchr(ptr + 1, '-')) || /* weight_name */ 40623a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* slant */ 40723a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* setwidth_name */ 40823a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* add_style_name */ 40923a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* pixel_size */ 41023a0898aSmrg !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK)) || 41123a0898aSmrg !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK)) || 41223a0898aSmrg !(ptr = GetInt(ptr + 1, &tmpvals.x)) || /* resolution_x */ 41323a0898aSmrg !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) || /* resolution_y */ 41423a0898aSmrg !(ptr4 = ptr = strchr(ptr + 1, '-')) || /* spacing */ 41523a0898aSmrg !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */ 41623a0898aSmrg !(ptr = strchr(ptr + 1, '-')) || /* charset_registry */ 41723a0898aSmrg strchr(ptr + 1, '-'))/* charset_encoding */ 41823a0898aSmrg return FALSE; 41923a0898aSmrg 42023a0898aSmrg /* Lop off HP charset subsetting enhancement. Interpreting this 42123a0898aSmrg field requires allocating some space in which to return the 42223a0898aSmrg results. So, to prevent memory leaks, this procedure will simply 42323a0898aSmrg lop off and ignore charset subsetting, and initialize the 42423a0898aSmrg relevant vals fields to zero. It's up to the caller to make its 42523a0898aSmrg own call to FontParseRanges() if it's interested in the charset 42623a0898aSmrg subsetting. */ 42723a0898aSmrg 42823a0898aSmrg if (subst != FONT_XLFD_REPLACE_NONE && 42923a0898aSmrg (p = strchr(strrchr(fname, '-'), '['))) 43023a0898aSmrg { 43123a0898aSmrg tmpvals.values_supplied |= CHARSUBSET_SPECIFIED; 43223a0898aSmrg *p = '\0'; 43323a0898aSmrg } 43423a0898aSmrg 43523a0898aSmrg /* Fill in deprecated fields for the benefit of rasterizers that care 43623a0898aSmrg about them. */ 43723a0898aSmrg tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ? 43823a0898aSmrg (int)(tmpvals.pixel_matrix[3] + .5) : 43923a0898aSmrg (int)(tmpvals.pixel_matrix[3] - .5); 44023a0898aSmrg tmpvals.point = (tmpvals.point_matrix[3] >= 0) ? 44123a0898aSmrg (int)(tmpvals.point_matrix[3] * 10 + .5) : 44223a0898aSmrg (int)(tmpvals.point_matrix[3] * 10 - .5); 44323a0898aSmrg 44423a0898aSmrg spacingLen = ptr4 - ptr3 + 1; 44523a0898aSmrg 44623a0898aSmrg switch (subst) { 44723a0898aSmrg case FONT_XLFD_REPLACE_NONE: 44823a0898aSmrg *vals = tmpvals; 44923a0898aSmrg break; 45023a0898aSmrg case FONT_XLFD_REPLACE_STAR: 45123a0898aSmrg replaceChar = '*'; 45223a0898aSmrg case FONT_XLFD_REPLACE_ZERO: 45323a0898aSmrg strcpy(tmpBuf, ptr2); 45423a0898aSmrg ptr5 = tmpBuf + (ptr5 - ptr2); 45523a0898aSmrg ptr3 = tmpBuf + (ptr3 - ptr2); 45623a0898aSmrg ptr2 = tmpBuf; 45723a0898aSmrg ptr = ptr1 + 1; 45823a0898aSmrg 45923a0898aSmrg ptr = strchr(ptr, '-') + 1; /* skip weight */ 46023a0898aSmrg ptr = strchr(ptr, '-') + 1; /* skip slant */ 46123a0898aSmrg ptr = strchr(ptr, '-') + 1; /* skip setwidth_name */ 46223a0898aSmrg ptr = strchr(ptr, '-') + 1; /* skip add_style_name */ 46323a0898aSmrg 46423a0898aSmrg if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024) 46523a0898aSmrg return FALSE; 46623a0898aSmrg *ptr++ = replaceChar; 46723a0898aSmrg *ptr++ = '-'; 46823a0898aSmrg *ptr++ = replaceChar; 46923a0898aSmrg *ptr++ = '-'; 47023a0898aSmrg *ptr++ = '*'; 47123a0898aSmrg *ptr++ = '-'; 47223a0898aSmrg *ptr++ = '*'; 47323a0898aSmrg if (spacingLen > 2) 47423a0898aSmrg { 47523a0898aSmrg memmove(ptr, ptr3, spacingLen); 47623a0898aSmrg ptr += spacingLen; 47723a0898aSmrg } 47823a0898aSmrg else 47923a0898aSmrg { 48023a0898aSmrg *ptr++ = '-'; 48123a0898aSmrg *ptr++ = '*'; 48223a0898aSmrg *ptr++ = '-'; 48323a0898aSmrg } 48423a0898aSmrg *ptr++ = replaceChar; 48523a0898aSmrg strcpy(ptr, ptr5); 48623a0898aSmrg *vals = tmpvals; 48723a0898aSmrg break; 48823a0898aSmrg case FONT_XLFD_REPLACE_VALUE: 48923a0898aSmrg if (vals->values_supplied & PIXELSIZE_MASK) 49023a0898aSmrg { 49123a0898aSmrg tmpvals.values_supplied = 49223a0898aSmrg (tmpvals.values_supplied & ~PIXELSIZE_MASK) | 49323a0898aSmrg (vals->values_supplied & PIXELSIZE_MASK); 49423a0898aSmrg tmpvals.pixel_matrix[0] = vals->pixel_matrix[0]; 49523a0898aSmrg tmpvals.pixel_matrix[1] = vals->pixel_matrix[1]; 49623a0898aSmrg tmpvals.pixel_matrix[2] = vals->pixel_matrix[2]; 49723a0898aSmrg tmpvals.pixel_matrix[3] = vals->pixel_matrix[3]; 49823a0898aSmrg } 49923a0898aSmrg if (vals->values_supplied & POINTSIZE_MASK) 50023a0898aSmrg { 50123a0898aSmrg tmpvals.values_supplied = 50223a0898aSmrg (tmpvals.values_supplied & ~POINTSIZE_MASK) | 50323a0898aSmrg (vals->values_supplied & POINTSIZE_MASK); 50423a0898aSmrg tmpvals.point_matrix[0] = vals->point_matrix[0]; 50523a0898aSmrg tmpvals.point_matrix[1] = vals->point_matrix[1]; 50623a0898aSmrg tmpvals.point_matrix[2] = vals->point_matrix[2]; 50723a0898aSmrg tmpvals.point_matrix[3] = vals->point_matrix[3]; 50823a0898aSmrg } 50923a0898aSmrg if (vals->x >= 0) 51023a0898aSmrg tmpvals.x = vals->x; 51123a0898aSmrg if (vals->y >= 0) 51223a0898aSmrg tmpvals.y = vals->y; 51323a0898aSmrg if (vals->width >= 0) 51423a0898aSmrg tmpvals.width = vals->width; 51523a0898aSmrg else if (vals->width < -1) /* overload: -1 means wildcard */ 51623a0898aSmrg tmpvals.width = -vals->width; 51723a0898aSmrg 51823a0898aSmrg 51923a0898aSmrg p = ptr1 + 1; /* weight field */ 52023a0898aSmrg l = strchr(p, '-') - p; 52123a0898aSmrg sprintf(tmpBuf, "%*.*s", l, l, p); 52223a0898aSmrg 52323a0898aSmrg p += l + 1; /* slant field */ 52423a0898aSmrg l = strchr(p, '-') - p; 52523a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); 52623a0898aSmrg 52723a0898aSmrg p += l + 1; /* setwidth_name */ 52823a0898aSmrg l = strchr(p, '-') - p; 52923a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); 53023a0898aSmrg 53123a0898aSmrg p += l + 1; /* add_style_name field */ 53223a0898aSmrg l = strchr(p, '-') - p; 53323a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); 53423a0898aSmrg 53523a0898aSmrg strcat(tmpBuf, "-"); 53623a0898aSmrg if ((tmpvals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY) 53723a0898aSmrg { 53823a0898aSmrg char buffer[80]; 53923a0898aSmrg strcat(tmpBuf, "["); 54023a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0], 54123a0898aSmrg buffer, 0)); 54223a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1], 54323a0898aSmrg buffer, 1)); 54423a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2], 54523a0898aSmrg buffer, 1)); 54623a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3], 54723a0898aSmrg buffer, 1)); 54823a0898aSmrg strcat(tmpBuf, "]"); 54923a0898aSmrg } 55023a0898aSmrg else 55123a0898aSmrg { 55223a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "%d", 55323a0898aSmrg (int)(tmpvals.pixel_matrix[3] + .5)); 55423a0898aSmrg } 55523a0898aSmrg strcat(tmpBuf, "-"); 55623a0898aSmrg if ((tmpvals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) 55723a0898aSmrg { 55823a0898aSmrg char buffer[80]; 55923a0898aSmrg strcat(tmpBuf, "["); 56023a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0], 56123a0898aSmrg buffer, 0)); 56223a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1], 56323a0898aSmrg buffer, 1)); 56423a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2], 56523a0898aSmrg buffer, 1)); 56623a0898aSmrg strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3], 56723a0898aSmrg buffer, 1)); 56823a0898aSmrg strcat(tmpBuf, "]"); 56923a0898aSmrg } 57023a0898aSmrg else 57123a0898aSmrg { 57223a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "%d", 57323a0898aSmrg (int)(tmpvals.point_matrix[3] * 10.0 + .5)); 57423a0898aSmrg } 57523a0898aSmrg sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s", 57623a0898aSmrg tmpvals.x, tmpvals.y, 57723a0898aSmrg spacingLen, spacingLen, ptr3, tmpvals.width, ptr5); 57823a0898aSmrg strcpy(ptr1 + 1, tmpBuf); 57923a0898aSmrg if ((vals->values_supplied & CHARSUBSET_SPECIFIED) && !vals->nranges) 58023a0898aSmrg strcat(fname, "[]"); 58123a0898aSmrg else 58223a0898aSmrg append_ranges(fname, vals->nranges, vals->ranges); 58323a0898aSmrg break; 58423a0898aSmrg } 58523a0898aSmrg return TRUE; 58623a0898aSmrg} 58723a0898aSmrg 58823a0898aSmrgfsRange *FontParseRanges(char *name, int *nranges) 58923a0898aSmrg{ 59023a0898aSmrg int n; 59123a0898aSmrg unsigned long l; 59223a0898aSmrg char *p1, *p2; 59323a0898aSmrg fsRange *result = (fsRange *)0; 59423a0898aSmrg 59523a0898aSmrg name = strchr(name, '-'); 59623a0898aSmrg for (n = 1; name && n < 14; n++) 59723a0898aSmrg name = strchr(name + 1, '-'); 59823a0898aSmrg 59923a0898aSmrg *nranges = 0; 60023a0898aSmrg if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0; 60123a0898aSmrg p1++; 60223a0898aSmrg 60323a0898aSmrg while (*p1 && *p1 != ']') 60423a0898aSmrg { 60523a0898aSmrg fsRange thisrange; 60623a0898aSmrg 60723a0898aSmrg l = strtol(p1, &p2, 0); 60823a0898aSmrg if (p2 == p1 || l > 0xffff) break; 60923a0898aSmrg thisrange.max_char_low = thisrange.min_char_low = l & 0xff; 61023a0898aSmrg thisrange.max_char_high = thisrange.min_char_high = l >> 8; 61123a0898aSmrg 61223a0898aSmrg p1 = p2; 61323a0898aSmrg if (*p1 == ']' || *p1 == ' ') 61423a0898aSmrg { 61523a0898aSmrg while (*p1 == ' ') p1++; 61623a0898aSmrg if (add_range(&thisrange, nranges, &result, TRUE) != Successful) 61723a0898aSmrg break; 61823a0898aSmrg } 61923a0898aSmrg else if (*p1 == '_') 62023a0898aSmrg { 62123a0898aSmrg l = strtol(++p1, &p2, 0); 62223a0898aSmrg if (p2 == p1 || l > 0xffff) break; 62323a0898aSmrg thisrange.max_char_low = l & 0xff; 62423a0898aSmrg thisrange.max_char_high = l >> 8; 62523a0898aSmrg p1 = p2; 62623a0898aSmrg if (*p1 == ']' || *p1 == ' ') 62723a0898aSmrg { 62823a0898aSmrg while (*p1 == ' ') p1++; 62923a0898aSmrg if (add_range(&thisrange, nranges, &result, TRUE) != Successful) 63023a0898aSmrg break; 63123a0898aSmrg } 63223a0898aSmrg } 63323a0898aSmrg else break; 63423a0898aSmrg } 63523a0898aSmrg 63623a0898aSmrg return result; 63723a0898aSmrg} 638