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.6 by greg, Mon Jul 22 13:02:27 1991 UTC vs.
Revision 2.3 by greg, Tue Jun 16 13:24:23 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1990 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 char  *libpath;
74 +
75   extern char  *fgetword();
76  
77 < extern GLYPH  *getglyph();
77 > TEXT  *gettext();
78  
79 < extern FONT  *getfont();
79 > TLINE  *tlalloc();
80  
74 static FONT  *fontlist = NULL;          /* our font list */
81  
76
82   text(m, r)
83   register OBJREC  *m;
84   RAY  *r;
85   {
86 <        double  v[3], y, x;
82 <        int  col, lno;
86 >        FVECT  v;
87          int  foreground;
88 <        GLYPH  *g;
85 <        register double  *ap;
86 <
87 <        if (m->oargs.nsargs - tndx(m) < 1 ||
88 <                        m->oargs.nfargs != (m->otype == PAT_BTEXT ? 11 :
89 <                                        m->otype == PAT_CTEXT ? 15 : 9))
90 <                objerror(m, USER, "bad # arguments");
91 <
92 <                                /* first, discover position in text */
93 <        ap = m->oargs.farg;
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 <        v[0] -= ap[0];
94 <        v[1] -= ap[1];
100 <        v[2] -= ap[2];
101 <        col = x = DOT(v, ap+3) / DOT(ap+3, ap+3);
102 <        lno = y = DOT(v, ap+6) / DOT(ap+6, ap+6);
103 <        x -= col;
104 <        y = (lno+1) - y;
105 <                                /* get the font character, check it */
106 <        if ((g = getglyph(m, lno, col)) == NULL)
107 <                foreground = 0;
108 <        else
109 <                foreground = inglyph(x, y, g);
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;
# Line 117 | Line 102 | RAY  *r;
102                          sprintf(errmsg, "undefined modifier \"%s\"", modname);
103                          objerror(m, USER, errmsg);
104                  }
105 <                raymixture(r, omod, OVOID, 1.0);
105 >                raytexture(r, omod);
106          } else if (m->otype == PAT_BTEXT) {
107                  if (foreground)
108 <                        scalecolor(r->pcol, ap[9]);
108 >                        scalecolor(r->pcol, m->oargs.farg[9]);
109                  else
110 <                        scalecolor(r->pcol, ap[10]);
110 >                        scalecolor(r->pcol, m->oargs.farg[10]);
111          } else { /* PAT_CTEXT */
112                  COLOR  cval;
113                  if (foreground)
114 <                        setcolor(cval, ap[9], ap[10], ap[11]);
114 >                        setcolor(cval, m->oargs.farg[9],
115 >                                        m->oargs.farg[10],
116 >                                        m->oargs.farg[11]);
117                  else
118 <                        setcolor(cval, ap[12], ap[13], ap[14]);
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 < GLYPH *
127 < getglyph(tm, lno, col)          /* get a glyph from a text description */
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;
140 int  lno;
141 int  col;
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 char  **txt;
155 >        register TLINE  *tlp;
156          register char  *s;
157  
158 <        if (lno < 0 || col < 0)
159 <                return(NULL);
160 <        if (tm->os == NULL) {
161 <                txt = (char **)malloc(2*sizeof(char **));
162 <                if (txt == NULL)
163 <                        goto memerr;
164 <                if (tm->oargs.nsargs - tndx(tm) > 1) {  /* single line */
165 <                        s = linbuf;
166 <                        for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
167 <                                strcpy(s, tm->oargs.sarg[i]);
168 <                                s += strlen(s);
169 <                                *s++ = ' ';
170 <                        }
171 <                        *--s = '\0';
172 <                        txt[0] = savqstr(linbuf);
173 <                        txt[1] = NULL;
174 <                } else {                                /* text file */
175 <                        if ((s = getpath(tm->oargs.sarg[tndx(tm)],
176 <                                        libpath, R_OK)) == NULL) {
177 <                                sprintf(errmsg, "cannot find text file \"%s\"",
178 <                                                tm->oargs.sarg[tndx(tm)]);
179 <                                error(USER, errmsg);
180 <                        }
181 <                        if ((fp = fopen(s, "r")) == NULL) {
182 <                                sprintf(errmsg, "cannot open text file \"%s\"",
183 <                                                s);
184 <                                error(SYSTEM, errmsg);
177 <                        }
178 <                        for (i=0; fgets(linbuf,sizeof(linbuf),fp)!=NULL; i++) {
179 <                                s = linbuf + strlen(linbuf) - 1;
180 <                                if (*s == '\n')
181 <                                        *s = '\0';
182 <                                txt=(char **)realloc(txt,(i+2)*sizeof(char **));
183 <                                if (txt == NULL)
184 <                                        goto memerr;
185 <                                txt[i] = savqstr(linbuf);
186 <                        }
187 <                        txt[i] = NULL;
188 <                        fclose(fp);
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 <                tm->os = (char *)txt;
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 <        txt = (char **)tm->os;
211 <        for (i = 0; i < lno; i++)
212 <                if (txt[i] == NULL)
213 <                        break;
214 <        if ((s = txt[i]) == NULL || col >= strlen(s))
215 <                return(NULL);
216 <        else
217 <                return(getfont(tm->oargs.sarg[fndx(tm)])->fg[s[col]]);
200 < memerr:
201 <        error(SYSTEM, "out of memory in getglyph");
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 < FONT *
222 < getfont(fname)                          /* return font fname */
207 < char  *fname;
221 > freetext(m)                     /* free text structures associated with m */
222 > OBJREC  *m;
223   {
224 <        char  buf[16];
225 <        FILE  *fp;
211 <        char  *pathname, *err;
212 <        int  gn, ngv, gv;
213 <        register GLYPH  *g;
214 <        register FONT  *f;
224 >        register TEXT  *tp;
225 >        register TLINE  *tlp;
226  
227 <        for (f = fontlist; f != NULL; f = f->next)
228 <                if (!strcmp(f->name, fname))
229 <                        return(f);
230 <                                                /* load the font file */
231 <        if ((pathname = getpath(fname, libpath, R_OK)) == NULL) {
232 <                sprintf(errmsg, "cannot find font file \"%s\"", fname);
233 <                error(USER, errmsg);
223 <        }
224 <        f = (FONT *)calloc(1, sizeof(FONT));
225 <        if (f == NULL)
226 <                goto memerr;
227 <        f->name = savestr(fname);
228 <        if ((fp = fopen(pathname, "r")) == NULL) {
229 <                sprintf(errmsg, "cannot open font file \"%s\"",
230 <                                pathname);
231 <                error(SYSTEM, errmsg);
232 <        }
233 <        while (fgetword(buf,sizeof(buf),fp) != NULL) {  /* get each glyph */
234 <                if (!isint(buf))
235 <                        goto nonint;
236 <                gn = atoi(buf);
237 <                if (gn < 0 || gn > 255) {
238 <                        err = "illegal";
239 <                        goto fonterr;
240 <                }
241 <                if (f->fg[gn] != NULL) {
242 <                        err = "duplicate";
243 <                        goto fonterr;
244 <                }
245 <                if (fgetword(buf,sizeof(buf),fp) == NULL || !isint(buf) ||
246 <                                (ngv = atoi(buf)) < 0 || ngv > 255) {
247 <                        err = "bad # vertices for";
248 <                        goto fonterr;
249 <                }
250 <                g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH));
251 <                if (g == NULL)
252 <                        goto memerr;
253 <                f->fg[gn] = g;
254 <                *g++ = ngv;
255 <                ngv *= 2;
256 <                while (ngv--) {
257 <                        if (fgetword(buf,sizeof(buf),fp) == NULL ||
258 <                                        !isint(buf) ||
259 <                                        (gv = atoi(buf)) < 0 || gv > 255) {
260 <                                err = "bad vertex for";
261 <                                goto fonterr;
262 <                        }
263 <                        *g++ = gv;
264 <                }
265 <        }
266 <        fclose(fp);
267 <        f->next = fontlist;
268 <        return(fontlist = f);
269 < nonint:
270 <        sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
271 <        error(USER, errmsg);
272 < fonterr:
273 <        sprintf(errmsg, "%s character (%d) in font file \"%s\"",
274 <                        err, gn, pathname);
275 <        error(USER, errmsg);
276 < memerr:
277 <        error(SYSTEM, "out of memory in fontglyph");
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 < GLYPH  *gl;
270 > register GLYPH  *gl;
271   {
272          int  n, ncross;
273          int  xlb, ylb;
274 <        register GLYPH  *p0, *p1;
274 >        register GORD  *p0, *p1;
275  
276 <        if (x < 0.0 || y < 0.0)
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 <        n = *gl++;                      /* get # of vertices */
283 <        p0 = gl + 2*(n-1);              /* connect last to first */
284 <        p1 = gl;
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--) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines