ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/font.c
Revision: 2.11
Committed: Fri Jun 30 16:06:40 1995 UTC (28 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +6 -12 lines
Log Message:
added comments to font file using new fgetval() routine

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