|
|
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.