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

# Content
1 /* Copyright (c) 1990 Regents of the University of California */
2
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 extern char *fgetword();
69
70 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 if (r->rox != NULL)
95 multp3(v, r->rop, r->rox->b.xfm);
96 else
97 VCOPY(v, r->rop);
98 v[0] -= ap[0];
99 v[1] -= ap[1];
100 v[2] -= ap[2];
101 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 libpath, R_OK)) == NULL) {
169 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 char buf[16];
210 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 if ((pathname = getpath(fname, libpath, R_OK)) == NULL) {
221 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 while (fgetword(buf,sizeof(buf),fp) != NULL) { /* get each glyph */
234 if (!isint(buf))
235 goto nonint;
236 gn = atoi(buf);
237 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 if (fgetword(buf,sizeof(buf),fp) == NULL || !isint(buf) ||
246 (ngv = atoi(buf)) < 0 || ngv > 255) {
247 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 if (fgetword(buf,sizeof(buf),fp) == NULL ||
258 !isint(buf) ||
259 (gv = atoi(buf)) < 0 || gv > 255) {
260 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 nonint:
270 sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
271 error(USER, errmsg);
272 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 x *= 256.0; /* get glyph coordinates */
292 y *= 256.0;
293 xlb = x + 0.5;
294 ylb = y + 0.5;
295 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 }