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