ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/text.c
Revision: 2.3
Committed: Tue Jun 16 13:24:23 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +6 -1 lines
Log Message:
added checking of extents to inglyph()

File Contents

# Content
1 /* Copyright (c) 1991 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 #include "font.h"
18
19 /*
20 * A text pattern is specified as the text (a file or line),
21 * the upper left anchor point, the right motion vector, the down
22 * motion vector, and the foreground and background brightness.
23 * For a file, the description is as follows:
24 *
25 * modifier brighttext id
26 * 2 fontfile textfile
27 * 0
28 * 11
29 * Ax Ay Az
30 * Rx Ry Rz
31 * Dx Dy Dz
32 * foreground background
33 *
34 * For a single line, we use:
35 *
36 * modifier brighttext id
37 * N+2 fontfile . This is a line with N words...
38 * 0
39 * 11
40 * Ax Ay Az
41 * Rx Ry Rz
42 * Dx Dy Dz
43 * foreground background
44 *
45 * Colortext is identical, except colors are given rather than
46 * brightnesses. Mixtext has foreground and background modifiers:
47 *
48 * modifier mixtext id
49 * 4+ foremod backmod fontfile text..
50 * 0
51 * 9
52 * Ax Ay Az
53 * Rx Ry Rz
54 * Dx Dy Dz
55 */
56
57 #define fndx(m) ((m)->otype==MIX_TEXT ? 2 : 0)
58 #define tndx(m) ((m)->otype==MIX_TEXT ? 3 : 1)
59
60 typedef struct tline {
61 struct tline *next; /* pointer to next line */
62 /* followed by the string */
63 } TLINE;
64
65 #define TLSTR(l) ((char *)((l)+1))
66
67 typedef struct {
68 FVECT right, down; /* right and down unit vectors */
69 FONT *f; /* our font */
70 TLINE tl; /* line list */
71 } TEXT;
72
73 extern char *libpath;
74
75 extern char *fgetword();
76
77 TEXT *gettext();
78
79 TLINE *tlalloc();
80
81
82 text(m, r)
83 register OBJREC *m;
84 RAY *r;
85 {
86 FVECT v;
87 int foreground;
88 /* get transformed position */
89 if (r->rox != NULL)
90 multp3(v, r->rop, r->rox->b.xfm);
91 else
92 VCOPY(v, r->rop);
93 /* check if we are within a text glyph */
94 foreground = intext(v, m);
95 /* modify */
96 if (m->otype == MIX_TEXT) {
97 OBJECT omod;
98 char *modname = m->oargs.sarg[foreground ? 0 : 1];
99 if (!strcmp(modname, VOIDID))
100 omod = OVOID;
101 else if ((omod = modifier(modname)) == OVOID) {
102 sprintf(errmsg, "undefined modifier \"%s\"", modname);
103 objerror(m, USER, errmsg);
104 }
105 raytexture(r, omod);
106 } else if (m->otype == PAT_BTEXT) {
107 if (foreground)
108 scalecolor(r->pcol, m->oargs.farg[9]);
109 else
110 scalecolor(r->pcol, m->oargs.farg[10]);
111 } else { /* PAT_CTEXT */
112 COLOR cval;
113 if (foreground)
114 setcolor(cval, m->oargs.farg[9],
115 m->oargs.farg[10],
116 m->oargs.farg[11]);
117 else
118 setcolor(cval, m->oargs.farg[12],
119 m->oargs.farg[13],
120 m->oargs.farg[14]);
121 multcolor(r->pcol, cval);
122 }
123 }
124
125
126 TLINE *
127 tlalloc(s) /* allocate and assign text line */
128 char *s;
129 {
130 extern char *strcpy();
131 register TLINE *tl;
132
133 tl = (TLINE *)malloc(sizeof(TLINE)+1+strlen(s));
134 if (tl == NULL)
135 error(SYSTEM, "out of memory in tlalloc");
136 tl->next = NULL;
137 strcpy(TLSTR(tl), s);
138 return(tl);
139 }
140
141
142 TEXT *
143 gettext(tm) /* get text structure for material */
144 register OBJREC *tm;
145 {
146 #define R (tm->oargs.farg+3)
147 #define D (tm->oargs.farg+6)
148 extern char *strcpy(), *fgets();
149 FVECT DxR;
150 double d;
151 FILE *fp;
152 char linbuf[512];
153 TEXT *t;
154 register int i;
155 register TLINE *tlp;
156 register char *s;
157
158 if ((t = (TEXT *)tm->os) != NULL)
159 return(t);
160 /* check arguments */
161 if (tm->oargs.nsargs - tndx(tm) < 1 ||
162 tm->oargs.nfargs != (tm->otype == PAT_BTEXT ? 11 :
163 tm->otype == PAT_CTEXT ? 15 : 9))
164 objerror(tm, USER, "bad # arguments");
165 if ((t = (TEXT *)malloc(sizeof(TEXT))) == NULL)
166 error(SYSTEM, "out of memory in gettext");
167 /* compute vectors */
168 fcross(DxR, D, R);
169 fcross(t->right, DxR, D);
170 d = DOT(D,D)/DOT(t->right,t->right);
171 for (i = 0; i < 3; i++)
172 t->right[i] *= d;
173 fcross(t->down, R, DxR);
174 d = DOT(R,R)/DOT(t->down,t->down);
175 for (i = 0; i < 3; i++)
176 t->down[i] *= d;
177 /* get text */
178 tlp = &t->tl;
179 if (tm->oargs.nsargs - tndx(tm) > 1) { /* single line */
180 s = linbuf;
181 for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
182 strcpy(s, tm->oargs.sarg[i]);
183 s += strlen(s);
184 *s++ = ' ';
185 }
186 *--s = '\0';
187 tlp->next = tlalloc(linbuf);
188 tlp = tlp->next;
189 } else { /* text file */
190 if ((s = getpath(tm->oargs.sarg[tndx(tm)],
191 libpath, R_OK)) == NULL) {
192 sprintf(errmsg, "cannot find text file \"%s\"",
193 tm->oargs.sarg[tndx(tm)]);
194 error(USER, errmsg);
195 }
196 if ((fp = fopen(s, "r")) == NULL) {
197 sprintf(errmsg, "cannot open text file \"%s\"",
198 s);
199 error(SYSTEM, errmsg);
200 }
201 while (fgets(linbuf, sizeof(linbuf), fp) != NULL) {
202 s = linbuf + strlen(linbuf) - 1;
203 if (*s == '\n')
204 *s = '\0';
205 tlp->next = tlalloc(linbuf);
206 tlp = tlp->next;
207 }
208 fclose(fp);
209 }
210 tlp->next = NULL;
211 /* get the font */
212 t->f = getfont(tm->oargs.sarg[fndx(tm)]);
213 /* we're done */
214 tm->os = (char *)t;
215 return(t);
216 #undef R
217 #undef D
218 }
219
220
221 freetext(m) /* free text structures associated with m */
222 OBJREC *m;
223 {
224 register TEXT *tp;
225 register TLINE *tlp;
226
227 tp = (TEXT *)m->os;
228 if (tp == NULL)
229 return;
230 for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next);
231 free((char *)tlp);
232 free((char *)tp);
233 m->os = NULL;
234 }
235
236
237 intext(p, m) /* check to see if p is in text glyph */
238 FVECT p;
239 OBJREC *m;
240 {
241 register TEXT *tp;
242 register TLINE *tlp;
243 FVECT v;
244 double y, x;
245 int col;
246 register int lno;
247 /* first, compute position in text */
248 tp = gettext(m);
249 v[0] = p[0] - m->oargs.farg[0];
250 v[1] = p[1] - m->oargs.farg[1];
251 v[2] = p[2] - m->oargs.farg[2];
252 col = x = DOT(v, tp->right);
253 lno = y = DOT(v, tp->down);
254 if (x < 0.0 || y < 0.0)
255 return(0);
256 x -= (double)col;
257 y = (lno+1) - y;
258 /* get the font character */
259 for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next)
260 if (--lno < 0)
261 break;
262 if (tlp == NULL || col >= strlen(TLSTR(tlp)))
263 return(0);
264 return(inglyph(x, y, tp->f->fg[TLSTR(tlp)[col]&0xff]));
265 }
266
267
268 inglyph(x, y, gl) /* (x,y) within font glyph gl? */
269 double x, y;
270 register GLYPH *gl;
271 {
272 int n, ncross;
273 int xlb, ylb;
274 register GORD *p0, *p1;
275
276 if (gl == NULL)
277 return(0);
278 x *= 256.0; /* get glyph coordinates */
279 y *= 256.0;
280 xlb = x + 0.5;
281 ylb = y + 0.5;
282 if (gl->left > xlb || gl->right <= xlb ||
283 gl->bottom > ylb || gl->top <= ylb)
284 return(0); /* outside extent */
285 n = gl->nverts; /* get # of vertices */
286 p0 = gvlist(gl) + 2*(n-1); /* connect last to first */
287 p1 = gvlist(gl);
288 ncross = 0;
289 /* positive x axis cross test */
290 while (n--) {
291 if ((p0[1] > ylb) ^ (p1[1] > ylb))
292 if (p0[0] > xlb && p1[0] > xlb)
293 ncross++;
294 else if (p0[0] > xlb || p1[0] > xlb)
295 ncross += (p1[1] > p0[1]) ^
296 ((p0[1]-y)*(p1[0]-x) >
297 (p0[0]-x)*(p1[1]-y));
298 p0 = p1;
299 p1 += 2;
300 }
301 return(ncross & 01);
302 }