ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/text.c
Revision: 1.1
Committed: Thu Feb 2 10:41:47 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
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 /*
18 * A text pattern is specified as the text (a file or line),
19 * the upper left anchor point, the right motion vector, the down
20 * motion vector, and the foreground and background brightness.
21 * For a file, the description is as follows:
22 *
23 * modifier brighttext id
24 * 2 fontfile textfile
25 * 0
26 * 11
27 * Ax Ay Az
28 * Rx Ry Rz
29 * Dx Dy Dz
30 * foreground background
31 *
32 * For a single line, we use:
33 *
34 * modifier brighttext id
35 * N+2 fontfile . This is a line with N words...
36 * 0
37 * 11
38 * Ax Ay Az
39 * Rx Ry Rz
40 * Dx Dy Dz
41 * foreground background
42 *
43 * Colortext is identical, except colors are given rather than
44 * brightnesses. Mixtext has foreground and background modifiers:
45 *
46 * modifier mixtext id
47 * 4+ foremod backmod fontfile text..
48 * 0
49 * 9
50 * Ax Ay Az
51 * Rx Ry Rz
52 * Dx Dy Dz
53 */
54
55 #define fndx(m) ((m)->otype==MIX_TEXT ? 2 : 0)
56 #define tndx(m) ((m)->otype==MIX_TEXT ? 3 : 1)
57
58 extern char *libpath; /* library search path */
59
60 typedef unsigned char GLYPH;
61
62 typedef struct font {
63 GLYPH *fg[256]; /* font glyphs */
64 char *name; /* font file name */
65 struct font *next; /* next font in list */
66 } FONT;
67
68 extern GLYPH *getglyph();
69
70 extern FONT *getfont();
71
72 static FONT *fontlist = NULL; /* our font list */
73
74
75 text(m, r)
76 register OBJREC *m;
77 RAY *r;
78 {
79 double v[3], y, x;
80 int col, lno;
81 int foreground;
82 GLYPH *g;
83 register double *ap;
84
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 v[0] = r->rop[0] - ap[0];
93 v[1] = r->rop[1] - ap[1];
94 v[2] = r->rop[2] - ap[2];
95 col = x = DOT(v, ap+3) / DOT(ap+3, ap+3);
96 lno = y = DOT(v, ap+6) / DOT(ap+6, ap+6);
97 x -= col;
98 y = (lno+1) - y;
99 /* get the font character, check it */
100 if ((g = getglyph(m, lno, col)) == NULL)
101 foreground = 0;
102 else
103 foreground = inglyph(x, y, g);
104 /* modify */
105 if (m->otype == MIX_TEXT) {
106 OBJECT omod;
107 char *modname = m->oargs.sarg[foreground ? 0 : 1];
108 if (!strcmp(modname, VOIDID))
109 omod = OVOID;
110 else if ((omod = modifier(modname)) == OVOID) {
111 sprintf(errmsg, "undefined modifier \"%s\"", modname);
112 objerror(m, USER, errmsg);
113 }
114 raymixture(r, omod, OVOID, 1.0);
115 } else if (m->otype == PAT_BTEXT) {
116 if (foreground)
117 scalecolor(r->pcol, ap[9]);
118 else
119 scalecolor(r->pcol, ap[10]);
120 } else { /* PAT_CTEXT */
121 COLOR cval;
122 if (foreground)
123 setcolor(cval, ap[9], ap[10], ap[11]);
124 else
125 setcolor(cval, ap[12], ap[13], ap[14]);
126 multcolor(r->pcol, cval);
127 }
128 }
129
130
131 GLYPH *
132 getglyph(tm, lno, col) /* get a glyph from a text description */
133 register OBJREC *tm;
134 int lno;
135 int col;
136 {
137 extern char *strcpy(), *fgets();
138 FILE *fp;
139 char linbuf[512];
140 register int i;
141 register char **txt;
142 register char *s;
143
144 if (lno < 0 || col < 0)
145 return(NULL);
146 if (tm->os == NULL) {
147 txt = (char **)malloc(2*sizeof(char **));
148 if (txt == NULL)
149 goto memerr;
150 if (tm->oargs.nsargs - tndx(tm) > 1) { /* single line */
151 s = linbuf;
152 for (i = tndx(tm)+1; i < tm->oargs.nsargs; i++) {
153 strcpy(s, tm->oargs.sarg[i]);
154 s += strlen(s);
155 *s++ = ' ';
156 }
157 *--s = '\0';
158 txt[0] = savqstr(linbuf);
159 txt[1] = NULL;
160 } else { /* text file */
161 if ((s = getpath(tm->oargs.sarg[tndx(tm)],
162 libpath)) == NULL) {
163 sprintf(errmsg, "cannot find text file \"%s\"",
164 tm->oargs.sarg[tndx(tm)]);
165 error(USER, errmsg);
166 }
167 if ((fp = fopen(s, "r")) == NULL) {
168 sprintf(errmsg, "cannot open text file \"%s\"",
169 s);
170 error(SYSTEM, errmsg);
171 }
172 for (i=0; fgets(linbuf,sizeof(linbuf),fp)!=NULL; i++) {
173 s = linbuf + strlen(linbuf) - 1;
174 if (*s == '\n')
175 *s = '\0';
176 txt=(char **)realloc(txt,(i+2)*sizeof(char **));
177 if (txt == NULL)
178 goto memerr;
179 txt[i] = savqstr(linbuf);
180 }
181 txt[i] = NULL;
182 fclose(fp);
183 }
184 tm->os = (char *)txt;
185 }
186 txt = (char **)tm->os;
187 for (i = 0; i < lno; i++)
188 if (txt[i] == NULL)
189 break;
190 if ((s = txt[i]) == NULL || col >= strlen(s))
191 return(NULL);
192 else
193 return(getfont(tm->oargs.sarg[fndx(tm)])->fg[s[col]]);
194 memerr:
195 error(SYSTEM, "out of memory in getglyph");
196 }
197
198
199 FONT *
200 getfont(fname) /* return font fname */
201 char *fname;
202 {
203 FILE *fp;
204 char *pathname, *err;
205 int gn, ngv, gv;
206 register GLYPH *g;
207 register FONT *f;
208
209 for (f = fontlist; f != NULL; f = f->next)
210 if (!strcmp(f->name, fname))
211 return(f);
212 /* load the font file */
213 if ((pathname = getpath(fname, libpath)) == NULL) {
214 sprintf(errmsg, "cannot find font file \"%s\"", fname);
215 error(USER, errmsg);
216 }
217 f = (FONT *)calloc(1, sizeof(FONT));
218 if (f == NULL)
219 goto memerr;
220 f->name = savestr(fname);
221 if ((fp = fopen(pathname, "r")) == NULL) {
222 sprintf(errmsg, "cannot open font file \"%s\"",
223 pathname);
224 error(SYSTEM, errmsg);
225 }
226 while (fscanf(fp, "%d", &gn) == 1) { /* get each glyph */
227 if (gn < 0 || gn > 255) {
228 err = "illegal";
229 goto fonterr;
230 }
231 if (f->fg[gn] != NULL) {
232 err = "duplicate";
233 goto fonterr;
234 }
235 if (fscanf(fp, "%d", &ngv) != 1 ||
236 ngv < 0 || ngv > 255) {
237 err = "bad # vertices for";
238 goto fonterr;
239 }
240 g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH));
241 if (g == NULL)
242 goto memerr;
243 f->fg[gn] = g;
244 *g++ = ngv;
245 ngv *= 2;
246 while (ngv--) {
247 if (fscanf(fp, "%d", &gv) != 1 ||
248 gv < 0 || gv > 255) {
249 err = "bad vertex for";
250 goto fonterr;
251 }
252 *g++ = gv;
253 }
254 }
255 fclose(fp);
256 f->next = fontlist;
257 return(fontlist = f);
258 fonterr:
259 sprintf(errmsg, "%s character (%d) in font file \"%s\"",
260 err, gn, pathname);
261 error(USER, errmsg);
262 memerr:
263 error(SYSTEM, "out of memory in fontglyph");
264 }
265
266
267 inglyph(x, y, gl) /* (x,y) within font glyph gl? */
268 double x, y;
269 GLYPH *gl;
270 {
271 int n, ncross;
272 int xlb, ylb;
273 register GLYPH *p0, *p1;
274
275 if (x < 0.0 || y < 0.0)
276 return(0);
277 xlb = x *= 255.0; /* get glyph coordinates */
278 ylb = y *= 255.0;
279 n = *gl++; /* get # of vertices */
280 p0 = gl + 2*(n-1); /* connect last to first */
281 p1 = gl;
282 ncross = 0;
283 /* positive x axis cross test */
284 while (n--) {
285 if ((p0[1] > ylb) ^ (p1[1] > ylb))
286 if (p0[0] > xlb && p1[0] > xlb)
287 ncross++;
288 else if (p0[0] > xlb || p1[0] > xlb)
289 ncross += (p1[1] > p0[1]) ^
290 ((p0[1]-y)*(p1[0]-x) >
291 (p0[0]-x)*(p1[1]-y));
292 p0 = p1;
293 p1 += 2;
294 }
295 return(ncross & 01);
296 }