ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/rplot.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 2 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 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     }