ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/rplot.c
Revision: 1.2
Committed: Mon Jul 21 22:30:18 2003 UTC (21 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -2 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rplot.c,v 1.1 2003/02/22 02:07:26 greg Exp $";
3 #endif
4 /*
5 * Plotting routines for meta-files to raster files
6 */
7
8
9 #include "meta.h"
10
11 #include "plot.h"
12
13 #include "rast.h"
14
15
16 int minwidth = 0;
17
18 static PLIST inqueue = {NULL, NULL};
19
20 static PRIMITIVE nextp;
21
22
23 plot(infp) /* plot meta-file */
24
25 FILE *infp;
26
27 {
28
29 do {
30 readp(&nextp, infp);
31 initplot();
32 while (inqueue.ptop != NULL || isprim(nextp.com))
33 plotblock(infp);
34 doglobal(&nextp);
35 fargs(&nextp);
36 } while (nextp.com != PEOF);
37
38 }
39
40
41
42
43
44 initplot() /* initialize this plot */
45
46 {
47 int i;
48
49 thispage();
50 /* allocate block */
51 if (outblock.xright <= 0) {
52 for (i = 0; i < NUMSCANS; i++)
53 if ((outblock.cols[i] = (unsigned char *)malloc(dxsize)) == NULL)
54 error(SYSTEM, "out of memory in initplot");
55 }
56 outblock.xleft = 0;
57 outblock.xright = dxsize-1;
58 if (ydown) {
59 outblock.ytop = dysize+NUMSCANS-1;
60 outblock.ybot = dysize;
61 } else {
62 outblock.ytop = -1;
63 outblock.ybot = -NUMSCANS;
64 }
65
66 }
67
68
69
70
71
72 doglobal(g) /* execute a global command */
73
74 PRIMITIVE *g;
75
76 {
77 char c;
78 int tty;
79
80 switch (g->com) {
81
82 case PEOF:
83 break;
84
85 case PEOP:
86 if (g->arg0 & 0200) /* advance page */
87 nextpage();
88 else
89 error(USER, "illegal continue direction in doglobal");
90 break;
91
92 case PSET:
93 set(g->arg0, g->args);
94 break;
95
96 case PUNSET:
97 unset(g->arg0);
98 break;
99
100 case PRESET:
101 reset(g->arg0);
102 break;
103
104 default:
105 sprintf(errmsg, "unknown command '%c' in doglobal", g->com);
106 error(WARNING, errmsg);
107 break;
108 }
109
110 }
111
112
113
114
115
116 plotblock(infp) /* plot next block */
117
118 FILE *infp;
119
120 {
121 PLIST lastinq;
122 register PRIMITIVE *p;
123
124 /* clear block */
125 nextblock();
126 /* plot from queue */
127 lastinq.ptop = inqueue.ptop;
128 lastinq.pbot = inqueue.pbot;
129 inqueue.ptop = inqueue.pbot = NULL;
130 while ((p = pop(&lastinq)) != NULL) {
131 doprim(p);
132 pfree(p);
133 }
134 /* plot from file */
135 while (isprim(nextp.com) && inthis(&nextp)) {
136 doprim(&nextp);
137 fargs(&nextp);
138 readp(&nextp, infp);
139 }
140 /* print out block */
141 outputblock();
142
143 }
144
145
146
147
148
149 nextblock() /* prepare next block */
150
151 {
152 register int i, n;
153 register unsigned char *colp;
154 /* clear block */
155 for (i = 0; i < NUMSCANS; i++) {
156 colp = outblock.cols[i];
157 n = dxsize;
158 while (n--)
159 *colp++ = IWHT<<3 | IWHT;
160 }
161 /* advance */
162 if (ydown) {
163 outblock.ytop -= NUMSCANS;
164 outblock.ybot -= NUMSCANS;
165 } else {
166 outblock.ytop += NUMSCANS;
167 outblock.ybot += NUMSCANS;
168 }
169 return;
170 memerr:
171 error(SYSTEM, "out of memory in nextblock");
172 }
173
174
175
176 outputblock() /* output block to printer */
177 {
178 register int i, n;
179 register unsigned char *colp;
180
181 for (i = 0; i < NUMSCANS; i++) { /* overlay blocks */
182
183 n = outblock.xright - outblock.xleft + 1;
184 colp = outblock.cols[i] + outblock.xleft;
185 while (n--) {
186 *colp = *colp>>3 & *colp;
187 colp++;
188 }
189 }
190 printblock(); /* print block */
191 }
192
193
194
195 doprim(p) /* plot primitive */
196
197 register PRIMITIVE *p;
198
199 {
200 register PRIMITIVE *newp;
201
202 switch (p->com) {
203
204 case PLSEG:
205 plotlseg(p);
206 break;
207
208 case PRFILL:
209 fill((p->arg0&0103) | (pati[(p->arg0>>2)&03]<<2),
210 CONV(p->xy[XMN],dxsize),CONV(p->xy[YMN],dysize),
211 CONV(p->xy[XMX],dxsize)+(p->arg0&0100?-1:0),
212 CONV(p->xy[YMX],dysize)+(p->arg0&0100?-1:0));
213 break;
214
215 case PTFILL:
216 tfill(p);
217 break;
218
219 default:
220 sprintf(errmsg, "unknown command '%c' in doprim", p->com);
221 error(WARNING, errmsg);
222 return;
223 }
224
225 if (innext(p)) { /* save for next time */
226 if ((newp = palloc()) == NULL)
227 error(SYSTEM, "memory limit exceeded in doprim");
228 mcopy((char *)newp, (char *)p, sizeof(PRIMITIVE));
229 newp->args = savestr(p->args);
230 add(newp, &inqueue);
231 }
232
233 }
234
235
236
237
238
239 plotlseg(p) /* plot a line segment */
240
241 register PRIMITIVE *p;
242
243 {
244 register int ti;
245 long run2 = 0L, rise2 = 0L;
246 int x, y, run, rise, xstop, ystop, hrad, vrad, lpat, n;
247
248 /* compute line pattern */
249 lpat = (p->arg0 >> 2) & 014;
250 if (p->arg0 & 0100 && lpat != 0)
251 lpat += 014;
252 lpat |= p->arg0 & 03;
253
254 ti = (p->arg0 >> 2) & 03; /* compute line radius */
255 ti = WIDTH(ti) / 2;
256 hrad = CONV(ti, dxsize);
257 vrad = CONV(ti, dysize);
258 if (hrad < minwidth)
259 hrad = minwidth;
260 if (vrad < minwidth)
261 vrad = minwidth;
262
263 x = CONV(p->xy[XMX], dxsize); /* start at top */
264 y = CONV(p->xy[YMX], dysize);
265 run = CONV(p->xy[XMN], dxsize) - x;
266 rise = CONV(p->xy[YMN], dysize) - y;
267
268 if (p->arg0 & 0100) /* slope < 0; reverse x */
269 x -= (run = -run);
270
271 xstop = x + run; /* compute end point */
272 ystop = y + rise;
273
274 if ((ti = outblock.ytop+vrad+1-y) < 0) { /* adjust to top of block */
275 run2 = rise2 = (long)ti*run;
276 x += rise2/rise;
277 y += ti;
278 }
279
280 if ((ti = outblock.ybot-vrad-1-ystop) > 0) { /* adjust to bottom of block */
281 xstop += (long)ti*run/rise;
282 ystop += ti;
283 }
284
285 if (abs(run) > -rise)
286 n = abs(xstop - x);
287 else
288 n = y - ystop;
289
290 paintline(x, y, run, rise, hrad, vrad, lpat, run2, rise2, n);
291
292 }
293
294
295
296 /*
297 * This routine paints a line with calls to fill(). The line can
298 * start and end at arbitrary points on a longer line segment.
299 */
300
301 paintline(x, y, run, rise, hrad, vrad, lpat, run2, rise2, n)
302
303 register int x, y;
304 int run, rise;
305 int hrad, vrad;
306 int lpat;
307 long run2, rise2;
308 int n;
309
310 {
311 int xstep, ystep;
312
313 if (run >= 0)
314 xstep = 1;
315 else {
316 xstep = -1;
317 run = -run;
318 }
319 if (rise >= 0)
320 ystep = 1;
321 else {
322 ystep = -1;
323 rise = -rise;
324 }
325 if (n < 0)
326 n = max(run, rise);
327
328 if (run > rise)
329 while (n >= 0)
330 if (run2 >= rise2) {
331 fill(lpat, x-hrad, y-vrad, x+hrad, y+vrad);
332 n--;
333 x += xstep;
334 rise2 += rise;
335 } else {
336 y += ystep;
337 run2 += run;
338 }
339 else
340 while (n >= 0)
341 if (rise2 >= run2) {
342 fill(lpat, x-hrad, y-vrad, x+hrad, y+vrad);
343 n--;
344 y += ystep;
345 run2 += run;
346 } else {
347 x += xstep;
348 rise2 += rise;
349 }
350
351 }
352
353
354
355 tfill(p) /* fill a triangle */
356 register PRIMITIVE *p;
357 {
358 register int x, txmin, txmax;
359 int xmn, ymn, tpat;
360 long xsz, ysz;
361
362 xmn = CONV(p->xy[XMN], dxsize);
363 xsz = CONV(p->xy[XMX], dxsize) - xmn;
364 ymn = CONV(p->xy[YMN], dysize);
365 ysz = CONV(p->xy[YMX], dysize) - ymn;
366 if (xsz <= 0 || ysz <= 0)
367 return;
368 txmin = (outblock.ybot - ymn)*xsz/ysz;
369 txmax = (outblock.ytop - ymn)*xsz/ysz;
370 if (p->arg0 & 020) { /* up or down */
371 x = txmin;
372 txmin = xsz - txmax;
373 txmax = xsz - x;
374 }
375 txmin += xmn;
376 txmax += xmn;
377 txmin = max(txmin, xmn);
378 txmax = min(txmax, xmn + (int)xsz - 1);
379 tpat = (p->arg0&0103) | (pati[(p->arg0>>2)&03]<<2);
380
381 if (p->arg0 & 040) { /* left or down */
382 fill(tpat, xmn, ymn, txmin - 1, ymn + (int)ysz - 1);
383 for (x = txmin; x <= txmax; x++)
384 if (p->arg0 & 020) /* down */
385 fill(tpat, x, ymn, x, (int)(ysz-(x-xmn)*ysz/xsz) + ymn - 1);
386 else /* left */
387 fill(tpat, x, (int)((x-xmn)*ysz/xsz) + ymn, x, ymn + (int)ysz - 1);
388 } else { /* right or up */
389 for (x = txmin; x <= txmax; x++)
390 if (p->arg0 & 020) /* up */
391 fill(tpat, x, (int)(ysz-(x-xmn)*ysz/xsz) + ymn, x, ymn + (int)ysz - 1);
392 else /* right */
393 fill(tpat, x, ymn, x, (int)((x-xmn)*ysz/xsz) + ymn - 1);
394 fill(tpat, txmax + 1, ymn, xmn + (int)xsz - 1, ymn + (int)ysz - 1);
395 }
396 }
397
398
399
400
401 fill(attrib, xmin, ymin, xmax, ymax) /* fill rectangle with attribute */
402
403 register int attrib;
404 int xmin, ymin, xmax, ymax;
405
406 {
407 register int i, j;
408
409 xmin = max(xmin, outblock.xleft);
410 ymin = max(ymin, outblock.ybot);
411 xmax = min(xmax, outblock.xright);
412 ymax = min(ymax, outblock.ytop);
413
414 for (j = ymin; j <= ymax; j++)
415 for (i = xmin; i <= xmax; i++)
416 if (pattern[(attrib&074)>>2]
417 [(j>>3)%(PATSIZE>>3)][i%PATSIZE] & 1<<(j&07)) {
418
419 if (attrib & 0100) {
420 pixtog(i,j,attrib&03);
421 } else {
422 pixmix(i,j,attrib&03);
423 }
424 }
425
426 }