|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_font_c = "$Header: font.c,v 10.1 86/11/29 13:52:01 jg Rel $";
3: #endif lint
4: /*
5:
6: Copyright 1986 by the University of Utah
7:
8: Permission to use, copy, modify, and distribute this
9: software and its documentation for any purpose and without
10: fee is hereby granted, provided that the above copyright
11: notice appear in all copies and that both that copyright
12: notice and this permission notice appear in supporting
13: documentation, and that the name of the University of Utah
14: not be used in advertising or publicity pertaining to
15: distribution of the software without specific, written
16: prior permission. The University of Utah makes no
17: representations about the suitability of this software for
18: any purpose. It is provided "as is" without express or
19: implied warranty.
20:
21: */
22:
23: /* font.c Reads a font from a file and stores it on the workstation
24: *
25: * GetFont Takes a font name and stores it
26: * FreeFont Frees the storage taken by a font
27: *
28: */
29:
30: /*
31: * ToDo:
32: * Use Sun fonts too
33: */
34:
35: #include "Xapollo.h"
36: #include "vssite.h"
37: #include "../libvs100/param.h"
38: #include <errno.h>
39: #include <sys/file.h>
40:
41: extern int errno;
42: extern int borrow_flag;
43:
44: char *Xalloc(), *strcpy(), *strcat();
45: long lseek();
46:
47: #define CHARPERFONT 256
48:
49: static short ReverseBitsInByte[256] = {
50: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
51: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
52: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
53: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
54: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
55: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
56: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
57: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
58: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
59: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
60: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
61: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
62: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
63: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
64: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
65: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
66: };
67:
68: #define ReverseBitsInShort(s) ((ReverseBitsInByte[(s)&0xff]<<8)|ReverseBitsInByte[((s)>>8)&0xff])
69:
70:
71: FONT *GetFont (name)
72: char *name;
73: {
74: char fontname[256];
75: int fontfile = -1;
76: FontData font;
77: #define chars ((BitMap *) font.f_characters)
78: int fontsize, leftsize, width, i, j;
79: char *fontarea;
80: register short *leftarea, *leftarray;
81: register FONT *fd;
82: register FontPriv *fpriv;
83: int tablesize = (CHARPERFONT + 1) * sizeof(short);
84: extern char *getenv(), *index();
85: static char *Fontpath = NULL;
86: char *fontpath;
87: char lname[64];
88: int namelen;
89:
90: strcpy( lname, DEFAULT_APOLLO_FONT_PATH);
91: strcat( lname, name );
92: fontfile = access (lname, F_OK);
93: if (fontfile == 0) {
94: short fid;
95: gpr_$offset_t size;
96: status_$t status;
97:
98: fd = (FONT *) Xalloc (sizeof (FONT));
99:
100: fd->name = (char *) Xalloc (strlen (name) + 1);
101: strcpy (fd->name, name);
102:
103: fpriv = (FontPriv *) Xalloc (sizeof (FontPriv));
104:
105: fd->fixed = 1;
106: fd->data = (caddr_t) fpriv;
107:
108: fpriv->widths = NULL;
109: fpriv->leftarray = NULL;
110:
111: namelen = strlen(lname);
112: gpr_$load_font_file(*lname, (short)namelen, (short)fid, status);
113: check_status(status, "Getfont");
114: gpr_$set_text_font( fid, status);
115: gpr_$inq_text_extent("W", 1, size, status);
116: fd->height = size.y_size;
117: fd->avg_width = size.x_size;
118: fpriv->maxwidth = size.x_size;
119:
120: fd->first = '\0';
121: fd->last = '\177';
122: fd->base = 0;
123: fd->space = 0;
124: fd->refcnt = 1;
125: fpriv->ap_font_id = fid;
126: fpriv->ap_font = true;
127: /* Now load inverse version of font
128: */
129: strcat(lname, ".i");
130: namelen = strlen(lname);
131: gpr_$load_font_file(*lname, (short)namelen, (short)fid, status);
132: check_status(status, "GetFont: ");
133: fpriv->ap_font_id_inv = fid;
134: if (!borrow_flag) {
135: fpriv->ap_font_id_inv = fpriv->ap_font_id;
136: fpriv->ap_font_id = fid;
137: }
138: }
139: else {
140: if (!Fontpath) {
141: char *temp = getenv("XFONTPATH");
142:
143: if (temp) {
144: Fontpath = Xalloc(strlen(temp) + 1);
145: strcpy(Fontpath, temp);
146: }
147: }
148:
149: if ((fontpath = Fontpath) == NULL)
150: fontpath = DEFAULT_FONT_PATH;
151:
152: fontfile = open (name, 0, 0);
153:
154: while (fontfile < 0) {
155: char *fend;
156:
157: if ((fend = index(fontpath, ':')) != 0)
158: *fend = '\0';
159: if (*fontpath == '\0') {
160: errno = EINVAL;
161: return (NULL);
162: }
163:
164: if (*fontpath == '~') {
165: /* XXX - should implement ~foobar as well */
166: strcpy (fontname, getenv("HOME"));
167: strcat (fontname, "/");
168: fontpath++;
169: } else
170: *fontname = '\0';
171: strcat (fontname, fontpath);
172: strcat (fontname, "/");
173: strcat (fontname, name);
174: strcat (fontname, DEFAULT_FONT_SUFFIX);
175:
176: fontfile = open (fontname, 0, 0);
177: if (fend) {
178: *fend = ':';
179: fontpath = ++fend;
180: } else
181: break;
182: }
183: if (read (fontfile, (caddr_t) &font, sizeof (FontData)) != sizeof (FontData)) {
184: close (fontfile);
185: errno = EINVAL;
186: return (NULL);
187: }
188: Swap_shorts((short *) &font, sizeof (FontData)>>1);
189:
190: fontsize = BitmapSize(chars->bm_width, chars->bm_height);
191: fontarea = (char *) Xalloc (fontsize);
192: bzero( fontarea, fontsize );
193: lseek (fontfile, (long) font.f_characters[0], 0);
194: if (read (fontfile, fontarea, fontsize) != fontsize) {
195: close (fontfile);
196: free (fontarea);
197: errno = EINVAL;
198: return (NULL);
199: }
200: Swap_shorts((short *)fontarea, fontsize>>1);
201:
202: leftarea = (short *) Xalloc (tablesize);
203: bzero(leftarea, tablesize);
204: leftarray = (short *) Xalloc (tablesize);
205: if (font.f_fixedWidth == 0) {
206: leftsize = (font.f_lastChar - font.f_firstChar + 2) * sizeof (short);
207: lseek (fontfile, (long) font.f_leftArray[0], 0);
208: if (read (fontfile, & leftarea[font.f_firstChar], leftsize)
209: != leftsize) {
210: close (fontfile);
211: free (fontarea);
212: free ((caddr_t) leftarea);
213: free ((caddr_t) leftarray);
214: errno = EINVAL;
215: return (NULL);
216: }
217: Swap_shorts(((short *)& leftarea[font.f_firstChar]), leftsize>>1);
218: } else { /* if fixed width font, generate leftarray for use later */
219: j = 0;
220: for (i = font.f_firstChar; i <= font.f_lastChar + 1; i++) {
221: leftarea[i] = j;
222: j += font.f_fixedWidth;
223: }
224: }
225: bcopy(leftarea, leftarray, tablesize);
226:
227: close (fontfile);
228: /*
229: * set up font data structures
230: */
231:
232: fd = (FONT *) Xalloc (sizeof (FONT));
233:
234: fd->height = chars->bm_height;
235: fd->first = font.f_firstChar;
236: fd->last = font.f_lastChar;
237: fd->base = font.f_baseline;
238: fd->space = font.f_spaceIndex;
239: fd->space += fd->first;
240: fd->refcnt = 1;
241:
242:
243: fd->name = (char *) Xalloc (strlen (name) + 1);
244: strcpy (fd->name, name);
245:
246: /*
247: * set up the private font structure
248: */
249: fpriv = (FontPriv *) Xalloc (sizeof (FontPriv));
250:
251: if (fd->avg_width = font.f_fixedWidth) {
252: fd->fixed = 1;
253: fpriv->maxwidth = fd->avg_width;
254: }
255: else
256: fd->fixed = 0;
257: fd->data = (caddr_t) fpriv;
258:
259: fpriv->widths = leftarea;
260: fpriv->leftarray = leftarray;
261: fpriv->maxwidth = 0;
262:
263: /* of course... the bits are all switched... */
264: { register short *sh = (short *) fontarea;
265: register short limit = ((chars->bm_width+15)>>4)*chars->bm_height;
266: do *sh = ReverseBitsInShort(*sh), sh++;
267: while (--limit != -1);
268: }
269:
270: /* convert the leftarray to the width table */
271: for (i = fd->first; i <= fd->last; i++) {
272: width = fpriv->leftarray[i + 1] - fpriv->leftarray[i];
273: if (width > fpriv->maxwidth) fpriv->maxwidth = width;
274: if (width < 0) {
275: width = 0; /* font sanity check */
276: errno = EINVAL;
277: return(NULL);
278: }
279: fpriv->widths[i] = width;
280: }
281: fd->avg_width = ((fpriv->leftarray[fd->last] -
282: fpriv->leftarray[fd->first]) / (fd->last - fd->first));
283:
284: if ((fpriv->strike = make_bitmap( fontarea, chars->bm_width, chars->bm_height) ) == NULL) {
285: free (fontarea);
286: free ((caddr_t) leftarea);
287: free ((caddr_t) leftarray);
288: free ((caddr_t) fd);
289: free ((caddr_t) fpriv);
290: errno = EINVAL;
291: return (NULL);
292: }
293:
294: /* make_fontmap(fd); */
295: /* XXX free fontarea */
296:
297: #undef chars
298: }
299: return (fd);
300: }
301:
302: FreeFont (font)
303: register FONT *font;
304: {
305: FontPriv * fp;
306: status_$t status;
307:
308: fp = (FontPriv *)font->data;
309: if (fp->ap_font)
310: gpr_$unload_font_file((short)fp->ap_font_id, status);
311:
312: free ((caddr_t) font->data);
313: free (font->name);
314: free ((caddr_t) font);
315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.