ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mplot.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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