ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/font.c
Revision: 2.10
Committed: Thu May 25 15:14:03 1995 UTC (28 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +1 -1 lines
Log Message:
fixed problem with hexbit font (spacing from 256 to 255 per char)

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Polygonal font handling routines
9 */
10
11 #include "standard.h"
12
13 #include "font.h"
14
15 #define galloc(nv) (GLYPH *)malloc(sizeof(GLYPH)+2*sizeof(GORD)*(nv))
16
17
18 extern char *fgetword(), *getlibpath();
19
20 static FONT *fontlist = NULL; /* list of loaded fonts */
21
22
23 FONT *
24 getfont(fname) /* return font fname */
25 char *fname;
26 {
27 char buf[16];
28 FILE *fp;
29 char *pathname, *err;
30 unsigned wsum, hsum, ngly;
31 int gn, ngv;
32 register int gv;
33 register GLYPH *g;
34 GORD *gp;
35 register FONT *f;
36
37 for (f = fontlist; f != NULL; f = f->next)
38 if (!strcmp(f->name, fname))
39 return(f);
40 /* load the font file */
41 if ((pathname = getpath(fname, getlibpath(), R_OK)) == NULL) {
42 sprintf(errmsg, "cannot find font file \"%s\"", fname);
43 error(USER, errmsg);
44 }
45 f = (FONT *)calloc(1, sizeof(FONT));
46 if (f == NULL)
47 goto memerr;
48 f->name = savestr(fname);
49 if ((fp = fopen(pathname, "r")) == NULL) {
50 sprintf(errmsg, "cannot open font file \"%s\"",
51 pathname);
52 error(SYSTEM, errmsg);
53 }
54 wsum = hsum = ngly = 0;
55 while (fgetword(buf,sizeof(buf),fp) != NULL) { /* get each glyph */
56 if (!isint(buf))
57 goto nonint;
58 gn = atoi(buf);
59 if (gn < 1 || gn > 255) {
60 err = "illegal";
61 goto fonterr;
62 }
63 if (f->fg[gn] != NULL) {
64 err = "duplicate";
65 goto fonterr;
66 }
67 if (fgetword(buf,sizeof(buf),fp) == NULL || !isint(buf) ||
68 (ngv = atoi(buf)) < 0 || ngv > 32000) {
69 err = "bad # vertices for";
70 goto fonterr;
71 }
72 g = galloc(ngv);
73 if (g == NULL)
74 goto memerr;
75 g->nverts = ngv;
76 g->left = g->right = g->top = g->bottom = 128;
77 ngv *= 2;
78 gp = gvlist(g);
79 while (ngv--) {
80 if (fgetword(buf,sizeof(buf),fp) == NULL ||
81 !isint(buf) ||
82 (gv = atoi(buf)) < 0 || gv > 255) {
83 err = "bad vertex for";
84 goto fonterr;
85 }
86 *gp++ = gv;
87 if (ngv & 1) { /* follow x limits */
88 if (gv < g->left)
89 g->left = gv;
90 else if (gv > g->right)
91 g->right = gv;
92 } else { /* follow y limits */
93 if (gv < g->bottom)
94 g->bottom = gv;
95 else if (gv > g->top)
96 g->top = gv;
97 }
98 }
99 if (g->right - g->left && g->top - g->bottom) {
100 ngly++;
101 wsum += g->right - g->left;
102 hsum += g->top - g->bottom;
103 }
104 f->fg[gn] = g;
105 }
106 fclose(fp);
107 if (ngly) {
108 f->mwidth = wsum / ngly;
109 f->mheight = hsum / ngly;
110 }
111 f->next = fontlist;
112 return(fontlist = f);
113 nonint:
114 sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
115 error(USER, errmsg);
116 fonterr:
117 sprintf(errmsg, "%s character (%d) in font file \"%s\"",
118 err, gn, pathname);
119 error(USER, errmsg);
120 memerr:
121 error(SYSTEM, "out of memory in fontglyph");
122 }
123
124
125 freefont(fname) /* free a font (free all if fname==NULL) */
126 char *fname;
127 {
128 FONT head;
129 register FONT *fl, *f;
130 register int i;
131
132 head.next = fontlist;
133 fl = &head;
134 while ((f = fl->next) != NULL)
135 if (fname == NULL || !strcmp(fname, f->name)) {
136 fl->next = f->next;
137 for (i = 0; i < 256; i++)
138 if (f->fg[i] != NULL)
139 free((char *)f->fg[i]);
140 freestr(f->name);
141 free((char *)f);
142 } else
143 fl = f;
144 fontlist = head.next;
145 }
146
147
148 int
149 uniftext(sp, tp, f) /* uniformly space text line */
150 register short *sp; /* returned character spacing */
151 register char *tp; /* text line */
152 register FONT *f; /* font */
153 {
154 int linelen;
155
156 linelen = *sp++ = 0;
157 while (*tp)
158 if (f->fg[*tp++&0xff] == NULL)
159 *sp++ = 0;
160 else
161 linelen += *sp++ = 255;
162 return(linelen);
163 }
164
165
166 int
167 squeeztext(sp, tp, f, cis) /* squeeze text line */
168 short *sp; /* returned character spacing */
169 char *tp; /* text line */
170 FONT *f; /* font */
171 int cis; /* intercharacter spacing */
172 {
173 int linelen;
174 register GLYPH *gp;
175
176 linelen = 0;
177 gp = NULL;
178 while (*tp && (gp = f->fg[*tp++&0xff]) == NULL)
179 *sp++ = 0;
180 cis /= 2;
181 *sp = cis;
182 while (gp != NULL) {
183 if (gp->nverts) { /* regular character */
184 linelen += *sp++ += cis - gp->left;
185 *sp = gp->right + cis;
186 } else { /* space */
187 linelen += *sp++;
188 *sp = f->mwidth;
189 }
190 gp = NULL;
191 while (*tp && (gp = f->fg[*tp++&0xff]) == NULL) {
192 linelen += *sp++;
193 *sp = 0;
194 }
195 }
196 linelen += *sp += cis;
197 return(linelen);
198 }
199
200
201 int
202 proptext(sp, tp, f, cis, nsi) /* space line proportionally */
203 short *sp; /* returned character spacing */
204 char *tp; /* text line */
205 FONT *f; /* font */
206 int cis; /* target intercharacter spacing */
207 int nsi; /* minimum number of spaces for indent */
208 {
209 register char *end, *tab;
210 GLYPH *gp;
211 short *nsp;
212 int alen, len, width;
213 /* start by squeezing it */
214 squeeztext(sp, tp, f, cis);
215 /* now, realign spacing */
216 width = *sp++;
217 while (*tp) {
218 len = alen = 0;
219 nsp = sp;
220 for (end = tp; *end; end = tab) {
221 tab = end + 1;
222 alen += *nsp++;
223 if (f->fg[*end&0xff]) {
224 while ((gp = f->fg[*tab&0xff]) != NULL &&
225 gp->nverts == 0) { /* tab in */
226 alen += *nsp++;
227 tab++;
228 }
229 len += tab - end;
230 }
231 if (nsi && tab - end > nsi)
232 break;
233 }
234 len *= f->mwidth + cis; /* compute target length */
235 width += len;
236 len -= alen; /* necessary adjustment */
237 while (sp < nsp) {
238 alen = len/(nsp-sp);
239 *sp++ += alen;
240 len -= alen;
241 }
242 tp = tab;
243 }
244 return(width);
245 }