ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mplot.c
Revision: 1.3
Committed: Sat Nov 15 02:13:37 2003 UTC (20 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 1.2: +67 -64 lines
Log Message:
Continued ANSIfication, and reduced other compile warnings.

File Contents

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