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.2 by greg, Sat Jun 6 07:40:23 1992 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 14 | Line 14 | static char SCCSid[] = "$SunId$ LBL";
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
# Line 55 | Line 57 | static char SCCSid[] = "$SunId$ LBL";
57   #define  fndx(m)        ((m)->otype==MIX_TEXT ? 2 : 0)
58   #define  tndx(m)        ((m)->otype==MIX_TEXT ? 3 : 1)
59  
60 < extern char  *libpath;                  /* library search path */
60 > typedef struct tline {
61 >        struct tline  *next;            /* pointer to next line */
62 >                                        /* followed by the string */
63 > }  TLINE;
64  
65 < typedef unsigned char  GLYPH;
65 > #define  TLSTR(l)       ((char *)((l)+1))
66  
67 < typedef struct font {
68 <        GLYPH  *fg[256];                /* font glyphs */
69 <        char  *name;                    /* font file name */
70 <        struct font  *next;             /* next font in list */
71 < }  FONT;
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 GLYPH  *getglyph();
73 > extern char  *fgetword();
74  
75 < extern FONT  *getfont();
75 > TEXT  *gettext();
76  
77 < static FONT  *fontlist = NULL;          /* our font list */
77 > TLINE  *tlalloc();
78  
79  
80   text(m, r)
81   register OBJREC  *m;
82   RAY  *r;
83   {
84 <        double  v[3], y, x;
80 <        int  col, lno;
84 >        FVECT  v;
85          int  foreground;
86 <        GLYPH  *g;
87 <        register double  *ap;
88 <
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;
86 >                                /* get transformed position */
87 >        if (r->rox != NULL)
88 >                multp3(v, r->rop, r->rox->b.xfm);
89          else
90 <                foreground = inglyph(x, y, g);
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;
# Line 112 | Line 100 | RAY  *r;
100                          sprintf(errmsg, "undefined modifier \"%s\"", modname);
101                          objerror(m, USER, errmsg);
102                  }
103 <                raymixture(r, omod, OVOID, 1.0);
103 >                raytexture(r, omod);
104          } else if (m->otype == PAT_BTEXT) {
105                  if (foreground)
106 <                        scalecolor(r->pcol, ap[9]);
106 >                        scalecolor(r->pcol, m->oargs.farg[9]);
107                  else
108 <                        scalecolor(r->pcol, ap[10]);
108 >                        scalecolor(r->pcol, m->oargs.farg[10]);
109          } else { /* PAT_CTEXT */
110                  COLOR  cval;
111                  if (foreground)
112 <                        setcolor(cval, ap[9], ap[10], ap[11]);
112 >                        setcolor(cval, m->oargs.farg[9],
113 >                                        m->oargs.farg[10],
114 >                                        m->oargs.farg[11]);
115                  else
116 <                        setcolor(cval, ap[12], ap[13], ap[14]);
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 < GLYPH *
125 < getglyph(tm, lno, col)          /* get a glyph from a text description */
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;
135 int  lno;
136 int  col;
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 char  **txt;
153 >        register TLINE  *tlp;
154          register char  *s;
155  
156 <        if (lno < 0 || col < 0)
157 <                return(NULL);
158 <        if (tm->os == NULL) {
159 <                txt = (char **)malloc(2*sizeof(char **));
160 <                if (txt == NULL)
161 <                        goto memerr;
162 <                if (tm->oargs.nsargs - tndx(tm) > 1) {  /* single line */
163 <                        s = linbuf;
164 <                        for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
165 <                                strcpy(s, tm->oargs.sarg[i]);
166 <                                s += strlen(s);
167 <                                *s++ = ' ';
168 <                        }
169 <                        *--s = '\0';
170 <                        txt[0] = savqstr(linbuf);
171 <                        txt[1] = NULL;
172 <                } else {                                /* text file */
173 <                        if ((s = getpath(tm->oargs.sarg[tndx(tm)],
174 <                                        libpath)) == NULL) {
175 <                                sprintf(errmsg, "cannot find text file \"%s\"",
176 <                                                tm->oargs.sarg[tndx(tm)]);
177 <                                error(USER, errmsg);
178 <                        }
179 <                        if ((fp = fopen(s, "r")) == NULL) {
180 <                                sprintf(errmsg, "cannot open text file \"%s\"",
181 <                                                s);
182 <                                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);
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 <                tm->os = (char *)txt;
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 <        txt = (char **)tm->os;
209 <        for (i = 0; i < lno; i++)
210 <                if (txt[i] == NULL)
211 <                        break;
212 <        if ((s = txt[i]) == NULL || col >= strlen(s))
213 <                return(NULL);
214 <        else
215 <                return(getfont(tm->oargs.sarg[fndx(tm)])->fg[s[col]]);
195 < memerr:
196 <        error(SYSTEM, "out of memory in getglyph");
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 < FONT *
220 < getfont(fname)                          /* return font fname */
202 < char  *fname;
219 > freetext(m)                     /* free text structures associated with m */
220 > OBJREC  *m;
221   {
222 <        FILE  *fp;
223 <        char  *pathname, *err;
206 <        int  gn, ngv, gv;
207 <        register GLYPH  *g;
208 <        register FONT  *f;
222 >        register TEXT  *tp;
223 >        register TLINE  *tlp;
224  
225 <        for (f = fontlist; f != NULL; f = f->next)
226 <                if (!strcmp(f->name, fname))
227 <                        return(f);
228 <                                                /* load the font file */
229 <        if ((pathname = getpath(fname, libpath)) == NULL) {
230 <                sprintf(errmsg, "cannot find font file \"%s\"", fname);
231 <                error(USER, errmsg);
217 <        }
218 <        f = (FONT *)calloc(1, sizeof(FONT));
219 <        if (f == NULL)
220 <                goto memerr;
221 <        f->name = savestr(fname);
222 <        if ((fp = fopen(pathname, "r")) == NULL) {
223 <                sprintf(errmsg, "cannot open font file \"%s\"",
224 <                                pathname);
225 <                error(SYSTEM, errmsg);
226 <        }
227 <        while (fscanf(fp, "%d", &gn) == 1) {    /* get each glyph */
228 <                if (gn < 0 || gn > 255) {
229 <                        err = "illegal";
230 <                        goto fonterr;
231 <                }
232 <                if (f->fg[gn] != NULL) {
233 <                        err = "duplicate";
234 <                        goto fonterr;
235 <                }
236 <                if (fscanf(fp, "%d", &ngv) != 1 ||
237 <                                ngv < 0 || ngv > 255) {
238 <                        err = "bad # vertices for";
239 <                        goto fonterr;
240 <                }
241 <                g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH));
242 <                if (g == NULL)
243 <                        goto memerr;
244 <                f->fg[gn] = g;
245 <                *g++ = ngv;
246 <                ngv *= 2;
247 <                while (ngv--) {
248 <                        if (fscanf(fp, "%d", &gv) != 1 ||
249 <                                        gv < 0 || gv > 255) {
250 <                                err = "bad vertex for";
251 <                                goto fonterr;
252 <                        }
253 <                        *g++ = gv;
254 <                }
255 <        }
256 <        fclose(fp);
257 <        f->next = fontlist;
258 <        return(fontlist = f);
259 < fonterr:
260 <        sprintf(errmsg, "%s character (%d) in font file \"%s\"",
261 <                        err, gn, pathname);
262 <        error(USER, errmsg);
263 < memerr:
264 <        error(SYSTEM, "out of memory in fontglyph");
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 GLYPH  *p0, *p1;
272 >        register GORD  *p0, *p1;
273  
274 <        if (x < 0.0 || y < 0.0)
274 >        if (gl == NULL)
275                  return(0);
276 <        xlb = x *= 255.0;               /* get glyph coordinates */
277 <        ylb = y *= 255.0;
278 <        n = *gl++;                      /* get # of vertices */
279 <        p0 = gl + 2*(n-1);              /* connect last to first */
280 <        p1 = gl;
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--) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines