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