|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid_font_c = "$Header: font.c,v 10.1 86/11/19 10:41:45 jg Exp $"; ! 3: #endif lint ! 4: /* Copyright 1985 Massachusetts Institute of Technology */ ! 5: ! 6: /* font.c - Reads a font from a file and stores it on the workstation ! 7: * ! 8: * GetFont Takes a font name and opens it ! 9: * FreeFont Frees the storage taken by a font ! 10: * StrikeToBitmaps converts strike format into an array of individual ! 11: * character bitmaps ! 12: * ! 13: * Changes and additions by: ! 14: * ! 15: * Scott Bates ! 16: * Brown University ! 17: * IRIS, Box 1946 ! 18: * Providence, RI 02912 ! 19: * ! 20: * ! 21: * Copyright (c) 1986 Brown University ! 22: * ! 23: * Permission to use, copy, modify and distribute this software and its ! 24: * documentation for any purpose and without fee is hereby granted, provided ! 25: * that the above copyright notice appear in all copies, and that both ! 26: * that copyright notice and this permission notice appear in supporting ! 27: * documentation, and that the name of Brown University not be used in ! 28: * advertising or publicity pertaining to distribution of the software ! 29: * without specific, written prior permission. Brown University makes no ! 30: * representations about the suitability of this software for any purpose. ! 31: * It is provided "as-is" without express or implied warranty. ! 32: */ ! 33: ! 34: #include "private.h" ! 35: #include "bitblt.h" ! 36: #include "xsite.h" ! 37: #include "font.h" ! 38: ! 39: /* ! 40: * Open font file ! 41: */ ! 42: ! 43: FONT *GetFont (name) ! 44: char *name; ! 45: { ! 46: char fontname[256]; ! 47: int fontfile; ! 48: FontData fd; ! 49: #define chars ((BitMap *) fd.f_characters) ! 50: int fontsize, leftsize, width; ! 51: register i, j; ! 52: BITMAP *strike_bm; ! 53: char *fontarea; ! 54: int VisibleChars = 0; ! 55: register short *leftarea, *leftarray; ! 56: register FONT *font; ! 57: register FontPriv *fpriv; ! 58: int tablesize = CHARPERFONT * sizeof(short); ! 59: ! 60: #ifdef TRACE_X ! 61: fprintf(stderr, "In GetFont\n"); ! 62: fflush(stderr); ! 63: #endif TRACE_X ! 64: ! 65: /* ! 66: * Convert font name into full path name ! 67: */ ! 68: ! 69: strcpy (fontname, DEFAULT_FONT_DIRECTORY); ! 70: strcat (fontname, name); ! 71: strcat (fontname, DEFAULT_FONT_SUFFIX); ! 72: ! 73: /* ! 74: * Open font file ! 75: */ ! 76: ! 77: if ((fontfile = open (fontname, 0)) == -1 && ! 78: (errno != ENOENT || (fontfile = open (name, 0)) == -1)) { ! 79: errno = EINVAL; ! 80: return (NULL); ! 81: } ! 82: ! 83: /* ! 84: * Read in font data structure ! 85: */ ! 86: ! 87: if (read (fontfile, (caddr_t) &fd, sizeof (FontData)) ! 88: != sizeof(FontData)) { ! 89: close (fontfile); ! 90: errno = EINVAL; ! 91: return (NULL); ! 92: } ! 93: ! 94: /* ! 95: * Swap each of the shorts in font data structure. ! 96: * font was created on a VAX and needs to be swapped ! 97: * for this hardware. ! 98: */ ! 99: ! 100: Swap_shorts((short *) &fd, sizeof(FontData) / sizeof(short)); ! 101: ! 102: /* ! 103: * Allocate space for font bitmap. ! 104: * bitmap is in strike format. ! 105: */ ! 106: ! 107: fontsize = BitmapSize(chars->bm_width, chars->bm_height); ! 108: fontarea = (char *) Xalloc (fontsize); ! 109: ! 110: /* ! 111: * Read font bitmap into allocated area ! 112: */ ! 113: ! 114: lseek (fontfile, (long) fd.f_characters[0], 0); ! 115: if (read (fontfile, fontarea, fontsize) != fontsize) { ! 116: close (fontfile); ! 117: free (fontarea); ! 118: errno = EINVAL; ! 119: return (NULL); ! 120: } ! 121: ! 122: /* ! 123: * Reverse all the bits in each character of font bitmap. ! 124: * The font bitmap was created on VAX and needs to be ! 125: * reversed for this hardware. ! 126: */ ! 127: ! 128: ReverseCharBits(fontarea, fontsize); ! 129: ! 130: /* ! 131: * Allocate space for left array and width table ! 132: */ ! 133: ! 134: leftarea = (short *) Xalloc (tablesize); ! 135: bzero((caddr_t)leftarea, tablesize); ! 136: leftarray = (short *) Xalloc (tablesize); ! 137: ! 138: /* ! 139: * What kind of font is this ? ! 140: */ ! 141: ! 142: if (fd.f_fixedWidth == 0) { ! 143: /* ! 144: * The font is variable width so allocate space for left ! 145: * array and read it in. The left array is an array ! 146: * of pointers to the left most bit of each character ! 147: * in the font. ! 148: */ ! 149: ! 150: leftsize = (fd.f_lastChar - fd.f_firstChar + 2) ! 151: * sizeof (short); ! 152: lseek (fontfile, (long) fd.f_leftArray[0], 0); ! 153: if (read(fontfile,(caddr_t)&leftarea[fd.f_firstChar],leftsize) ! 154: != leftsize) { ! 155: close (fontfile); ! 156: free (fontarea); ! 157: free ((caddr_t) leftarea); ! 158: free ((caddr_t) leftarray); ! 159: errno = EINVAL; ! 160: return (NULL); ! 161: } ! 162: ! 163: /* ! 164: * Swap each short in the leftarray. The array was created ! 165: * on a VAX and needs to be swapped for this hardware ! 166: */ ! 167: ! 168: Swap_shorts(leftarea, leftsize / sizeof (short)); ! 169: } else { ! 170: /* ! 171: * The font is of a fixed width so create the left ! 172: * array ourselves ! 173: */ ! 174: ! 175: j = 0; ! 176: for (i = fd.f_firstChar; i <= fd.f_lastChar + 1; i++) { ! 177: leftarea[i] = j; ! 178: j += fd.f_fixedWidth; ! 179: } ! 180: } ! 181: ! 182: /* ! 183: * Make a copy of the left array for future use ! 184: */ ! 185: ! 186: bcopy(leftarea, leftarray, tablesize); ! 187: ! 188: /* ! 189: * Close the font file ! 190: */ ! 191: ! 192: close (fontfile); ! 193: ! 194: /* ! 195: * Allocate space for FONT structure ! 196: */ ! 197: ! 198: font = (FONT *) Xalloc (sizeof (FONT)); ! 199: ! 200: /* ! 201: * Fill in FONT structure with data obtained from font file ! 202: */ ! 203: ! 204: font->height = chars->bm_height; ! 205: font->first = fd.f_firstChar; ! 206: font->last = fd.f_lastChar; ! 207: font->base = fd.f_baseline; ! 208: font->space = fd.f_spaceIndex; ! 209: font->space += font->first; ! 210: if (fd.f_fixedWidth) { ! 211: font->fixed = 1; ! 212: } else { ! 213: font->fixed = 0; ! 214: } ! 215: font->refcnt = 1; ! 216: font->name = (char *) Xalloc (strlen (name) + 1); ! 217: strcpy (font->name, name); ! 218: ! 219: /* ! 220: * Allocate space for the fonts private data structure ! 221: */ ! 222: ! 223: fpriv = (FontPriv *) Xalloc (sizeof (FontPriv)); ! 224: font->data = (caddr_t) fpriv; ! 225: ! 226: /* ! 227: * Save pointers to left array, width table , and font bitmap ! 228: */ ! 229: ! 230: fpriv->widths = leftarea; ! 231: fpriv->leftarray = leftarray; ! 232: ! 233: /* ! 234: * Allocate a temporary buffer for the strike bitmap. ! 235: */ ! 236: if ((strike_bm = (BITMAP *) Xalloc(sizeof(BITMAP))) == NULL) { ! 237: free (fontarea); ! 238: free ((caddr_t) leftarea); ! 239: free ((caddr_t) leftarray); ! 240: free ((caddr_t) name); ! 241: free ((caddr_t) font); ! 242: free ((caddr_t) fpriv); ! 243: return (NULL); ! 244: } ! 245: ! 246: strike_bm->width = chars->bm_width; ! 247: strike_bm->height = chars->bm_height; ! 248: strike_bm->refcnt = 1; ! 249: strike_bm->data = (caddr_t) fontarea; ! 250: ! 251: /* ! 252: * Convert leftarray to the width table ! 253: */ ! 254: ! 255: fpriv->maxwidth = 0; ! 256: for (i = font->first; i < font->last; i++) { ! 257: width = fpriv->leftarray[i + 1] - fpriv->leftarray[i]; ! 258: if (width > fpriv->maxwidth) { ! 259: fpriv->maxwidth = width; ! 260: } ! 261: if (width < 0) { ! 262: width = 0; /* font sanity check */ ! 263: DeviceError ("Bad font leftarray!"); ! 264: } else if (width > 0) { ! 265: VisibleChars++; ! 266: } ! 267: fpriv->widths[i] = width; ! 268: } ! 269: fpriv->widths[i] = strike_bm->width - fpriv->leftarray[i]; ! 270: font->avg_width = strike_bm->width / VisibleChars; ! 271: ! 272: /* ! 273: * Make individual bitmaps of each character in font ! 274: */ ! 275: ! 276: if (StrikeToBitmaps(font,strike_bm) == NULL) { ! 277: free (fontarea); ! 278: free ((caddr_t) leftarea); ! 279: free ((caddr_t) leftarray); ! 280: free ((caddr_t) strike_bm); ! 281: free ((caddr_t) fpriv); ! 282: free ((caddr_t) name); ! 283: free ((caddr_t) font); ! 284: return (NULL); ! 285: } ! 286: ! 287: /* ! 288: * Set up offscr if the font will fit into the offscreen ! 289: * buffer. ! 290: */ ! 291: ! 292: if (font->height > MAX_OFFSCR_HT) { ! 293: fpriv->offscr = NILBITMAP; ! 294: } else { ! 295: fpriv->offscr = &txtbm; ! 296: } ! 297: ! 298: /* ! 299: * Don't need the temporary strike bitmap. ! 300: */ ! 301: ! 302: free ((caddr_t) strike_bm); ! 303: ! 304: /* ! 305: * Return pointer to FONT stucture ! 306: */ ! 307: ! 308: return (font); ! 309: #undef chars ! 310: } ! 311: ! 312: /* ! 313: * Free all allocated space used by font ! 314: */ ! 315: ! 316: FreeFont (font) ! 317: register FONT *font; ! 318: { ! 319: register FontPriv *data; ! 320: ! 321: #ifdef TRACE_X ! 322: fprintf(stderr, "In FreeFont\n"); ! 323: fflush(stderr); ! 324: #endif TRACE_X ! 325: ! 326: data = FDATA(font); ! 327: if (data->widths) { ! 328: free ((caddr_t) data->widths); ! 329: } ! 330: FreeBitmap(data->chrs); ! 331: free ((caddr_t) data); ! 332: free (font->name); ! 333: free ((caddr_t) font); ! 334: } ! 335: ! 336: /* ! 337: * This routine converts strike format into an array of bitmaps ! 338: */ ! 339: ! 340: StrikeToBitmaps(font,sbm) ! 341: FONT *font; ! 342: BITMAP *sbm; ! 343: { ! 344: register FontPriv *fpriv = FDATA(font); ! 345: register BITMAP *cbm; ! 346: register charwidth; ! 347: register charoffset; ! 348: register i; ! 349: register desty = 0; ! 350: int size; ! 351: ! 352: #ifdef TRACE_X ! 353: fprintf(stderr, "In StrikeToBitmaps\n"); ! 354: fflush(stderr); ! 355: #endif TRACE_X ! 356: ! 357: /* ! 358: * Allocate bitmap structure for character bitmap ! 359: */ ! 360: ! 361: if ((cbm = fpriv->chrs = (BITMAP *) Xalloc(sizeof(BITMAP))) == NULL) { ! 362: return(NULL); ! 363: } ! 364: ! 365: /* ! 366: * Allocate all of the individual character bitmaps in one shot ! 367: */ ! 368: ! 369: cbm->width = (((fpriv->maxwidth + 15) >> 4) << 4); ! 370: cbm->height = (font->last - font->first + 1) * font->height; ! 371: size = BitmapSize(cbm->width, cbm->height); ! 372: cbm->refcnt = 1; ! 373: if ((cbm->data = (char *) Xalloc(size)) == NULL) { ! 374: free((caddr_t) cbm); ! 375: return(NULL); ! 376: } ! 377: bzero(cbm->data, size); ! 378: ! 379: /* ! 380: * Loop thru font and blt each character into its ! 381: * apporpriate bitmap ! 382: */ ! 383: ! 384: for (i = font->first; i <= font->last; i++) { ! 385: ! 386: charwidth = fpriv->widths[i]; ! 387: charoffset = fpriv->leftarray[i]; ! 388: ! 389: /* ! 390: * make source and destination rectangles ! 391: */ ! 392: ! 393: FillInRect(charoffset, 0, charwidth, font->height, &SrcRect); ! 394: FillInRect(0, desty, charwidth, font->height, &DstRect); ! 395: ! 396: /* ! 397: * blt character to bitmap ! 398: */ ! 399: ! 400: CopyBits((u_short *)sbm->data,sbm->width,sbm->height, &SrcRect, ! 401: (u_short *)cbm->data,cbm->width,cbm->height, &DstRect, ! 402: NILMASK, NIL, NIL, GXcopy, 0, NILCLIP); ! 403: ! 404: /* ! 405: * adjust destination address ! 406: */ ! 407: ! 408: desty += font->height; ! 409: } ! 410: ! 411: return(1); ! 412: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.