ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/font.c
Revision: 2.3
Committed: Wed Jun 24 17:52:58 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +72 -6 lines
Log Message:
finally got proptext() working

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     extern char *libpath; /* list of library directories */
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 greg 2.3 unsigned wsum, hsum, ngly;
31 greg 2.1 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, libpath, 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 greg 2.3 wsum = hsum = ngly = 0;
55 greg 2.1 while (fgetword(buf,sizeof(buf),fp) != NULL) { /* get each glyph */
56     if (!isint(buf))
57     goto nonint;
58     gn = atoi(buf);
59 greg 2.3 if (gn < 1 || gn > 255) {
60 greg 2.1 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 greg 2.2 g->left = g->right = g->top = g->bottom = 128;
77 greg 2.1 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 greg 2.2 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 greg 2.1 }
99 greg 2.3 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 greg 2.1 f->fg[gn] = g;
105     }
106     fclose(fp);
107 greg 2.3 if (ngly) {
108     f->mwidth = wsum / ngly;
109     f->mheight = hsum / ngly;
110     }
111 greg 2.1 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 greg 2.2
124    
125     int
126 greg 2.3 uniftext(sp, tp, f) /* uniformly space text line */
127     register short *sp; /* returned character spacing */
128     register char *tp; /* text line */
129     register FONT *f; /* font */
130     {
131     int linelen;
132    
133     linelen = *sp++ = 0;
134     while (*tp)
135     if (f->fg[*tp++&0xff] == NULL)
136     *sp++ = 0;
137     else
138     linelen += *sp++ = 256;
139     return(linelen);
140     }
141    
142    
143     int
144 greg 2.2 squeeztext(sp, tp, f, cis) /* squeeze text line */
145     short *sp; /* returned character spacing */
146     char *tp; /* text line */
147     FONT *f; /* font */
148     int cis; /* intercharacter spacing */
149     {
150     int linelen;
151     register GLYPH *gp;
152    
153     gp = NULL;
154     while (*tp && (gp = f->fg[*tp++&0xff]) == NULL)
155     *sp++ = 0;
156     cis /= 2;
157 greg 2.3 linelen = *sp = cis;
158 greg 2.2 while (gp != NULL) {
159     if (gp->nverts) { /* regular character */
160     linelen += *sp++ += cis - gp->left;
161     *sp = gp->right + cis;
162     } else { /* space */
163     linelen += *sp++;
164 greg 2.3 *sp = f->mwidth;
165 greg 2.2 }
166     gp = NULL;
167     while (*tp && (gp = f->fg[*tp++&0xff]) == NULL) {
168     linelen += *sp++;
169     *sp = 0;
170     }
171     }
172 greg 2.3 linelen += *sp += cis;
173 greg 2.2 return(linelen);
174     }
175    
176    
177 greg 2.3 int
178 greg 2.2 proptext(sp, tp, f, cis, nsi) /* space line proportionally */
179     short *sp; /* returned character spacing */
180     char *tp; /* text line */
181     FONT *f; /* font */
182     int cis; /* target intercharacter spacing */
183     int nsi; /* minimum number of spaces for indent */
184     {
185 greg 2.3 register char *end, *tab;
186     GLYPH *gp;
187     short *nsp;
188     int alen, len, width;
189     /* start by squeezing it */
190     squeeztext(sp, tp, f, cis);
191     /* now, realign spacing */
192     len = 0;
193     width = alen = *sp++;
194     while (*tp) {
195     nsp = sp;
196     for (end = tp; *end; end = tab) {
197     tab = end + 1;
198     alen += *nsp++;
199     if (f->fg[*end&0xff]) {
200     while ((gp = f->fg[*tab&0xff]) != NULL &&
201     gp->nverts == 0) { /* tab in */
202     alen += *nsp++;
203     tab++;
204     }
205     len += tab - end;
206     }
207     if (tab - end > nsi)
208     break;
209     }
210     len *= f->mwidth + cis; /* compute target length */
211     width += len;
212     len -= alen; /* necessary adjustment */
213     while (sp < nsp) {
214     alen = len/(nsp-sp);
215     *sp++ += alen;
216     len -= alen;
217     }
218     len = 0;
219     alen = 0;
220     tp = tab;
221     }
222     return(width);
223 greg 2.2 }