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, 4 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.3 static const char RCSid[] = "$Id: mplot.c,v 1.2 2003/07/01 21:21:40 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * Plotting routines for meta-files to line-at-a-time printers
6     */
7    
8    
9 schorsch 1.3 #include <stdio.h>
10     #include <string.h>
11 greg 1.1 #include <fcntl.h>
12    
13 schorsch 1.3 #include "platform.h"
14 greg 1.1 #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 schorsch 1.3 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 greg 1.1 {
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 schorsch 1.3 void
57     initplot(void) /* initialize this plot */
58 greg 1.1 {
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 schorsch 1.3 void
70     doglobal( /* execute a global command */
71     PRIMITIVE *g
72     )
73 greg 1.1 {
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 greg 1.2 case PPAUS:
96 greg 1.1 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 schorsch 1.3 void
133     plotspan( /* plot next span */
134     FILE *infp
135     )
136 greg 1.1 {
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 schorsch 1.3 void
163     nextspan(void) /* prepare next span */
164 greg 1.1 {
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 schorsch 1.3 void
186     outputspan(void) /* output span to printer */
187 greg 1.1 {
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 schorsch 1.3 void
204     doprim( /* plot primitive */
205     register PRIMITIVE *p
206     )
207 greg 1.1 {
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 schorsch 1.3 void
250     plotlseg( /* plot a line segment */
251     register PRIMITIVE *p
252     )
253 greg 1.1 {
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 schorsch 1.3 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 greg 1.1 {
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 schorsch 1.3 void
368     tfill( /* fill a triangle */
369     register PRIMITIVE *p
370     )
371 greg 1.1 {
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 schorsch 1.3 void
415     fill( /* fill rectangle with attribute */
416     int attrib,
417     int xmin,
418     int ymin,
419     int xmax,
420     int ymax
421     )
422 greg 1.1 {
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     }