|
|
1.1 ! root 1: /* ! 2: * font.c ! 3: * ! 4: * Copyright (c) 1985 Massachusetts Institue of Technology ! 5: * Copyright (c) 1986 Sun Microsystems, Inc. ! 6: * Copyright (c) 1986 David C. Martin, UC Berkeley ! 7: * ! 8: * David C. Martin ! 9: * ARPA: [email protected] ! 10: * UUCP: ...!ucbvax!dcmartin ! 11: * ! 12: * $Log: font.c,v $ ! 13: * Revision 10.4 86/11/29 13:48:04 jg ! 14: * fixes from Berkeley ! 15: * ! 16: * Revision 1.20 86/07/27 13:46:41 dcmartin ! 17: * more modifications to LoadVFont() to fix bugs w/ invalid pixrect pointers ! 18: * and variable height fonts. ! 19: * ! 20: * Revision 1.19 86/07/25 15:36:56 dcmartin ! 21: * modified code in StrikeToPixfont() to free all sub-structures in ! 22: * FontPriv pointer. ! 23: * ! 24: * Revision 1.18 86/07/25 15:30:46 dcmartin ! 25: * changed all calls to Xalloc() to malloc() due to necessity of getting NULLs ! 26: * when ENOMEM. ! 27: * ! 28: * Revision 1.17 86/07/25 14:40:18 dcmartin ! 29: * changed the algorithm for determining variable width. ! 30: * should work for all fonts, now. ! 31: * ! 32: * Revision 1.16 86/07/17 10:47:00 dcmartin ! 33: * can't include <sys/param.h> on Sun release 2.x due to brain damage in ! 34: * compiler as <sys/param.h> wants to include <sys/types.h> and so does ! 35: * <pixrect/pixrect_hs.h> in Xsun.h ! 36: * ! 37: * Revision 1.15 86/07/17 10:36:33 dcmartin ! 38: * release version w/ new LoadXFont() and support for Sun vfont files. ! 39: * ! 40: * Revision 1.14 86/07/17 10:31:49 dcmartin ! 41: * ! 42: */ ! 43: ! 44: #ifndef lint ! 45: static char rcs_id[] = "$Header: font.c,v 10.4 86/11/29 13:48:04 jg Rel $"; ! 46: #endif lint ! 47: ! 48: #include <X/mit-copyright.h> ! 49: ! 50: /* ! 51: * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided ! 52: * for unrestricted use provided that this legend is included on all tape ! 53: * media and as a part of the software program in whole or part. Users ! 54: * may copy or modify these drivers without charge, but are not authorized ! 55: * to license or distribute them to anyone else except as part of a product or ! 56: * program developed by the user. ! 57: * ! 58: * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND ! 59: * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A ! 60: * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE ! 61: * PRACTICE. ! 62: * ! 63: * The Sun X Drivers are provided with no support and without any obligation ! 64: * on the part of Sun Microsystems, Inc. to assist in their use, correction, ! 65: * modification or enhancement. ! 66: * ! 67: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE ! 68: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X ! 69: * DRIVERS OR ANY PART THEREOF. ! 70: * ! 71: * In no event will Sun Microsystems, Inc. be liable for any lost revenue ! 72: * or profits or other special, indirect and consequential damages, even if ! 73: * Sun has been advised of the possibility of such damages. ! 74: * ! 75: * Sun Microsystems, Inc. ! 76: * 2550 Garcia Avenue ! 77: * Mountain View, California 94043 ! 78: */ ! 79: ! 80: #ifdef sun ! 81: ! 82: #include "Xsun.h" ! 83: #include "vssite.h" ! 84: #include "../libvs100/param.h" ! 85: #include <vfont.h> ! 86: #include <sys/file.h> ! 87: #include <sys/stat.h> ! 88: #include <errno.h> ! 89: #include <strings.h> ! 90: ! 91: /* ! 92: * from /usr/include/sys/param.h ! 93: */ ! 94: #define MAXPATHLEN 1024 ! 95: ! 96: extern int errno; ! 97: extern char *getenv(); ! 98: extern char *malloc(); ! 99: extern long lseek(); ! 100: ! 101: #define XFONT 0 ! 102: #define VFONT 1 ! 103: #define ReverseShort(s) ((ReverseByte[(unsigned char)(s)]<<8) \ ! 104: | ReverseByte[(unsigned char)((s)>>8)]) ! 105: ! 106: static short ReverseByte[256] = { ! 107: 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0, ! 108: 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, ! 109: 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8, ! 110: 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, ! 111: 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4, ! 112: 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, ! 113: 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec, ! 114: 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, ! 115: 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2, ! 116: 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2, ! 117: 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea, ! 118: 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, ! 119: 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6, ! 120: 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, ! 121: 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee, ! 122: 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, ! 123: 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1, ! 124: 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, ! 125: 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9, ! 126: 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, ! 127: 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5, ! 128: 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, ! 129: 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed, ! 130: 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd, ! 131: 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3, ! 132: 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3, ! 133: 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb, ! 134: 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb, ! 135: 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7, ! 136: 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, ! 137: 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef, ! 138: 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff ! 139: }; ! 140: ! 141: extern struct pixrectops mem_ops; ! 142: static struct mpr_data mprd; ! 143: ! 144: /* ! 145: * These define the biggest font that will successfully load. ! 146: */ ! 147: #define MAX_FONT_WIDTH 60 ! 148: #define MAX_FONT_HEIGHT 60 ! 149: ! 150: static struct pixrect spr = { ! 151: &mem_ops, ! 152: 256 * MAX_FONT_WIDTH, ! 153: MAX_FONT_HEIGHT, ! 154: 1, ! 155: (caddr_t) &mprd ! 156: }; ! 157: ! 158: static struct pixfont * ! 159: StrikeToPixfont(fp) ! 160: FONT *fp; ! 161: { ! 162: register FontPriv *fpp = (FontPriv *) fp->data; ! 163: register struct pixfont *pf; ! 164: register int i, w; ! 165: register short *sh, limit; ! 166: register struct pixchar *pc; ! 167: ! 168: pf = (struct pixfont *) malloc(sizeof(struct pixfont)); ! 169: if (pf == (struct pixfont *) NULL) { ! 170: errno = ENOMEM; ! 171: return(pf); ! 172: } ! 173: bzero(pf, sizeof(struct pixfont)); ! 174: limit = (fpp->wpitch / 2) * fp->height; ! 175: sh = (short *) fpp->fltable[0]; ! 176: do { ! 177: *sh = ReverseShort(*sh); ! 178: sh++; ! 179: } while (--limit != -1); ! 180: mprd.md_linebytes = fpp->wpitch; ! 181: mprd.md_image = (short *) fpp->fltable[0]; ! 182: bzero((caddr_t) pf, sizeof(struct pixfont)); ! 183: pf->pf_defaultsize.y = fp->height; ! 184: if (fp->fixed) { ! 185: pf->pf_defaultsize.x = fp->avg_width; ! 186: } ! 187: /* for all the characters */ ! 188: for (i = fp->first; i <= fp->last; i++) { ! 189: if ((w = fpp->widths[i]) < 0) ! 190: continue; ! 191: pc = &(pf->pf_char[i]); ! 192: pc->pc_pr = mem_create(w, fp->height, 1); ! 193: pc->pc_home.x = 0; ! 194: pc->pc_home.y = fp->height - fp->base; ! 195: pc->pc_adv.x = w; ! 196: pc->pc_adv.y = 0; ! 197: pr_rop(pc->pc_pr, 0, 0, w, fp->height, PIX_SRC, ! 198: &spr, fpp->leftarray[i], 0); ! 199: } ! 200: free((caddr_t) fpp->leftarray); ! 201: free((caddr_t) fpp->widths); ! 202: free((caddr_t) fpp->strike); ! 203: free((caddr_t) fpp->fltable); ! 204: free((caddr_t) fpp); ! 205: return(pf); ! 206: } /* end StrikeToPixfont() */ ! 207: ! 208: /* ! 209: * LoadXFont - load an xfont format file ! 210: * ! 211: * The FontData structure consists of { ! 212: * short f_characters[5] ! 213: * short f_firstChar ! 214: * short f_lastChar ! 215: * short f_leftArray[2] ! 216: * short f_baseline ! 217: * short f_spaceIndex ! 218: * short f_fixedWidth ! 219: * } ! 220: * ! 221: * The five shorts of f_characters[] are: ! 222: * [0] - location (in bytes) from start of file where font data begins ! 223: * [1] - unused ! 224: * [2] - width of font bitmap pointed at by [0] ! 225: * [3] - height of font bitmap ! 226: * [4] - bits per pixel of font bitmap ! 227: * ! 228: * The two shorts of f_leftArray[] are: ! 229: * [0] - location (in bytes) from start of file of bitmap offset array ! 230: * [1] - unused ! 231: * ! 232: */ ! 233: static FONT * ! 234: LoadXFont(fildes, name) ! 235: int fildes; ! 236: caddr_t name; ! 237: { ! 238: register int i, j; ! 239: int font_nbytes, totalWidth, datasiz, tablesiz; ! 240: char *fontdata; ! 241: short *offset_table, *width_table; ! 242: FONT *fp; ! 243: FontData font; ! 244: FontPriv *fpriv; ! 245: struct stat stb; ! 246: ! 247: /* read in the xfont header */ ! 248: if (read(fildes, (caddr_t) &font, sizeof(FontData)) != ! 249: sizeof(FontData)) { ! 250: errno = EINVAL; ! 251: return (NULL); ! 252: } ! 253: /* byte swap */ ! 254: Swap_shorts((short *) &font, sizeof(FontData) / sizeof(short)); ! 255: /* determine the number of bytes in the bitmap */ ! 256: font_nbytes = BitmapSize(font.f_characters[2], font.f_characters[3]); ! 257: /* stat the file to determine size */ ! 258: fstat(fildes, &stb); ! 259: /* if the location of the offset table is > location of bitmap ... */ ! 260: if (font.f_leftArray[0] > font.f_characters[0]) { ! 261: /* check for sufficient space for font bitmap */ ! 262: if (font.f_leftArray[0] - font.f_characters[0] < font_nbytes) { ! 263: /* no */ ! 264: errno = EINVAL; ! 265: return(NULL); ! 266: } ! 267: /* determine the space allocated for the offset table */ ! 268: tablesiz = stb.st_size - font.f_leftArray[0]; ! 269: /* determine the space allocated for the font data */ ! 270: datasiz = font.f_leftArray[0] - font.f_characters[0]; ! 271: } else { ! 272: /* check for sufficient space for font bitmap */ ! 273: if (font_nbytes + font.f_characters[0] > stb.st_size) { ! 274: errno = EINVAL; ! 275: return(NULL); ! 276: } ! 277: /* determine the space allocated for the offset table */ ! 278: tablesiz = font.f_characters[0] - font.f_leftArray[0]; ! 279: /* determine the space allocated for the font data */ ! 280: datasiz = stb.st_size - font.f_characters[0]; ! 281: } ! 282: /* are we going to ask for more than we have? */ ! 283: if (font_nbytes > datasiz) { ! 284: errno = EINVAL; ! 285: return(NULL); ! 286: } ! 287: /* allocate space for the font bitmap */ ! 288: fontdata = (caddr_t) malloc(font_nbytes); ! 289: if (fontdata == (caddr_t) NULL) { ! 290: errno = ENOMEM; ! 291: return(NULL); ! 292: } ! 293: /* seek to start of bitmap */ ! 294: lseek(fildes, (long) font.f_characters[0], 0); ! 295: /* read it in */ ! 296: if (read(fildes, fontdata, font_nbytes) != font_nbytes) { ! 297: free(fontdata); ! 298: errno = EINVAL; ! 299: return (NULL); ! 300: } ! 301: /* byte swap */ ! 302: Swap_shorts((short *) fontdata, font_nbytes / sizeof(short)); ! 303: /* is there an offset table? */ ! 304: if (tablesiz == 0) { ! 305: /* no -- this had better be a fixed width font */ ! 306: if (font.f_fixedWidth == 0) { ! 307: free(fontdata); ! 308: errno = EINVAL; ! 309: return(NULL); ! 310: } ! 311: /* determine table size */ ! 312: tablesiz = sizeof(short) * ! 313: (font.f_lastChar - font.f_firstChar + 2); ! 314: /* allocate space for table */ ! 315: offset_table = (short *) malloc(tablesiz); ! 316: if (offset_table == (short *) NULL) { ! 317: free(fontdata); ! 318: errno = ENOMEM; ! 319: return(NULL); ! 320: } ! 321: /* zero out the offset table */ ! 322: bzero(offset_table, tablesiz); ! 323: /* build the offset table */ ! 324: for (j=0, i = font.f_firstChar; i < font.f_lastChar + 2; i++) { ! 325: offset_table[i] = j; ! 326: j += font.f_fixedWidth; ! 327: } ! 328: } else { ! 329: /* allocate space for table */ ! 330: offset_table = (short *) malloc(tablesiz); ! 331: if (offset_table == (short *) NULL) { ! 332: free(fontdata); ! 333: errno = ENOMEM; ! 334: return(NULL); ! 335: } ! 336: /* zero out the offset table */ ! 337: bzero(offset_table, tablesiz); ! 338: /* seek to offset array */ ! 339: lseek(fildes, (long) font.f_leftArray[0], 0); ! 340: /* read the offset array */ ! 341: if (read(fildes, (caddr_t) &offset_table[font.f_firstChar], ! 342: tablesiz) != tablesiz) { ! 343: free(fontdata); ! 344: free((caddr_t) offset_table); ! 345: errno = EINVAL; ! 346: return (NULL); ! 347: } ! 348: Swap_shorts(offset_table, tablesiz / sizeof(short)); ! 349: } ! 350: /* allocate a width table -- to be built from the offset table */ ! 351: width_table = (short *) malloc(tablesiz); ! 352: if (width_table == (short *) NULL) { ! 353: free(fontdata); ! 354: free((caddr_t) offset_table); ! 355: errno = ENOMEM; ! 356: return(NULL); ! 357: } ! 358: /* allocate space for the device dependent private font data */ ! 359: fpriv = (FontPriv *) malloc(sizeof(FontPriv)); ! 360: if (fpriv == (FontPriv *) NULL) { ! 361: free(fontdata); ! 362: free((caddr_t) offset_table); ! 363: free((caddr_t) width_table); ! 364: errno = ENOMEM; ! 365: return(NULL); ! 366: } ! 367: /* initialize */ ! 368: fpriv->maxwidth = 0; ! 369: totalWidth = 0; ! 370: /* convert the offset table to the width table */ ! 371: for (i = font.f_firstChar; i <= font.f_lastChar; i++) { ! 372: width_table[i] = offset_table[i + 1] - offset_table[i]; ! 373: if (width_table[i] > fpriv->maxwidth) { ! 374: fpriv->maxwidth = width_table[i]; ! 375: } ! 376: if (width_table[i] < 0) { ! 377: errno = EINVAL; ! 378: return(NULL); ! 379: } ! 380: totalWidth += width_table[i]; ! 381: } ! 382: fpriv->widths = width_table; ! 383: fpriv->leftarray = offset_table; ! 384: /* allocate space for the strike font */ ! 385: fpriv->strike = (BITMAP *) malloc(sizeof(BITMAP)); ! 386: if (fpriv->strike == (BITMAP *) NULL) { ! 387: free(fontdata); ! 388: free((caddr_t) offset_table); ! 389: free((caddr_t) width_table); ! 390: free((caddr_t) fpriv); ! 391: errno = ENOMEM; ! 392: return(NULL); ! 393: } ! 394: /* determine the number of bytes per line of the bitmap */ ! 395: fpriv->wpitch = (((font.f_characters[2] + 15) >> 3) & ~1); ! 396: /* set other strike stuff .. */ ! 397: fpriv->strike->width = font.f_characters[2]; ! 398: fpriv->strike->height = font.f_characters[3]; ! 399: fpriv->strike->refcnt = 1; ! 400: fpriv->strike->data = (caddr_t) fontdata; ! 401: /* allocate space for the font line table */ ! 402: fpriv->fltable = (char **) malloc(font.f_characters[3]*sizeof(char *)); ! 403: if (fpriv->fltable == (char **) NULL) { ! 404: free(fontdata); ! 405: free((caddr_t) offset_table); ! 406: free((caddr_t) width_table); ! 407: free((caddr_t) fpriv->strike); ! 408: free((caddr_t) fpriv); ! 409: errno = ENOMEM; ! 410: return(NULL); ! 411: } ! 412: /* compute the font line table entries */ ! 413: for (i = 0; i < font.f_characters[3]; i++) { ! 414: fpriv->fltable[i] = ((caddr_t) fontdata) + i * fpriv->wpitch; ! 415: } ! 416: /* allocate an xfont */ ! 417: fp = (FONT *) malloc(sizeof(FONT)); ! 418: if (fp == (FONT *) NULL) { ! 419: free(fontdata); ! 420: free((caddr_t) offset_table); ! 421: free((caddr_t) width_table); ! 422: free((caddr_t) fpriv->strike); ! 423: free((caddr_t) fpriv->fltable); ! 424: free((caddr_t) fpriv); ! 425: errno = ENOMEM; ! 426: return(NULL); ! 427: } ! 428: fp->first = font.f_firstChar; ! 429: fp->last = font.f_lastChar; ! 430: fp->height = font.f_characters[3]; ! 431: fp->base = font.f_baseline; ! 432: fp->space = font.f_spaceIndex + font.f_firstChar; ! 433: fp->refcnt = 1; ! 434: /* set the average width */ ! 435: fp->avg_width = totalWidth / (fp->last - fp->first + 1); ! 436: if (fp->avg_width == font.f_fixedWidth) { ! 437: fp->fixed = 1; ! 438: fpriv->maxwidth = fp->avg_width; ! 439: } else { ! 440: fp->fixed = 0; ! 441: } ! 442: /* allocate space for the name */ ! 443: fp->name = (caddr_t) malloc(strlen(name) + 1); ! 444: if (fp->name == (caddr_t) NULL) { ! 445: free(fontdata); ! 446: free((caddr_t) offset_table); ! 447: free((caddr_t) width_table); ! 448: free((caddr_t) fpriv->fltable); ! 449: free((caddr_t) fpriv->strike); ! 450: free((caddr_t) fpriv); ! 451: free((caddr_t) fp); ! 452: errno = ENOMEM; ! 453: return(NULL); ! 454: } ! 455: /* copy the name */ ! 456: (void) strcpy(fp->name, name); ! 457: /* change private font to pixfont */ ! 458: fp->data = (caddr_t) fpriv; ! 459: fp->data = (caddr_t) StrikeToPixfont(fp); ! 460: return (fp); ! 461: } /* end LoadXFont() */ ! 462: ! 463: static FONT * ! 464: LoadVFont(fd, name) ! 465: int fd; ! 466: caddr_t name; ! 467: { ! 468: register int i; ! 469: int fixed = 1; ! 470: register struct pixfont *pf = (struct pixfont *) NULL; ! 471: register struct pixchar *pc; ! 472: FONT *fp; ! 473: FILE *fonts; ! 474: short magic; ! 475: struct header hd; ! 476: struct dispatch disp[NUM_DISPATCH]; ! 477: struct stat stb; ! 478: int maxheight, maxwidth, maxup, maxdown; ! 479: ! 480: #define fbase (sizeof hd + sizeof disp) ! 481: ! 482: fonts = fdopen(fd, "r"); ! 483: if (fonts == 0) ! 484: return (0); ! 485: if (fread(&hd, sizeof hd, 1, fonts) != 1 || ! 486: fread(disp, sizeof disp, 1, fonts) != 1) ! 487: goto bad; ! 488: if (hd.magic != VFONT_MAGIC) ! 489: goto bad; ! 490: fstat(fd, &stb); ! 491: if (stb.st_size != fbase + hd.size) ! 492: goto bad; ! 493: ! 494: /* ! 495: * Allocate font header and set default sizes. The default width of the ! 496: * font is taken to be the width of a lower-case a, if there is one. ! 497: * The default interline spacing is taken to be 3/2 the height of an ! 498: * upper-case A above the baseline. ! 499: */ ! 500: pf = (struct pixfont *) malloc(sizeof(struct pixfont)); ! 501: if (pf == (struct pixfont *) NULL) ! 502: goto bad; ! 503: /* zero out the pixfont */ ! 504: bzero(pf, sizeof(struct pixfont)); ! 505: /* initialize */ ! 506: maxwidth = maxup = maxdown = 0; ! 507: /* determine maximum width, up and down for font */ ! 508: for (i = 0; i < NUM_DISPATCH; i++) { ! 509: register struct dispatch *d = &disp[i]; ! 510: ! 511: if (d->left + d->right > maxwidth) ! 512: maxwidth = d->left + d->right; ! 513: if (d->up > maxup) ! 514: maxup = d->up; ! 515: if (d->down > maxdown) ! 516: maxdown = d->down; ! 517: } ! 518: maxheight = maxup + maxdown; ! 519: pf->pf_defaultsize.x = maxwidth; ! 520: pf->pf_defaultsize.y = maxheight; ! 521: /* Create memory pixrects for characters of font. */ ! 522: for (i = 0; i < NUM_DISPATCH; i++) { ! 523: register struct dispatch *d = &disp[i]; ! 524: struct pr_size size; ! 525: struct pixrect *cpr; ! 526: int j, wb, ww; ! 527: short *sp; ! 528: ! 529: /* pointer to character */ ! 530: pc = &pf->pf_char[i]; ! 531: /* if there is no glyph, there is no character */ ! 532: if (d->nbytes == 0) { ! 533: pc->pc_pr = (struct pixrect *) NULL; ! 534: pc->pc_home.x = 0; ! 535: pc->pc_home.y = 0; ! 536: pc->pc_adv.x = 0; ! 537: pc->pc_adv.y = 0; ! 538: continue; ! 539: } ! 540: /* total character width */ ! 541: size.x = d->left + d->right; ! 542: /* total character height */ ! 543: size.y = d->up + d->down; ! 544: /* check for variable width */ ! 545: if (size.x != 0 && pf->pf_defaultsize.x != size.x) ! 546: fixed = 0; ! 547: /* get width in bytes and words */ ! 548: wb = (size.x + 7) >> 3; ! 549: ww = (size.x + 15) >> 4; ! 550: /* create a memory pixrect for character */ ! 551: if ((cpr = mem_create(size, 1)) == (struct pixrect *) NULL) ! 552: goto bad; ! 553: /* pointer to pixrect data */ ! 554: sp = mpr_d(cpr)->md_image; ! 555: /* seek to character */ ! 556: fseek(fonts, fbase + d->addr, 0); ! 557: /* read in the bytes */ ! 558: for (j = 0; j < size.y; j++) { ! 559: fread((caddr_t) sp, wb, 1, fonts); ! 560: sp += ww; ! 561: } ! 562: /* check to make sure all characters are the same height */ ! 563: if (size.y != maxheight) { ! 564: register struct pixrect *npr; ! 565: ! 566: npr = mem_create(size.x, maxheight, 1); ! 567: if (npr == (struct pixrect *) NULL) ! 568: goto bad; ! 569: d->up = maxup - d->up; ! 570: pr_rop(npr, 0, d->up, size.x, maxheight, ! 571: PIX_SRC, cpr, 0, 0); ! 572: (void) pr_destroy(cpr); ! 573: cpr = npr; ! 574: } ! 575: /* set character pixrect pointer */ ! 576: pc->pc_pr = cpr; ! 577: /* home from left edge */ ! 578: pc->pc_home.x = -d->left; ! 579: /* home from baseline */ ! 580: pc->pc_home.y = -d->up; ! 581: /* character horizonal advance */ ! 582: pc->pc_adv.x = d->width; ! 583: /* character vertical advance (vfont == 0) */ ! 584: pc->pc_adv.y = 0; ! 585: } ! 586: goto good; ! 587: bad: ! 588: free(pf); ! 589: errno = EINVAL; ! 590: return(NULL); ! 591: good: ! 592: fclose(fonts); ! 593: ! 594: /* allocate space for the X font description */ ! 595: if ((fp = (FONT *) malloc(sizeof(FONT))) == (FONT *) NULL) { ! 596: free((caddr_t) pf); ! 597: errno = ENOMEM; ! 598: return(NULL); ! 599: } ! 600: /* allocate space for font name */ ! 601: if ((fp->name = malloc(strlen(name) + 1)) == NULL) { ! 602: free((caddr_t) pf); ! 603: free((caddr_t) fp); ! 604: errno = ENOMEM; ! 605: return(NULL); ! 606: } ! 607: /* copy the name */ ! 608: (void) strcpy(name, fp->name); ! 609: /* set the X font attributes */ ! 610: if (fixed == 1) { ! 611: fp->fixed = 1; ! 612: fp->avg_width = pf->pf_defaultsize.x; ! 613: } else { ! 614: fp->fixed = 0; ! 615: fp->avg_width = 0; ! 616: } ! 617: fp->first = 0; ! 618: fp->last = 255; ! 619: fp->space = 32; ! 620: fp->height = maxheight; ! 621: fp->base = maxdown; ! 622: fp->refcnt = 1; ! 623: fp->data = (caddr_t) pf; ! 624: return(fp); ! 625: } /* end LoadVFont() */ ! 626: ! 627: static int ! 628: OpenFile(FileName, type_ptr) ! 629: char *FileName; ! 630: int *type_ptr; ! 631: { ! 632: int fd; ! 633: struct header hdrbuf; ! 634: ! 635: /* open the file */ ! 636: if ((fd = open(FileName, O_RDONLY, 0)) < 0) { ! 637: return(-1); ! 638: } ! 639: /* read header buffer */ ! 640: if (read(fd, (caddr_t) &hdrbuf, sizeof(struct header)) == ! 641: sizeof(struct header)) { ! 642: /* read \something/ -- now check the magic number */ ! 643: if (hdrbuf.magic == VFONT_MAGIC) { ! 644: /* VFONT */ ! 645: *type_ptr = VFONT; ! 646: } else { ! 647: /* XFONT */ ! 648: *type_ptr = XFONT; ! 649: } ! 650: /* rewind */ ! 651: (void) lseek(fd, (long) 0, 0); ! 652: /* return the file descriptor */ ! 653: return(fd); ! 654: } ! 655: /* bad read -- close and return -1 */ ! 656: close(fd); ! 657: return(-1); ! 658: } /* end OpenFile() */ ! 659: ! 660: static caddr_t ! 661: SearchXFontPath(fname) ! 662: register caddr_t fname; ! 663: { ! 664: register caddr_t cp, pp, c2p; ! 665: static char xfontpath[MAXPATHLEN]; ! 666: ! 667: /* check for an absolute pathname */ ! 668: if (*fname == '/') { ! 669: if (access(fname, R_OK) == 0) ! 670: return(fname); ! 671: else ! 672: return((caddr_t) NULL); ! 673: } ! 674: ! 675: /* get the environment variable for XFONTPATH */ ! 676: if ((pp = getenv("XFONTPATH")) == (caddr_t) NULL) { ! 677: pp = DEFAULT_FONT_PATH; ! 678: } ! 679: ! 680: for (; *pp != '\0'; pp++) { ! 681: for (cp = xfontpath; *pp != ':' && *pp != '\0'; *cp++ = *pp++); ! 682: *cp++ = '/'; ! 683: for (c2p = fname; *c2p != '\0'; *cp++ = *c2p++); ! 684: for (c2p = DEFAULT_FONT_SUFFIX; *c2p != '\0'; *cp++ = *c2p++); ! 685: *cp = '\0'; ! 686: if (access(xfontpath, R_OK) == 0) { ! 687: return(xfontpath); ! 688: } ! 689: } ! 690: return ((caddr_t) NULL); ! 691: } /* end SearchXFontPath() */ ! 692: ! 693: static int ! 694: FindFile(name, font_type) ! 695: char *name; ! 696: int *font_type; ! 697: { ! 698: caddr_t pathname; ! 699: int fd; ! 700: ! 701: if ((pathname = SearchXFontPath(name)) == (caddr_t) NULL) { ! 702: return(-1); ! 703: } ! 704: if ((fd = OpenFile(pathname, font_type)) < 0) { ! 705: return(-1); ! 706: } ! 707: return(fd); ! 708: } /* end FindFile() */ ! 709: ! 710: extern FONT * ! 711: GetFont(name) ! 712: caddr_t name; ! 713: { ! 714: int fd, type; ! 715: FONT *fp; ! 716: ! 717: if ((fd = FindFile(name, &type)) < 0) { ! 718: errno = EINVAL; ! 719: return ((FONT *) NULL); ! 720: } ! 721: ! 722: switch (type) { ! 723: case VFONT: ! 724: fp = LoadVFont(fd, name); ! 725: break; ! 726: case XFONT: ! 727: fp = LoadXFont(fd, name); ! 728: break; ! 729: default: ! 730: close(fd); ! 731: errno = EINVAL; ! 732: return((FONT *) NULL); ! 733: } /* end switch */ ! 734: close(fd); ! 735: if (fp == (FONT *) NULL) { ! 736: errno = EINVAL; ! 737: return((FONT *) NULL); ! 738: } ! 739: return(fp); ! 740: } /* end GetFont() */ ! 741: ! 742: FreeFont(font) ! 743: FONT *font; ! 744: { ! 745: pf_close((caddr_t) font->data); ! 746: free(font->name); ! 747: free((caddr_t) font); ! 748: } ! 749: ! 750: #endif sun
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.