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

# User Rev Content
1 greg 1.7 /* Copyright (c) 1991 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 greg 2.2 #include "font.h"
18    
19 greg 1.1 /*
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 greg 1.8 typedef struct tline {
61     struct tline *next; /* pointer to next line */
62     /* followed by the string */
63     } TLINE;
64    
65 greg 1.9 #define TLSTR(l) ((char *)((l)+1))
66 greg 1.8
67 greg 1.7 typedef struct {
68     FVECT right, down; /* right and down unit vectors */
69     FONT *f; /* our font */
70 greg 1.8 TLINE tl; /* line list */
71 greg 1.7 } TEXT;
72    
73 greg 1.6 extern char *fgetword();
74    
75 greg 1.7 TEXT *gettext();
76 greg 1.1
77 greg 1.8 TLINE *tlalloc();
78    
79 greg 1.1
80     text(m, r)
81     register OBJREC *m;
82     RAY *r;
83     {
84 greg 1.10 FVECT v;
85 greg 1.1 int foreground;
86 greg 1.7 /* get transformed position */
87 greg 1.4 if (r->rox != NULL)
88     multp3(v, r->rop, r->rox->b.xfm);
89     else
90     VCOPY(v, r->rop);
91 greg 1.7 /* check if we are within a text glyph */
92     foreground = intext(v, m);
93 greg 1.1 /* 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 greg 1.7 raytexture(r, omod);
104 greg 1.1 } else if (m->otype == PAT_BTEXT) {
105     if (foreground)
106 greg 1.7 scalecolor(r->pcol, m->oargs.farg[9]);
107 greg 1.1 else
108 greg 1.7 scalecolor(r->pcol, m->oargs.farg[10]);
109 greg 1.1 } else { /* PAT_CTEXT */
110     COLOR cval;
111     if (foreground)
112 greg 1.7 setcolor(cval, m->oargs.farg[9],
113     m->oargs.farg[10],
114     m->oargs.farg[11]);
115 greg 1.1 else
116 greg 1.7 setcolor(cval, m->oargs.farg[12],
117     m->oargs.farg[13],
118     m->oargs.farg[14]);
119 greg 1.1 multcolor(r->pcol, cval);
120     }
121     }
122    
123    
124 greg 1.8 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 greg 1.7 TEXT *
141     gettext(tm) /* get text structure for material */
142 greg 1.1 register OBJREC *tm;
143     {
144 greg 1.7 #define R (tm->oargs.farg+3)
145     #define D (tm->oargs.farg+6)
146 greg 1.1 extern char *strcpy(), *fgets();
147 greg 1.7 FVECT DxR;
148     double d;
149 greg 1.1 FILE *fp;
150     char linbuf[512];
151 greg 1.8 TEXT *t;
152 greg 1.1 register int i;
153 greg 1.8 register TLINE *tlp;
154 greg 1.1 register char *s;
155    
156 greg 1.7 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 greg 1.8 error(SYSTEM, "out of memory in gettext");
165 greg 1.7 /* compute vectors */
166     fcross(DxR, D, R);
167     fcross(t->right, DxR, D);
168 greg 1.9 d = DOT(D,D)/DOT(t->right,t->right);
169 greg 1.7 for (i = 0; i < 3; i++)
170     t->right[i] *= d;
171     fcross(t->down, R, DxR);
172 greg 1.9 d = DOT(R,R)/DOT(t->down,t->down);
173 greg 1.7 for (i = 0; i < 3; i++)
174     t->down[i] *= d;
175     /* get text */
176 greg 1.8 tlp = &t->tl;
177 greg 1.7 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 greg 1.1 }
184 greg 1.7 *--s = '\0';
185 greg 1.8 tlp->next = tlalloc(linbuf);
186     tlp = tlp->next;
187 greg 1.7 } 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 greg 1.8 while (fgets(linbuf, sizeof(linbuf), fp) != NULL) {
200 greg 1.7 s = linbuf + strlen(linbuf) - 1;
201     if (*s == '\n')
202     *s = '\0';
203 greg 1.8 tlp->next = tlalloc(linbuf);
204     tlp = tlp->next;
205 greg 1.7 }
206     fclose(fp);
207 greg 1.1 }
208 greg 1.8 tlp->next = NULL;
209 greg 1.7 /* 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 greg 1.1 }
217    
218    
219 greg 1.7 freetext(m) /* free text structures associated with m */
220     OBJREC *m;
221     {
222     register TEXT *tp;
223 greg 1.8 register TLINE *tlp;
224 greg 1.7
225     tp = (TEXT *)m->os;
226     if (tp == NULL)
227     return;
228 greg 1.8 for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next);
229 greg 1.9 free((char *)tlp);
230 greg 1.7 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 greg 1.8 OBJREC *m;
238 greg 1.7 {
239     register TEXT *tp;
240 greg 1.8 register TLINE *tlp;
241 greg 1.10 FVECT v;
242     double y, x;
243 greg 1.8 int col;
244     register int lno;
245 greg 1.7 /* first, compute position in text */
246 greg 1.9 tp = gettext(m);
247 greg 1.7 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 greg 1.8 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 greg 1.7 return(0);
262 greg 2.2 return(inglyph(x, y, tp->f->fg[TLSTR(tlp)[col]&0xff]));
263 greg 1.7 }
264    
265    
266 greg 1.1 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 greg 2.2 register GORD *p0, *p1;
273 greg 1.1
274 greg 1.7 if (gl == NULL)
275 greg 1.1 return(0);
276 greg 1.5 x *= 256.0; /* get glyph coordinates */
277     y *= 256.0;
278     xlb = x + 0.5;
279     ylb = y + 0.5;
280 greg 2.2 n = gl->nverts; /* get # of vertices */
281     p0 = gvlist(gl) + 2*(n-1); /* connect last to first */
282     p1 = gvlist(gl);
283 greg 1.1 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     }