--- ray/src/rt/text.c 1992/11/10 10:33:43 2.8 +++ ray/src/rt/text.c 2004/03/30 16:13:01 2.25 @@ -1,19 +1,16 @@ -/* Copyright (c) 1991 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: text.c,v 2.25 2004/03/30 16:13:01 schorsch Exp $"; #endif - /* * text.c - functions for text patterns and mixtures. - * - * 11/12/86 */ -#include "ray.h" +#include "copyright.h" +#include "ray.h" +#include "paths.h" #include "otypes.h" - +#include "rtotypes.h" #include "font.h" /* @@ -45,8 +42,10 @@ static char SCCSid[] = "$SunId$ LBL"; * [spacing] * * Colortext is identical, except colors are given rather than - * brightnesses. Mixtext has foreground and background modifiers: + * brightnesses. * + * Mixtext has foreground and background modifiers: + * * modifier mixtext id * 4+ foremod backmod fontfile text.. * 0 @@ -77,18 +76,17 @@ typedef struct { TLINE tl; /* line list */ } TEXT; -extern char *libpath; +static TLINE * tlalloc(char *s); +static TEXT * gettext(OBJREC *tm); +static int intext(FVECT p, OBJREC *m); +static int inglyph(double x, double y, GLYPH *gl); -extern char *fgetword(); -TEXT *gettext(); - -TLINE *tlalloc(); - - -text(m, r) -register OBJREC *m; -RAY *r; +extern int +do_text( + register OBJREC *m, + RAY *r +) { FVECT v; int foreground; @@ -105,11 +103,15 @@ RAY *r; char *modname = m->oargs.sarg[foreground ? 0 : 1]; if (!strcmp(modname, VOIDID)) omod = OVOID; - else if ((omod = modifier(modname)) == OVOID) { + else if ((omod = lastmod(objndx(m), modname)) == OVOID) { sprintf(errmsg, "undefined modifier \"%s\"", modname); objerror(m, USER, errmsg); } - raytexture(r, omod); + if (rayshade(r, omod)) { + if (m->omod != OVOID) + objerror(m, USER, "inappropriate modifier"); + return(1); + } } else if (m->otype == PAT_BTEXT) { if (foreground) scalecolor(r->pcol, m->oargs.farg[9]); @@ -127,14 +129,15 @@ RAY *r; m->oargs.farg[14]); multcolor(r->pcol, cval); } + return(0); } -TLINE * -tlalloc(s) /* allocate and assign text line */ -char *s; +static TLINE * +tlalloc( /* allocate and assign text line */ + char *s +) { - extern char *strcpy(); register int siz; register TLINE *tl; @@ -142,20 +145,19 @@ char *s; if ((tl=(TLINE *)malloc(sizeof(TLINE)+siz)) == NULL || (tl->spc=(short *)malloc(siz*sizeof(short))) == NULL) error(SYSTEM, "out of memory in tlalloc"); - tl->spc = NULL; tl->next = NULL; strcpy(TLSTR(tl), s); return(tl); } -TEXT * -gettext(tm) /* get text structure for material */ -register OBJREC *tm; +static TEXT * +gettext( /* get text structure for material */ + register OBJREC *tm +) { #define R (tm->oargs.farg+3) #define D (tm->oargs.farg+6) - extern char *strcpy(), *fgets(); FVECT DxR; double d; FILE *fp; @@ -171,11 +173,14 @@ register OBJREC *tm; if (tm->oargs.nsargs - tndx(tm) < 1 || tm->oargs.nfargs < sndx(tm)) objerror(tm, USER, "bad # arguments"); if ((t = (TEXT *)malloc(sizeof(TEXT))) == NULL) - goto memerr; + error(SYSTEM, "out of memory in gettext"); /* compute vectors */ fcross(DxR, D, R); fcross(t->right, DxR, D); - d = DOT(D,D)/DOT(t->right,t->right); + d = DOT(t->right,t->right); + if (d <= FTINY*FTINY*FTINY*FTINY) + objerror(tm, USER, "illegal motion vector"); + d = DOT(D,D)/d; for (i = 0; i < 3; i++) t->right[i] *= d; fcross(t->down, R, DxR); @@ -196,7 +201,7 @@ register OBJREC *tm; tlp = tlp->next; } else { /* text file */ if ((s = getpath(tm->oargs.sarg[tndx(tm)], - libpath, R_OK)) == NULL) { + getrlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find text file \"%s\"", tm->oargs.sarg[tndx(tm)]); error(USER, errmsg); @@ -220,12 +225,9 @@ register OBJREC *tm; /* compute character spacing */ i = sndx(tm); d = i < tm->oargs.nfargs ? tm->oargs.farg[i] : 0.0; - i = d * 256.0; + i = d * 255.0; t->tl.width = 0; for (tlp = t->tl.next; tlp != NULL; tlp = tlp->next) { - if ((tlp->spc = (short *)malloc( - (strlen(TLSTR(tlp))+1)*sizeof(short))) == NULL) - goto memerr; if (i < 0) tlp->width = squeeztext(tlp->spc, TLSTR(tlp), t->f, -i); else if (i > 0) @@ -238,35 +240,38 @@ register OBJREC *tm; /* we're done */ tm->os = (char *)t; return(t); -memerr: - error(SYSTEM, "out of memory in gettext"); #undef R #undef D } -freetext(m) /* free text structures associated with m */ -OBJREC *m; +extern void +freetext( /* free text structures associated with m */ + OBJREC *m +) { - TEXT *tp; - register TLINE *tlp, *tln; + register TEXT *tp; + register TLINE *tlp; tp = (TEXT *)m->os; if (tp == NULL) return; - for (tlp = tp->tl.next; tlp != NULL; tlp = tln) { - tln = tlp->next; - free((char *)tlp->spc); - free((char *)tlp); + while ((tlp = tp->tl.next) != NULL) { + tp->tl.next = tlp->next; + free((void *)tlp->spc); + free((void *)tlp); } - free((char *)tp); + freefont(tp->f); /* release font reference */ + free((void *)tp); m->os = NULL; } -intext(p, m) /* check to see if p is in text glyph */ -FVECT p; -OBJREC *m; +static int +intext( /* check to see if p is in text glyph */ + FVECT p, + OBJREC *m +) { register TEXT *tp; register TLINE *tlp; @@ -281,15 +286,15 @@ OBJREC *m; x = DOT(v, tp->right); i = sndx(m); if (i < m->oargs.nfargs) - x *= tp->f->mwidth + 256.*fabs(m->oargs.farg[i]); + x *= tp->f->mwidth + 255.*fabs(m->oargs.farg[i]); else - x *= 256.; + x *= 255.; h = x; i = y = DOT(v, tp->down); if (x < 0.0 || y < 0.0) return(0); x -= (double)h; - y = ((i+1) - y)*256.; + y = ((i+1) - y)*255.; /* find the line position */ for (tlp = tp->tl.next; tlp != NULL; tlp = tlp->next) if (--i < 0) @@ -297,16 +302,19 @@ OBJREC *m; if (tlp == NULL || h >= tlp->width) return(0); for (i = 0; (h -= tlp->spc[i]) >= 0; i++) - if (h < 256 && inglyph(h+x, y, + if (h < 255 && inglyph(h+x, y, tp->f->fg[TLSTR(tlp)[i]&0xff])) return(1); return(0); } -inglyph(x, y, gl) /* (x,y) within font glyph gl? */ -double x, y; /* real coordinates in range [0,256) */ -register GLYPH *gl; +static int +inglyph( /* (x,y) within font glyph gl? */ + double x, /* real coordinates in range [0,255) */ + double y, + register GLYPH *gl +) { int n, ncross; int xlb, ylb; @@ -329,7 +337,7 @@ register GLYPH *gl; /* positive x axis cross test */ while (n--) { if ((p0[1]<<1 > ylb) ^ (p1[1]<<1 > ylb)) { - tv = p0[0]<<1 > xlb | (p1[0]<<1 > xlb) << 1; + tv = (p0[0]<<1 > xlb) | ((p1[0]<<1 > xlb) << 1); if (tv == 03) ncross++; else if (tv)