ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/text.c
Revision: 2.2
Committed: Sat Jun 6 07:40:23 1992 UTC (31 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +7 -95 lines
Log Message:
initial move of getfont to separate routine

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 *fgetword();
74
75 TEXT *gettext();
76
77 TLINE *tlalloc();
78
79
80 text(m, r)
81 register OBJREC *m;
82 RAY *r;
83 {
84 FVECT v;
85 int foreground;
86 /* get transformed position */
87 if (r->rox != NULL)
88 multp3(v, r->rop, r->rox->b.xfm);
89 else
90 VCOPY(v, r->rop);
91 /* check if we are within a text glyph */
92 foreground = intext(v, m);
93 /* modify */
94 if (m->otype == MIX_TEXT) {
95 OBJECT omod;
96 char *modname = m->oargs.sarg[foreground ? 0 : 1];
97 if (!strcmp(modname, VOIDID))
98 omod = OVOID;
99 else if ((omod = modifier(modname)) == OVOID) {
100 sprintf(errmsg, "undefined modifier \"%s\"", modname);
101 objerror(m, USER, errmsg);
102 }
103 raytexture(r, omod);
104 } else if (m->otype == PAT_BTEXT) {
105 if (foreground)
106 scalecolor(r->pcol, m->oargs.farg[9]);
107 else
108 scalecolor(r->pcol, m->oargs.farg[10]);
109 } else { /* PAT_CTEXT */
110 COLOR cval;
111 if (foreground)
112 setcolor(cval, m->oargs.farg[9],
113 m->oargs.farg[10],
114 m->oargs.farg[11]);
115 else
116 setcolor(cval, m->oargs.farg[12],
117 m->oargs.farg[13],
118 m->oargs.farg[14]);
119 multcolor(r->pcol, cval);
120 }
121 }
122
123
124 TLINE *
125 tlalloc(s) /* allocate and assign text line */
126 char *s;
127 {
128 extern char *strcpy();
129 register TLINE *tl;
130
131 tl = (TLINE *)malloc(sizeof(TLINE)+1+strlen(s));
132 if (tl == NULL)
133 error(SYSTEM, "out of memory in tlalloc");
134 tl->next = NULL;
135 strcpy(TLSTR(tl), s);
136 return(tl);
137 }
138
139
140 TEXT *
141 gettext(tm) /* get text structure for material */
142 register OBJREC *tm;
143 {
144 #define R (tm->oargs.farg+3)
145 #define D (tm->oargs.farg+6)
146 extern char *strcpy(), *fgets();
147 FVECT DxR;
148 double d;
149 FILE *fp;
150 char linbuf[512];
151 TEXT *t;
152 register int i;
153 register TLINE *tlp;
154 register char *s;
155
156 if ((t = (TEXT *)tm->os) != NULL)
157 return(t);
158 /* check arguments */
159 if (tm->oargs.nsargs - tndx(tm) < 1 ||
160 tm->oargs.nfargs != (tm->otype == PAT_BTEXT ? 11 :
161 tm->otype == PAT_CTEXT ? 15 : 9))
162 objerror(tm, USER, "bad # arguments");
163 if ((t = (TEXT *)malloc(sizeof(TEXT))) == NULL)
164 error(SYSTEM, "out of memory in gettext");
165 /* compute vectors */
166 fcross(DxR, D, R);
167 fcross(t->right, DxR, D);
168 d = DOT(D,D)/DOT(t->right,t->right);
169 for (i = 0; i < 3; i++)
170 t->right[i] *= d;
171 fcross(t->down, R, DxR);
172 d = DOT(R,R)/DOT(t->down,t->down);
173 for (i = 0; i < 3; i++)
174 t->down[i] *= d;
175 /* get text */
176 tlp = &t->tl;
177 if (tm->oargs.nsargs - tndx(tm) > 1) { /* single line */
178 s = linbuf;
179 for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
180 strcpy(s, tm->oargs.sarg[i]);
181 s += strlen(s);
182 *s++ = ' ';
183 }
184 *--s = '\0';
185 tlp->next = tlalloc(linbuf);
186 tlp = tlp->next;
187 } else { /* text file */
188 if ((s = getpath(tm->oargs.sarg[tndx(tm)],
189 libpath, R_OK)) == NULL) {
190 sprintf(errmsg, "cannot find text file \"%s\"",
191 tm->oargs.sarg[tndx(tm)]);
192 error(USER, errmsg);
193 }
194 if ((fp = fopen(s, "r")) == NULL) {
195 sprintf(errmsg, "cannot open text file \"%s\"",
196 s);
197 error(SYSTEM, errmsg);
198 }
199 while (fgets(linbuf, sizeof(linbuf), fp) != NULL) {
200 s = linbuf + strlen(linbuf) - 1;
201 if (*s == '\n')
202 *s = '\0';
203 tlp->next = tlalloc(linbuf);
204 tlp = tlp->next;
205 }
206 fclose(fp);
207 }
208 tlp->next = NULL;
209 /* get the font */
210 t->f = getfont(tm->oargs.sarg[fndx(tm)]);
211 /* we're done */
212 tm->os = (char *)t;
213 return(t);
214 #undef R
215 #undef D
216 }
217
218
219 freetext(m) /* free text structures associated with m */
220 OBJREC *m;
221 {
222 register TEXT *tp;
223 register TLINE *tlp;
224
225 tp = (TEXT *)m->os;
226 if (tp == NULL)
227 return;
228 for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next);
229 free((char *)tlp);
230 free((char *)tp);
231 m->os = NULL;
232 }
233
234
235 intext(p, m) /* check to see if p is in text glyph */
236 FVECT p;
237 OBJREC *m;
238 {
239 register TEXT *tp;
240 register TLINE *tlp;
241 FVECT v;
242 double y, x;
243 int col;
244 register int lno;
245 /* first, compute position in text */
246 tp = gettext(m);
247 v[0] = p[0] - m->oargs.farg[0];
248 v[1] = p[1] - m->oargs.farg[1];
249 v[2] = p[2] - m->oargs.farg[2];
250 col = x = DOT(v, tp->right);
251 lno = y = DOT(v, tp->down);
252 if (x < 0.0 || y < 0.0)
253 return(0);
254 x -= (double)col;
255 y = (lno+1) - y;
256 /* get the font character */
257 for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next)
258 if (--lno < 0)
259 break;
260 if (tlp == NULL || col >= strlen(TLSTR(tlp)))
261 return(0);
262 return(inglyph(x, y, tp->f->fg[TLSTR(tlp)[col]&0xff]));
263 }
264
265
266 inglyph(x, y, gl) /* (x,y) within font glyph gl? */
267 double x, y;
268 GLYPH *gl;
269 {
270 int n, ncross;
271 int xlb, ylb;
272 register GORD *p0, *p1;
273
274 if (gl == NULL)
275 return(0);
276 x *= 256.0; /* get glyph coordinates */
277 y *= 256.0;
278 xlb = x + 0.5;
279 ylb = y + 0.5;
280 n = gl->nverts; /* get # of vertices */
281 p0 = gvlist(gl) + 2*(n-1); /* connect last to first */
282 p1 = gvlist(gl);
283 ncross = 0;
284 /* positive x axis cross test */
285 while (n--) {
286 if ((p0[1] > ylb) ^ (p1[1] > ylb))
287 if (p0[0] > xlb && p1[0] > xlb)
288 ncross++;
289 else if (p0[0] > xlb || p1[0] > xlb)
290 ncross += (p1[1] > p0[1]) ^
291 ((p0[1]-y)*(p1[0]-x) >
292 (p0[0]-x)*(p1[1]-y));
293 p0 = p1;
294 p1 += 2;
295 }
296 return(ncross & 01);
297 }