ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/font.c
Revision: 2.5
Committed: Mon Sep 21 12:02:03 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +5 -3 lines
Log Message:
Changes for PC port

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