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

# User Rev Content
1 greg 2.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 greg 2.11 extern char *getlibpath();
19 greg 2.1
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 greg 2.3 unsigned wsum, hsum, ngly;
30 greg 2.11 int gn, ngv, gv;
31 greg 2.5 register GLYPH *g;
32 greg 2.1 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 greg 2.9 if ((pathname = getpath(fname, getlibpath(), R_OK)) == NULL) {
40 greg 2.1 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 greg 2.3 wsum = hsum = ngly = 0;
53 greg 2.11 while ((ngv = fgetval(fp, 'i', &gn)) != EOF) { /* get each glyph */
54     if (ngv == 0)
55 greg 2.1 goto nonint;
56 greg 2.3 if (gn < 1 || gn > 255) {
57 greg 2.1 err = "illegal";
58     goto fonterr;
59     }
60     if (f->fg[gn] != NULL) {
61     err = "duplicate";
62     goto fonterr;
63     }
64 greg 2.11 if (fgetval(fp, 'i', &ngv) <= 0 || ngv < 0 || ngv > 32000) {
65 greg 2.1 err = "bad # vertices for";
66     goto fonterr;
67     }
68     g = galloc(ngv);
69     if (g == NULL)
70     goto memerr;
71     g->nverts = ngv;
72 greg 2.2 g->left = g->right = g->top = g->bottom = 128;
73 greg 2.1 ngv *= 2;
74     gp = gvlist(g);
75     while (ngv--) {
76 greg 2.11 if (fgetval(fp, 'i', &gv) <= 0 || gv < 0 || gv > 255) {
77 greg 2.1 err = "bad vertex for";
78     goto fonterr;
79     }
80     *gp++ = gv;
81 greg 2.2 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 greg 2.1 }
93 greg 2.3 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 greg 2.1 f->fg[gn] = g;
99     }
100     fclose(fp);
101 greg 2.3 if (ngly) {
102     f->mwidth = wsum / ngly;
103     f->mheight = hsum / ngly;
104     }
105 greg 2.1 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 greg 2.2
118    
119 greg 2.6 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 greg 2.2 int
143 greg 2.3 uniftext(sp, tp, f) /* uniformly space text line */
144 greg 2.5 register short *sp; /* returned character spacing */
145 greg 2.3 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 greg 2.10 linelen += *sp++ = 255;
156 greg 2.3 return(linelen);
157     }
158    
159    
160     int
161 greg 2.2 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 greg 2.5 register GLYPH *gp;
169 greg 2.2
170 greg 2.8 linelen = 0;
171 greg 2.2 gp = NULL;
172     while (*tp && (gp = f->fg[*tp++&0xff]) == NULL)
173     *sp++ = 0;
174     cis /= 2;
175 greg 2.8 *sp = cis;
176 greg 2.2 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 greg 2.3 *sp = f->mwidth;
183 greg 2.2 }
184     gp = NULL;
185     while (*tp && (gp = f->fg[*tp++&0xff]) == NULL) {
186     linelen += *sp++;
187     *sp = 0;
188     }
189     }
190 greg 2.3 linelen += *sp += cis;
191 greg 2.2 return(linelen);
192     }
193    
194    
195 greg 2.3 int
196 greg 2.2 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 greg 2.3 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 greg 2.7 width = *sp++;
211 greg 2.3 while (*tp) {
212 greg 2.7 len = alen = 0;
213 greg 2.3 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 greg 2.4 if (nsi && tab - end > nsi)
226 greg 2.3 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 greg 2.2 }