ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/text.c
Revision: 1.6
Committed: Mon Jul 22 13:02:27 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +15 -5 lines
Log Message:
got rid of scanf() calls

File Contents

# User Rev Content
1 greg 1.4 /* Copyright (c) 1990 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * text.c - functions for text patterns and mixtures.
9     *
10     * 11/12/86
11     */
12    
13     #include "ray.h"
14    
15     #include "otypes.h"
16    
17     /*
18     * A text pattern is specified as the text (a file or line),
19     * the upper left anchor point, the right motion vector, the down
20     * motion vector, and the foreground and background brightness.
21     * For a file, the description is as follows:
22     *
23     * modifier brighttext id
24     * 2 fontfile textfile
25     * 0
26     * 11
27     * Ax Ay Az
28     * Rx Ry Rz
29     * Dx Dy Dz
30     * foreground background
31     *
32     * For a single line, we use:
33     *
34     * modifier brighttext id
35     * N+2 fontfile . This is a line with N words...
36     * 0
37     * 11
38     * Ax Ay Az
39     * Rx Ry Rz
40     * Dx Dy Dz
41     * foreground background
42     *
43     * Colortext is identical, except colors are given rather than
44     * brightnesses. Mixtext has foreground and background modifiers:
45     *
46     * modifier mixtext id
47     * 4+ foremod backmod fontfile text..
48     * 0
49     * 9
50     * Ax Ay Az
51     * Rx Ry Rz
52     * Dx Dy Dz
53     */
54    
55     #define fndx(m) ((m)->otype==MIX_TEXT ? 2 : 0)
56     #define tndx(m) ((m)->otype==MIX_TEXT ? 3 : 1)
57    
58     extern char *libpath; /* library search path */
59    
60     typedef unsigned char GLYPH;
61    
62     typedef struct font {
63     GLYPH *fg[256]; /* font glyphs */
64     char *name; /* font file name */
65     struct font *next; /* next font in list */
66     } FONT;
67    
68 greg 1.6 extern char *fgetword();
69    
70 greg 1.1 extern GLYPH *getglyph();
71    
72     extern FONT *getfont();
73    
74     static FONT *fontlist = NULL; /* our font list */
75    
76    
77     text(m, r)
78     register OBJREC *m;
79     RAY *r;
80     {
81     double v[3], y, x;
82     int col, lno;
83     int foreground;
84     GLYPH *g;
85     register double *ap;
86    
87     if (m->oargs.nsargs - tndx(m) < 1 ||
88     m->oargs.nfargs != (m->otype == PAT_BTEXT ? 11 :
89     m->otype == PAT_CTEXT ? 15 : 9))
90     objerror(m, USER, "bad # arguments");
91    
92     /* first, discover position in text */
93     ap = m->oargs.farg;
94 greg 1.4 if (r->rox != NULL)
95     multp3(v, r->rop, r->rox->b.xfm);
96     else
97     VCOPY(v, r->rop);
98 greg 1.2 v[0] -= ap[0];
99     v[1] -= ap[1];
100     v[2] -= ap[2];
101 greg 1.1 col = x = DOT(v, ap+3) / DOT(ap+3, ap+3);
102     lno = y = DOT(v, ap+6) / DOT(ap+6, ap+6);
103     x -= col;
104     y = (lno+1) - y;
105     /* get the font character, check it */
106     if ((g = getglyph(m, lno, col)) == NULL)
107     foreground = 0;
108     else
109     foreground = inglyph(x, y, g);
110     /* modify */
111     if (m->otype == MIX_TEXT) {
112     OBJECT omod;
113     char *modname = m->oargs.sarg[foreground ? 0 : 1];
114     if (!strcmp(modname, VOIDID))
115     omod = OVOID;
116     else if ((omod = modifier(modname)) == OVOID) {
117     sprintf(errmsg, "undefined modifier \"%s\"", modname);
118     objerror(m, USER, errmsg);
119     }
120     raymixture(r, omod, OVOID, 1.0);
121     } else if (m->otype == PAT_BTEXT) {
122     if (foreground)
123     scalecolor(r->pcol, ap[9]);
124     else
125     scalecolor(r->pcol, ap[10]);
126     } else { /* PAT_CTEXT */
127     COLOR cval;
128     if (foreground)
129     setcolor(cval, ap[9], ap[10], ap[11]);
130     else
131     setcolor(cval, ap[12], ap[13], ap[14]);
132     multcolor(r->pcol, cval);
133     }
134     }
135    
136    
137     GLYPH *
138     getglyph(tm, lno, col) /* get a glyph from a text description */
139     register OBJREC *tm;
140     int lno;
141     int col;
142     {
143     extern char *strcpy(), *fgets();
144     FILE *fp;
145     char linbuf[512];
146     register int i;
147     register char **txt;
148     register char *s;
149    
150     if (lno < 0 || col < 0)
151     return(NULL);
152     if (tm->os == NULL) {
153     txt = (char **)malloc(2*sizeof(char **));
154     if (txt == NULL)
155     goto memerr;
156     if (tm->oargs.nsargs - tndx(tm) > 1) { /* single line */
157     s = linbuf;
158     for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
159     strcpy(s, tm->oargs.sarg[i]);
160     s += strlen(s);
161     *s++ = ' ';
162     }
163     *--s = '\0';
164     txt[0] = savqstr(linbuf);
165     txt[1] = NULL;
166     } else { /* text file */
167     if ((s = getpath(tm->oargs.sarg[tndx(tm)],
168 greg 1.3 libpath, R_OK)) == NULL) {
169 greg 1.1 sprintf(errmsg, "cannot find text file \"%s\"",
170     tm->oargs.sarg[tndx(tm)]);
171     error(USER, errmsg);
172     }
173     if ((fp = fopen(s, "r")) == NULL) {
174     sprintf(errmsg, "cannot open text file \"%s\"",
175     s);
176     error(SYSTEM, errmsg);
177     }
178     for (i=0; fgets(linbuf,sizeof(linbuf),fp)!=NULL; i++) {
179     s = linbuf + strlen(linbuf) - 1;
180     if (*s == '\n')
181     *s = '\0';
182     txt=(char **)realloc(txt,(i+2)*sizeof(char **));
183     if (txt == NULL)
184     goto memerr;
185     txt[i] = savqstr(linbuf);
186     }
187     txt[i] = NULL;
188     fclose(fp);
189     }
190     tm->os = (char *)txt;
191     }
192     txt = (char **)tm->os;
193     for (i = 0; i < lno; i++)
194     if (txt[i] == NULL)
195     break;
196     if ((s = txt[i]) == NULL || col >= strlen(s))
197     return(NULL);
198     else
199     return(getfont(tm->oargs.sarg[fndx(tm)])->fg[s[col]]);
200     memerr:
201     error(SYSTEM, "out of memory in getglyph");
202     }
203    
204    
205     FONT *
206     getfont(fname) /* return font fname */
207     char *fname;
208     {
209 greg 1.6 char buf[16];
210 greg 1.1 FILE *fp;
211     char *pathname, *err;
212     int gn, ngv, gv;
213     register GLYPH *g;
214     register FONT *f;
215    
216     for (f = fontlist; f != NULL; f = f->next)
217     if (!strcmp(f->name, fname))
218     return(f);
219     /* load the font file */
220 greg 1.3 if ((pathname = getpath(fname, libpath, R_OK)) == NULL) {
221 greg 1.1 sprintf(errmsg, "cannot find font file \"%s\"", fname);
222     error(USER, errmsg);
223     }
224     f = (FONT *)calloc(1, sizeof(FONT));
225     if (f == NULL)
226     goto memerr;
227     f->name = savestr(fname);
228     if ((fp = fopen(pathname, "r")) == NULL) {
229     sprintf(errmsg, "cannot open font file \"%s\"",
230     pathname);
231     error(SYSTEM, errmsg);
232     }
233 greg 1.6 while (fgetword(buf,sizeof(buf),fp) != NULL) { /* get each glyph */
234     if (!isint(buf))
235     goto nonint;
236     gn = atoi(buf);
237 greg 1.1 if (gn < 0 || gn > 255) {
238     err = "illegal";
239     goto fonterr;
240     }
241     if (f->fg[gn] != NULL) {
242     err = "duplicate";
243     goto fonterr;
244     }
245 greg 1.6 if (fgetword(buf,sizeof(buf),fp) == NULL || !isint(buf) ||
246     (ngv = atoi(buf)) < 0 || ngv > 255) {
247 greg 1.1 err = "bad # vertices for";
248     goto fonterr;
249     }
250     g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH));
251     if (g == NULL)
252     goto memerr;
253     f->fg[gn] = g;
254     *g++ = ngv;
255     ngv *= 2;
256     while (ngv--) {
257 greg 1.6 if (fgetword(buf,sizeof(buf),fp) == NULL ||
258     !isint(buf) ||
259     (gv = atoi(buf)) < 0 || gv > 255) {
260 greg 1.1 err = "bad vertex for";
261     goto fonterr;
262     }
263     *g++ = gv;
264     }
265     }
266     fclose(fp);
267     f->next = fontlist;
268     return(fontlist = f);
269 greg 1.6 nonint:
270     sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
271     error(USER, errmsg);
272 greg 1.1 fonterr:
273     sprintf(errmsg, "%s character (%d) in font file \"%s\"",
274     err, gn, pathname);
275     error(USER, errmsg);
276     memerr:
277     error(SYSTEM, "out of memory in fontglyph");
278     }
279    
280    
281     inglyph(x, y, gl) /* (x,y) within font glyph gl? */
282     double x, y;
283     GLYPH *gl;
284     {
285     int n, ncross;
286     int xlb, ylb;
287     register GLYPH *p0, *p1;
288    
289     if (x < 0.0 || y < 0.0)
290     return(0);
291 greg 1.5 x *= 256.0; /* get glyph coordinates */
292     y *= 256.0;
293     xlb = x + 0.5;
294     ylb = y + 0.5;
295 greg 1.1 n = *gl++; /* get # of vertices */
296     p0 = gl + 2*(n-1); /* connect last to first */
297     p1 = gl;
298     ncross = 0;
299     /* positive x axis cross test */
300     while (n--) {
301     if ((p0[1] > ylb) ^ (p1[1] > ylb))
302     if (p0[0] > xlb && p1[0] > xlb)
303     ncross++;
304     else if (p0[0] > xlb || p1[0] > xlb)
305     ncross += (p1[1] > p0[1]) ^
306     ((p0[1]-y)*(p1[0]-x) >
307     (p0[0]-x)*(p1[1]-y));
308     p0 = p1;
309     p1 += 2;
310     }
311     return(ncross & 01);
312     }