ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/text.c
(Generate patch)

Comparing ray/src/rt/text.c (file contents):
Revision 1.2 by greg, Tue Apr 11 13:30:35 1989 UTC vs.
Revision 2.1 by greg, Tue Nov 12 17:10:02 1991 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 Regents of the University of California */
1 > /* Copyright (c) 1991 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 65 | Line 65 | typedef struct font {
65          struct font  *next;             /* next font in list */
66   }  FONT;
67  
68 < extern GLYPH  *getglyph();
68 > typedef struct tline {
69 >        struct tline  *next;            /* pointer to next line */
70 >                                        /* followed by the string */
71 > }  TLINE;
72  
73 < extern FONT  *getfont();
73 > #define  TLSTR(l)       ((char *)((l)+1))
74  
75 + typedef struct {
76 +        FVECT  right, down;             /* right and down unit vectors */
77 +        FONT  *f;                       /* our font */
78 +        TLINE  tl;                      /* line list */
79 + }  TEXT;
80 +
81 + extern char  *fgetword();
82 +
83 + TEXT  *gettext();
84 +
85 + TLINE  *tlalloc();
86 +
87 + FONT  *getfont();
88 +
89   static FONT  *fontlist = NULL;          /* our font list */
90  
91  
# Line 76 | Line 93 | text(m, r)
93   register OBJREC  *m;
94   RAY  *r;
95   {
96 <        double  v[3], y, x;
80 <        int  col, lno;
96 >        FVECT  v;
97          int  foreground;
98 <        GLYPH  *g;
99 <        register double  *ap;
100 <
85 <        if (m->oargs.nsargs - tndx(m) < 1 ||
86 <                        m->oargs.nfargs != (m->otype == PAT_BTEXT ? 11 :
87 <                                        m->otype == PAT_CTEXT ? 15 : 9))
88 <                objerror(m, USER, "bad # arguments");
89 <
90 <                                /* first, discover position in text */
91 <        ap = m->oargs.farg;
92 <        multp3(v, r->rop, r->robx);
93 <        v[0] -= ap[0];
94 <        v[1] -= ap[1];
95 <        v[2] -= ap[2];
96 <        col = x = DOT(v, ap+3) / DOT(ap+3, ap+3);
97 <        lno = y = DOT(v, ap+6) / DOT(ap+6, ap+6);
98 <        x -= col;
99 <        y = (lno+1) - y;
100 <                                /* get the font character, check it */
101 <        if ((g = getglyph(m, lno, col)) == NULL)
102 <                foreground = 0;
98 >                                /* get transformed position */
99 >        if (r->rox != NULL)
100 >                multp3(v, r->rop, r->rox->b.xfm);
101          else
102 <                foreground = inglyph(x, y, g);
102 >                VCOPY(v, r->rop);
103 >                                /* check if we are within a text glyph */
104 >        foreground = intext(v, m);
105                                  /* modify */
106          if (m->otype == MIX_TEXT) {
107                  OBJECT  omod;
# Line 112 | Line 112 | RAY  *r;
112                          sprintf(errmsg, "undefined modifier \"%s\"", modname);
113                          objerror(m, USER, errmsg);
114                  }
115 <                raymixture(r, omod, OVOID, 1.0);
115 >                raytexture(r, omod);
116          } else if (m->otype == PAT_BTEXT) {
117                  if (foreground)
118 <                        scalecolor(r->pcol, ap[9]);
118 >                        scalecolor(r->pcol, m->oargs.farg[9]);
119                  else
120 <                        scalecolor(r->pcol, ap[10]);
120 >                        scalecolor(r->pcol, m->oargs.farg[10]);
121          } else { /* PAT_CTEXT */
122                  COLOR  cval;
123                  if (foreground)
124 <                        setcolor(cval, ap[9], ap[10], ap[11]);
124 >                        setcolor(cval, m->oargs.farg[9],
125 >                                        m->oargs.farg[10],
126 >                                        m->oargs.farg[11]);
127                  else
128 <                        setcolor(cval, ap[12], ap[13], ap[14]);
128 >                        setcolor(cval, m->oargs.farg[12],
129 >                                        m->oargs.farg[13],
130 >                                        m->oargs.farg[14]);
131                  multcolor(r->pcol, cval);
132          }
133   }
134  
135  
136 < GLYPH *
137 < getglyph(tm, lno, col)          /* get a glyph from a text description */
136 > TLINE *
137 > tlalloc(s)                      /* allocate and assign text line */
138 > char  *s;
139 > {
140 >        extern char  *strcpy();
141 >        register TLINE  *tl;
142 >
143 >        tl = (TLINE *)malloc(sizeof(TLINE)+1+strlen(s));
144 >        if (tl == NULL)
145 >                error(SYSTEM, "out of memory in tlalloc");
146 >        tl->next = NULL;
147 >        strcpy(TLSTR(tl), s);
148 >        return(tl);
149 > }
150 >
151 >
152 > TEXT *
153 > gettext(tm)                     /* get text structure for material */
154   register OBJREC  *tm;
135 int  lno;
136 int  col;
155   {
156 + #define  R      (tm->oargs.farg+3)
157 + #define  D      (tm->oargs.farg+6)
158          extern char  *strcpy(), *fgets();
159 +        FVECT  DxR;
160 +        double  d;
161          FILE  *fp;
162          char  linbuf[512];
163 +        TEXT  *t;
164          register int  i;
165 <        register char  **txt;
165 >        register TLINE  *tlp;
166          register char  *s;
167  
168 <        if (lno < 0 || col < 0)
169 <                return(NULL);
170 <        if (tm->os == NULL) {
171 <                txt = (char **)malloc(2*sizeof(char **));
172 <                if (txt == NULL)
173 <                        goto memerr;
174 <                if (tm->oargs.nsargs - tndx(tm) > 1) {  /* single line */
175 <                        s = linbuf;
176 <                        for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
177 <                                strcpy(s, tm->oargs.sarg[i]);
178 <                                s += strlen(s);
179 <                                *s++ = ' ';
180 <                        }
181 <                        *--s = '\0';
182 <                        txt[0] = savqstr(linbuf);
183 <                        txt[1] = NULL;
184 <                } else {                                /* text file */
185 <                        if ((s = getpath(tm->oargs.sarg[tndx(tm)],
186 <                                        libpath)) == NULL) {
187 <                                sprintf(errmsg, "cannot find text file \"%s\"",
188 <                                                tm->oargs.sarg[tndx(tm)]);
189 <                                error(USER, errmsg);
190 <                        }
191 <                        if ((fp = fopen(s, "r")) == NULL) {
192 <                                sprintf(errmsg, "cannot open text file \"%s\"",
193 <                                                s);
194 <                                error(SYSTEM, errmsg);
172 <                        }
173 <                        for (i=0; fgets(linbuf,sizeof(linbuf),fp)!=NULL; i++) {
174 <                                s = linbuf + strlen(linbuf) - 1;
175 <                                if (*s == '\n')
176 <                                        *s = '\0';
177 <                                txt=(char **)realloc(txt,(i+2)*sizeof(char **));
178 <                                if (txt == NULL)
179 <                                        goto memerr;
180 <                                txt[i] = savqstr(linbuf);
181 <                        }
182 <                        txt[i] = NULL;
183 <                        fclose(fp);
168 >        if ((t = (TEXT *)tm->os) != NULL)
169 >                return(t);
170 >                                                /* check arguments */
171 >        if (tm->oargs.nsargs - tndx(tm) < 1 ||
172 >                        tm->oargs.nfargs != (tm->otype == PAT_BTEXT ? 11 :
173 >                                        tm->otype == PAT_CTEXT ? 15 : 9))
174 >                objerror(tm, USER, "bad # arguments");
175 >        if ((t = (TEXT *)malloc(sizeof(TEXT))) == NULL)
176 >                error(SYSTEM, "out of memory in gettext");
177 >                                                /* compute vectors */
178 >        fcross(DxR, D, R);
179 >        fcross(t->right, DxR, D);
180 >        d = DOT(D,D)/DOT(t->right,t->right);
181 >        for (i = 0; i < 3; i++)
182 >                t->right[i] *= d;
183 >        fcross(t->down, R, DxR);
184 >        d = DOT(R,R)/DOT(t->down,t->down);
185 >        for (i = 0; i < 3; i++)
186 >                t->down[i] *= d;
187 >                                                /* get text */
188 >        tlp = &t->tl;
189 >        if (tm->oargs.nsargs - tndx(tm) > 1) {  /* single line */
190 >                s = linbuf;
191 >                for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
192 >                        strcpy(s, tm->oargs.sarg[i]);
193 >                        s += strlen(s);
194 >                        *s++ = ' ';
195                  }
196 <                tm->os = (char *)txt;
196 >                *--s = '\0';
197 >                tlp->next = tlalloc(linbuf);
198 >                tlp = tlp->next;
199 >        } else {                                /* text file */
200 >                if ((s = getpath(tm->oargs.sarg[tndx(tm)],
201 >                                libpath, R_OK)) == NULL) {
202 >                        sprintf(errmsg, "cannot find text file \"%s\"",
203 >                                        tm->oargs.sarg[tndx(tm)]);
204 >                        error(USER, errmsg);
205 >                }
206 >                if ((fp = fopen(s, "r")) == NULL) {
207 >                        sprintf(errmsg, "cannot open text file \"%s\"",
208 >                                        s);
209 >                        error(SYSTEM, errmsg);
210 >                }
211 >                while (fgets(linbuf, sizeof(linbuf), fp) != NULL) {
212 >                        s = linbuf + strlen(linbuf) - 1;
213 >                        if (*s == '\n')
214 >                                *s = '\0';
215 >                        tlp->next = tlalloc(linbuf);
216 >                        tlp = tlp->next;
217 >                }
218 >                fclose(fp);
219          }
220 <        txt = (char **)tm->os;
221 <        for (i = 0; i < lno; i++)
222 <                if (txt[i] == NULL)
220 >        tlp->next = NULL;
221 >                                                /* get the font */
222 >        t->f = getfont(tm->oargs.sarg[fndx(tm)]);
223 >                                                /* we're done */
224 >        tm->os = (char *)t;
225 >        return(t);
226 > #undef  R
227 > #undef  D
228 > }
229 >
230 >
231 > freetext(m)                     /* free text structures associated with m */
232 > OBJREC  *m;
233 > {
234 >        register TEXT  *tp;
235 >        register TLINE  *tlp;
236 >
237 >        tp = (TEXT *)m->os;
238 >        if (tp == NULL)
239 >                return;
240 >        for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next);
241 >                free((char *)tlp);
242 >        free((char *)tp);
243 >        m->os = NULL;
244 > }
245 >
246 >
247 > intext(p, m)                    /* check to see if p is in text glyph */
248 > FVECT  p;
249 > OBJREC  *m;
250 > {
251 >        register TEXT  *tp;
252 >        register TLINE  *tlp;
253 >        FVECT  v;
254 >        double  y, x;
255 >        int  col;
256 >        register int  lno;
257 >                                /* first, compute position in text */
258 >        tp = gettext(m);
259 >        v[0] = p[0] - m->oargs.farg[0];
260 >        v[1] = p[1] - m->oargs.farg[1];
261 >        v[2] = p[2] - m->oargs.farg[2];
262 >        col = x = DOT(v, tp->right);
263 >        lno = y = DOT(v, tp->down);
264 >        if (x < 0.0 || y < 0.0)
265 >                return(0);
266 >        x -= (double)col;
267 >        y = (lno+1) - y;
268 >                                /* get the font character */
269 >        for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next)
270 >                if (--lno < 0)
271                          break;
272 <        if ((s = txt[i]) == NULL || col >= strlen(s))
273 <                return(NULL);
274 <        else
194 <                return(getfont(tm->oargs.sarg[fndx(tm)])->fg[s[col]]);
195 < memerr:
196 <        error(SYSTEM, "out of memory in getglyph");
272 >        if (tlp == NULL || col >= strlen(TLSTR(tlp)))
273 >                return(0);
274 >        return(inglyph(x, y, tp->f->fg[TLSTR(tlp)[col]]));
275   }
276  
277  
# Line 201 | Line 279 | FONT *
279   getfont(fname)                          /* return font fname */
280   char  *fname;
281   {
282 +        char  buf[16];
283          FILE  *fp;
284          char  *pathname, *err;
285          int  gn, ngv, gv;
# Line 211 | Line 290 | char  *fname;
290                  if (!strcmp(f->name, fname))
291                          return(f);
292                                                  /* load the font file */
293 <        if ((pathname = getpath(fname, libpath)) == NULL) {
293 >        if ((pathname = getpath(fname, libpath, R_OK)) == NULL) {
294                  sprintf(errmsg, "cannot find font file \"%s\"", fname);
295                  error(USER, errmsg);
296          }
# Line 224 | Line 303 | char  *fname;
303                                  pathname);
304                  error(SYSTEM, errmsg);
305          }
306 <        while (fscanf(fp, "%d", &gn) == 1) {    /* get each glyph */
306 >        while (fgetword(buf,sizeof(buf),fp) != NULL) {  /* get each glyph */
307 >                if (!isint(buf))
308 >                        goto nonint;
309 >                gn = atoi(buf);
310                  if (gn < 0 || gn > 255) {
311                          err = "illegal";
312                          goto fonterr;
# Line 233 | Line 315 | char  *fname;
315                          err = "duplicate";
316                          goto fonterr;
317                  }
318 <                if (fscanf(fp, "%d", &ngv) != 1 ||
319 <                                ngv < 0 || ngv > 255) {
318 >                if (fgetword(buf,sizeof(buf),fp) == NULL || !isint(buf) ||
319 >                                (ngv = atoi(buf)) < 0 || ngv > 255) {
320                          err = "bad # vertices for";
321                          goto fonterr;
322                  }
# Line 245 | Line 327 | char  *fname;
327                  *g++ = ngv;
328                  ngv *= 2;
329                  while (ngv--) {
330 <                        if (fscanf(fp, "%d", &gv) != 1 ||
331 <                                        gv < 0 || gv > 255) {
330 >                        if (fgetword(buf,sizeof(buf),fp) == NULL ||
331 >                                        !isint(buf) ||
332 >                                        (gv = atoi(buf)) < 0 || gv > 255) {
333                                  err = "bad vertex for";
334                                  goto fonterr;
335                          }
# Line 256 | Line 339 | char  *fname;
339          fclose(fp);
340          f->next = fontlist;
341          return(fontlist = f);
342 + nonint:
343 +        sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
344 +        error(USER, errmsg);
345   fonterr:
346          sprintf(errmsg, "%s character (%d) in font file \"%s\"",
347                          err, gn, pathname);
# Line 273 | Line 359 | GLYPH  *gl;
359          int  xlb, ylb;
360          register GLYPH  *p0, *p1;
361  
362 <        if (x < 0.0 || y < 0.0)
362 >        if (gl == NULL)
363                  return(0);
364 <        xlb = x *= 255.0;               /* get glyph coordinates */
365 <        ylb = y *= 255.0;
364 >        x *= 256.0;                     /* get glyph coordinates */
365 >        y *= 256.0;
366 >        xlb = x + 0.5;
367 >        ylb = y + 0.5;
368          n = *gl++;                      /* get # of vertices */
369          p0 = gl + 2*(n-1);              /* connect last to first */
370          p1 = gl;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines