1*16548Sslatteng /* vsort.c 1.11 84/05/29
213918Sslatteng *
314758Sslatteng * Sorts and shuffles ditroff output for versatec wide printer. It
414758Sslatteng * puts pages side-by-side on the output, and fits as many as it can
514758Sslatteng * on one horizontal span. The versatec driver sees only pages of
614758Sslatteng * full width, not the individual pages. Output is sorted vertically
714758Sslatteng * and bands are created NLINES pixels high. Any object that has
814758Sslatteng * ANY part of it in a band is put on that band.
913918Sslatteng */
1013918Sslatteng
1113918Sslatteng
1213918Sslatteng #include <stdio.h>
1313918Sslatteng #include <ctype.h>
1414758Sslatteng #include <math.h>
1513918Sslatteng
1613918Sslatteng
1715277Sslatteng /* #define DEBUGABLE /* compile-time flag for debugging */
1813918Sslatteng #define FATAL 1
1914758Sslatteng #define NVLIST 3000 /* size of list of vertical spans */
2014758Sslatteng #define OBUFSIZ 250000 /* size of character buffer before sorting */
2114297Sslatteng #define SLOP 1000 /* extra bit of buffer to allow for passing OBUFSIZ */
22*16548Sslatteng #define MAXVECT 200 /* maximum number of points (vectors) in a polygon */
2313918Sslatteng
2415946Sslatteng #ifndef FONTDIR
2514758Sslatteng #define FONTDIR "/usr/lib/font"
2615946Sslatteng #endif
2714758Sslatteng #define INCH 200 /* assumed resolution of the printer (dots/inch) */
2814758Sslatteng #define POINT 72 /* number of points per inch */
2914758Sslatteng #define WIDTH 7040 /* number of pixels across the page */
3014758Sslatteng #define HALF (INCH/2)
3115059Sslatteng #ifndef DEBUGABLE
3215616Sslatteng #define BAND 1 /* length of each band (or defined below) */
3315059Sslatteng #endif
3414758Sslatteng #define NLINES (int)(BAND * INCH) /* number of pixels in each band */
3513918Sslatteng
3614758Sslatteng #define hgoto(n) if((hpos = leftmarg + n) > maxh) maxh = hpos
3714758Sslatteng #define hmot(n) if((hpos += n) > maxh) maxh = hpos
38*16548Sslatteng #define vmot(n) vpos += (n)
39*16548Sslatteng #define vgoto(n) vpos = (n)
4013918Sslatteng
4114758Sslatteng
4214297Sslatteng #ifdef DEBUGABLE
4315059Sslatteng int dbg = 0; /* debug flag != 0 means do debug output */
4416183Sslatteng float BAND = 1.0;
4514297Sslatteng #endif
4614758Sslatteng
4715059Sslatteng
4814758Sslatteng int size = 10; /* current size (points) */
4914758Sslatteng int up = 0; /* number of pixels that the current size pushes up */
5014758Sslatteng int down = 0; /* # of pixels that the current size will hang down */
5113918Sslatteng int font = 1; /* current font */
52*16548Sslatteng int stip = 1; /* current stipple */
5314758Sslatteng char * fontdir = FONTDIR; /* place to find DESC.out file */
5414285Sslatteng int thick = 3; /* line thickness */
5514758Sslatteng int style = -1; /* line style bit-mask */
5613918Sslatteng int hpos = 0; /* horizontal position to be at next (left = 0) */
5713918Sslatteng int vpos = 0; /* current vertical position (down positive) */
5813918Sslatteng
5914758Sslatteng int maxh = 0; /* farthest right we've gone on the current span */
6014758Sslatteng int leftmarg= 0; /* current page offset */
6114758Sslatteng int spanno = 0; /* current span number for driver in 'p#' commands */
6215277Sslatteng int pageno = 0; /* number of pages spread across a physical page */
6314758Sslatteng
6414758Sslatteng
6513918Sslatteng struct vlist {
6615946Sslatteng unsigned short v; /* vertical position of this spread */
6715946Sslatteng unsigned short h; /* horizontal position */
6815946Sslatteng unsigned short t; /* line thickness */
69*16548Sslatteng short st; /* style mask */
7015946Sslatteng unsigned short u; /* upper extent of height */
7115946Sslatteng unsigned short d; /* depth of height */
72*16548Sslatteng unsigned short s; /* point size */
7315946Sslatteng unsigned char f; /* font number */
74*16548Sslatteng unsigned char l; /* stipple number */
75*16548Sslatteng char *p; /* text pointer to this spread */
7613918Sslatteng };
7713918Sslatteng
7813918Sslatteng struct vlist vlist[NVLIST + 1];
7914758Sslatteng struct vlist *vlp; /* current spread being added to */
8015946Sslatteng int nvlist = 1; /* number of spreads in list */
8113918Sslatteng int obufsiz = OBUFSIZ;
8213918Sslatteng char obuf[OBUFSIZ + SLOP];
8314758Sslatteng char *op = obuf; /* pointer to current spot in buffer */
8413918Sslatteng
8513918Sslatteng
main(argc,argv)8613918Sslatteng main(argc, argv)
8713918Sslatteng int argc;
8813918Sslatteng char *argv[];
8913918Sslatteng {
9013918Sslatteng FILE *fp;
9115059Sslatteng double atof();
9213918Sslatteng
9313918Sslatteng
9415946Sslatteng vlp = &vlist[0]; /* initialize spread pointer */
9515946Sslatteng vlp->p = op;
9615946Sslatteng vlp->v = vlp->d = vlp->u = vlp->h = 0;
9715946Sslatteng vlp->s = size;
9815946Sslatteng vlp->f = font;
99*16548Sslatteng vlp->l = stip;
10015946Sslatteng vlp->st = style;
10115946Sslatteng vlp->t = thick;
10215946Sslatteng
10313918Sslatteng while (argc > 1 && **++argv == '-') {
10413918Sslatteng switch ((*argv)[1]) {
10514758Sslatteng case 'f':
10614758Sslatteng fontdir = &(*argv)[2];
10714758Sslatteng break;
10814297Sslatteng #ifdef DEBUGABLE
10915059Sslatteng case 'B':
11015059Sslatteng BAND = atof(&(*argv)[2]);
11115059Sslatteng break;
11213918Sslatteng case 'd':
11313918Sslatteng dbg = atoi(&(*argv)[2]);
11414758Sslatteng if (!dbg) dbg = 1;
11513918Sslatteng break;
11614758Sslatteng
11714758Sslatteng case 's':
11814758Sslatteng if((obufsiz = atoi(&(*argv)[2])) > OBUFSIZ)
11914758Sslatteng obufsiz = OBUFSIZ;
12014758Sslatteng break;
12114297Sslatteng #endif
12213918Sslatteng }
12313918Sslatteng argc--;
12413918Sslatteng }
12514758Sslatteng
12613918Sslatteng if (argc <= 1)
12713918Sslatteng conv(stdin);
12813918Sslatteng else
12913918Sslatteng while (--argc > 0) {
13013918Sslatteng if ((fp = fopen(*argv, "r")) == NULL)
13113918Sslatteng error(FATAL, "can't open %s", *argv);
13213918Sslatteng conv(fp);
13313918Sslatteng fclose(fp);
13413918Sslatteng }
13514758Sslatteng done();
13613918Sslatteng }
13713918Sslatteng
13813918Sslatteng /* read number from input: copy to output */
getnumber(fp)13913918Sslatteng int getnumber (fp)
14013918Sslatteng register FILE *fp;
14113918Sslatteng {
14214758Sslatteng register int k;
14314758Sslatteng register char c;
14413918Sslatteng
145*16548Sslatteng while (isspace(c = getc(fp)))
14614758Sslatteng ;
14714758Sslatteng k = 0;
148*16548Sslatteng if (c == '-') {
149*16548Sslatteng c = getc(fp);
150*16548Sslatteng do {
151*16548Sslatteng k = 10 * k - ((*op++ = c) - '0');
152*16548Sslatteng } while (isdigit(c = getc(fp)));
153*16548Sslatteng } else {
154*16548Sslatteng do {
155*16548Sslatteng k = 10 * k + (*op++ = c) - '0';
156*16548Sslatteng } while (isdigit(c = getc(fp)));
157*16548Sslatteng }
15814758Sslatteng ungetc(c, fp);
15914758Sslatteng return (k);
16013918Sslatteng }
16113918Sslatteng
16213918Sslatteng /* read number from input: do _N_O_T copy to output */
ngetnumber(fp)16313918Sslatteng int ngetnumber (fp)
16413918Sslatteng register FILE *fp;
16513918Sslatteng {
16614758Sslatteng register int k;
16714758Sslatteng register char c;
16813918Sslatteng
169*16548Sslatteng while (isspace(c = getc(fp)))
17014758Sslatteng ;
17114758Sslatteng k = 0;
172*16548Sslatteng if (c == '-') {
173*16548Sslatteng c = getc(fp);
174*16548Sslatteng do {
175*16548Sslatteng k = 10 * k - (c - '0');
176*16548Sslatteng } while (isdigit(c = getc(fp)));
177*16548Sslatteng } else {
178*16548Sslatteng do {
179*16548Sslatteng k = 10 * k + c - '0';
180*16548Sslatteng } while (isdigit(c = getc(fp)));
181*16548Sslatteng }
18214758Sslatteng ungetc(c, fp);
18314758Sslatteng return (k);
18413918Sslatteng }
18513918Sslatteng
18613918Sslatteng
conv(fp)18713918Sslatteng conv(fp)
18813918Sslatteng register FILE *fp;
18913918Sslatteng {
19013918Sslatteng register int c;
19113918Sslatteng int m, n, m1, n1;
19213918Sslatteng
19313918Sslatteng while ((c = getc(fp)) != EOF) {
19414297Sslatteng #ifdef DEBUGABLE
19514758Sslatteng if (dbg > 2) fprintf(stderr, "%c i=%d V=%d\n", c, op-obuf, vpos);
19614297Sslatteng #endif
19715277Sslatteng if (op > obuf + obufsiz) {
19815277Sslatteng error(!FATAL, "buffer overflow %d.", op - (obuf + obufsiz));
19913918Sslatteng oflush();
20015277Sslatteng }
20113918Sslatteng switch (c) {
20216183Sslatteng case '\0': /* filter out noise */
20316183Sslatteng break;
20413918Sslatteng case '\n': /* let text input through */
20513918Sslatteng case '\t':
20613918Sslatteng case ' ':
20713918Sslatteng *op++ = c;
20813918Sslatteng break;
20913918Sslatteng case '{': /* push down current environment */
21013918Sslatteng *op++ = c;
21113918Sslatteng t_push();
21213918Sslatteng break;
21313918Sslatteng case '}': /* pop up last environment */
21413918Sslatteng *op++ = c;
21513918Sslatteng t_pop();
21613918Sslatteng break;
21713918Sslatteng case '0': case '1': case '2': case '3': case '4':
21813918Sslatteng case '5': case '6': case '7': case '8': case '9':
21913918Sslatteng /* two motion digits plus a character */
22015946Sslatteng setlimit(vpos - up, vpos + down);
22113918Sslatteng *op++ = c;
22213918Sslatteng hmot((c-'0') * 10 + (*op++ = getc(fp)) - '0');
22313918Sslatteng *op++ = getc(fp);
22413918Sslatteng break;
22513918Sslatteng case 'c': /* single ascii character */
22615946Sslatteng setlimit(vpos - up, vpos + down);
22713918Sslatteng *op++ = c;
22813918Sslatteng *op++ = getc(fp);
22913918Sslatteng break;
23013918Sslatteng case 'C': /* white-space terminated funny character */
23115946Sslatteng setlimit(vpos - up, vpos + down);
23213918Sslatteng *op++ = c;
23316183Sslatteng do
23416183Sslatteng *op++ = c = getc(fp);
235*16548Sslatteng while (c != EOF && !isspace(c));
23613918Sslatteng break;
23713918Sslatteng case 't': /* straight text */
23815946Sslatteng setlimit(vpos - up, vpos + down);
23913918Sslatteng *op++ = c;
24013918Sslatteng fgets(op, SLOP, fp);
24113918Sslatteng op += strlen(op);
24213918Sslatteng break;
24313918Sslatteng case 'D': /* draw function */
244*16548Sslatteng switch (c = getc(fp)) {
24514285Sslatteng case 's': /* "style" */
246*16548Sslatteng sprintf(op, "Ds ");
247*16548Sslatteng op += 3;
248*16548Sslatteng style = getnumber(fp);
24914285Sslatteng break;
250*16548Sslatteng
25114285Sslatteng case 't': /* thickness */
252*16548Sslatteng sprintf(op, "Dt ");
253*16548Sslatteng op += 3;
254*16548Sslatteng thick = getnumber(fp);
25514285Sslatteng break;
256*16548Sslatteng
25713918Sslatteng case 'l': /* draw a line */
258*16548Sslatteng n = ngetnumber(fp);
259*16548Sslatteng m = ngetnumber(fp);
26013918Sslatteng if (m < 0) {
26115946Sslatteng setlimit(vpos+m-thick/2, vpos+thick/2);
26214758Sslatteng } else {
26316183Sslatteng setlimit(vpos-(1+thick/2),vpos+1+m+thick/2);
26413918Sslatteng }
265*16548Sslatteng sprintf(op, "Dl %d %d", n, m);
26613918Sslatteng op += strlen(op);
26713918Sslatteng hmot(n);
26813918Sslatteng vmot(m);
26913918Sslatteng break;
270*16548Sslatteng
271*16548Sslatteng case 'e': /* ellipse */
272*16548Sslatteng n = ngetnumber(fp);
273*16548Sslatteng m = ngetnumber(fp);
274*16548Sslatteng setlimit(vpos-(m+thick)/2, vpos+(m+thick)/2);
275*16548Sslatteng sprintf(op, "De %d %d", n, m);
276*16548Sslatteng op += strlen(op);
277*16548Sslatteng hmot(n);
278*16548Sslatteng break;
279*16548Sslatteng
28013918Sslatteng case 'c': /* circle */
281*16548Sslatteng n = ngetnumber(fp);
28215946Sslatteng setlimit(vpos-(n+thick)/2, vpos+(n+thick)/2);
283*16548Sslatteng sprintf(op, "Dc %d", n);
28414758Sslatteng op += strlen(op);
28513918Sslatteng hmot(n);
28613918Sslatteng break;
287*16548Sslatteng
28813918Sslatteng case 'a': /* arc */
289*16548Sslatteng n = getnumber(fp);
290*16548Sslatteng m = getnumber(fp);
291*16548Sslatteng n1 = getnumber(fp);
292*16548Sslatteng m1 = getnumber(fp);
29314758Sslatteng arcbounds(n, m, n1, m1);
294*16548Sslatteng sprintf(op, "Da %d %d %d %d", n, m, n1, m1);
29513918Sslatteng op += strlen(op);
29614758Sslatteng hmot(n + n1);
29714758Sslatteng vmot(m + m1);
29813918Sslatteng break;
299*16548Sslatteng
300*16548Sslatteng case 'P':
301*16548Sslatteng case 'p':
30213918Sslatteng {
303*16548Sslatteng register int nvect;
304*16548Sslatteng int member;
305*16548Sslatteng int border;
306*16548Sslatteng int x[MAXVECT];
307*16548Sslatteng int y[MAXVECT];
30815946Sslatteng
309*16548Sslatteng
310*16548Sslatteng border = (c == 'p'); /* type of polygon */
311*16548Sslatteng member = ngetnumber(fp);/* and member number */
312*16548Sslatteng
313*16548Sslatteng nvect = 1; /* starting point for */
314*16548Sslatteng x[1] = hpos; /* points on polygon */
315*16548Sslatteng y[1] = vpos;
31614758Sslatteng m = n = vpos; /* = max/min vertical */
31713918Sslatteng /* position for curve */
318*16548Sslatteng {
319*16548Sslatteng register int h;
320*16548Sslatteng register int v;
32113918Sslatteng
322*16548Sslatteng
323*16548Sslatteng h = hpos; /* calculate max and minimum */
324*16548Sslatteng v = vpos; /* vertical position */
325*16548Sslatteng /* and get points */
326*16548Sslatteng do {
327*16548Sslatteng h += ngetnumber(fp);
328*16548Sslatteng v += ngetnumber(fp);
329*16548Sslatteng
330*16548Sslatteng if (v < n) n = v;
331*16548Sslatteng else if (v > m) m = v;
332*16548Sslatteng
333*16548Sslatteng if (nvect < (MAXVECT-1))/* keep the */
334*16548Sslatteng nvect++; /* points in */
335*16548Sslatteng x[nvect] = h; /* bounds */
336*16548Sslatteng y[nvect] = v; /* of arrays */
337*16548Sslatteng c = getc(fp);
338*16548Sslatteng } while (c != '\n' && c != EOF);
339*16548Sslatteng }
340*16548Sslatteng if (border) { /* output border as a */
341*16548Sslatteng register int *x1; /* bunch of lines */
342*16548Sslatteng register int *x2; /* instead of having */
343*16548Sslatteng register int *y1; /* the filter do it */
344*16548Sslatteng register int *y2;
345*16548Sslatteng register int extra = thick/2;
346*16548Sslatteng
347*16548Sslatteng x1 = &(x[0]); /* x1, y1, x2, y2 are */
348*16548Sslatteng x2 = &(x[1]); /* for indexing along */
349*16548Sslatteng y1 = &(y[0]); /* coordinate arrays */
350*16548Sslatteng y2 = &(y[1]);
351*16548Sslatteng for (border = 0; ++border < nvect; ) {
352*16548Sslatteng if (*++y1 > *++y2) {
353*16548Sslatteng setlimit(*y2-extra, vpos+extra);
354*16548Sslatteng } else {
355*16548Sslatteng setlimit(vpos-(1+extra),*y2+1+extra);
356*16548Sslatteng /* the extra 1's are to force */
357*16548Sslatteng /* setlimit to know this is a */
358*16548Sslatteng /* real entry (making sure it */
359*16548Sslatteng /* doesn't get vpos as limit */
360*16548Sslatteng }
361*16548Sslatteng sprintf(op, "Dl %d %d\n",
362*16548Sslatteng c = *++x2 - *++x1, *y2 - *y1);
363*16548Sslatteng op += strlen(op);
364*16548Sslatteng hmot(c); /* update vpos for */
365*16548Sslatteng vgoto(*y2); /* the setlimit call */
366*16548Sslatteng }
367*16548Sslatteng } else {
368*16548Sslatteng register int *x1; /* x1, x2, are for */
369*16548Sslatteng register int *x2; /* indexing points */
370*16548Sslatteng register int i; /* random int */
371*16548Sslatteng
372*16548Sslatteng x1 = &(x[0]);
373*16548Sslatteng x2 = &(x[1]);
374*16548Sslatteng for (i = 0; ++i < nvect; ) {
375*16548Sslatteng hmot(*++x2 - *++x1);
376*16548Sslatteng }
377*16548Sslatteng vgoto(y[nvect]);
378*16548Sslatteng sprintf(op, "H%dV%d", hpos, vpos);
379*16548Sslatteng op += strlen(op);
380*16548Sslatteng }
381*16548Sslatteng if (member) {
382*16548Sslatteng polygon(member, nvect, x, y, m, n);
383*16548Sslatteng }
38413918Sslatteng }
38513918Sslatteng break;
38613918Sslatteng
387*16548Sslatteng case '~': /* wiggly line */
388*16548Sslatteng case 'g': /* gremlin curve */
389*16548Sslatteng startspan(vpos); /* always put curve */
390*16548Sslatteng sprintf(op, "D%c ", c); /* on its own span */
391*16548Sslatteng op += 3;
392*16548Sslatteng
393*16548Sslatteng m = n = vpos; /* = max/min vertical */
394*16548Sslatteng do { /* position for curve */
395*16548Sslatteng hpos += getnumber(fp);
396*16548Sslatteng *op++ = ' ';
397*16548Sslatteng vpos += getnumber(fp);
398*16548Sslatteng *op++ = ' ';
399*16548Sslatteng
400*16548Sslatteng if (vpos < n) n = vpos;
401*16548Sslatteng else if (vpos > m) m = vpos;
402*16548Sslatteng
403*16548Sslatteng c = getc(fp);
404*16548Sslatteng } while (c != '\n' && c != EOF);
405*16548Sslatteng
406*16548Sslatteng vlp->u = n < 0 ? 0 : n;
407*16548Sslatteng vlp->d = m;
408*16548Sslatteng *op++ = '\n';
409*16548Sslatteng startspan(vpos);
410*16548Sslatteng break;
411*16548Sslatteng
41213918Sslatteng default:
413*16548Sslatteng error(FATAL,"unknown drawing command %c", c);
41413918Sslatteng break;
41513918Sslatteng }
41613918Sslatteng break;
41713918Sslatteng case 's':
41813918Sslatteng *op++ = c;
41914758Sslatteng size = getnumber(fp);
42016183Sslatteng up = ((size + 1)*INCH) / POINT; /* ROUGH estimate */
42115277Sslatteng down = up / 3; /* of max up/down */
42213918Sslatteng break;
42313918Sslatteng case 'f':
42413918Sslatteng *op++ = c;
42514758Sslatteng font = getnumber(fp);
42613918Sslatteng break;
427*16548Sslatteng case 'i':
428*16548Sslatteng *op++ = c;
429*16548Sslatteng stip = getnumber(fp);
430*16548Sslatteng break;
43113918Sslatteng case 'H': /* absolute horizontal motion */
43214758Sslatteng hgoto(ngetnumber(fp));
433*16548Sslatteng sprintf(op, "H%d", hpos);
43414758Sslatteng op += strlen(op); /* reposition by page offset */
43513918Sslatteng break;
43613918Sslatteng case 'h': /* relative horizontal motion */
43713918Sslatteng *op++ = c;
43814758Sslatteng hmot(getnumber(fp));
43913918Sslatteng break;
44013918Sslatteng case 'w': /* useless */
44113918Sslatteng break;
44213918Sslatteng case 'V': /* absolute vertical motion */
443*16548Sslatteng *op++ = c;
444*16548Sslatteng vgoto(getnumber(fp));
44513918Sslatteng break;
44613918Sslatteng case 'v':
447*16548Sslatteng *op++ = c;
448*16548Sslatteng vmot(getnumber(fp));
44913918Sslatteng break;
45013918Sslatteng case 'p': /* new page */
45114758Sslatteng t_page(ngetnumber(fp));
45213918Sslatteng vpos = 0;
45313918Sslatteng break;
45413918Sslatteng case 'n': /* end of line */
45514758Sslatteng hpos = leftmarg;
45616183Sslatteng *op++ = c;
45716183Sslatteng do
45816183Sslatteng *op++ = c = getc(fp);
45916183Sslatteng while (c != '\n' && c != EOF);
46016183Sslatteng break;
46113918Sslatteng case '#': /* comment */
46216183Sslatteng do
46316183Sslatteng c = getc(fp);
46416183Sslatteng while (c != '\n' && c != EOF);
46516183Sslatteng break;
46614758Sslatteng case 'x': /* device control */
46715946Sslatteng startspan(vpos);
46813918Sslatteng *op++ = c;
46916183Sslatteng do
47016183Sslatteng *op++ = c = getc(fp);
47116183Sslatteng while (c != '\n' && c != EOF);
47213918Sslatteng break;
47313918Sslatteng default:
47416183Sslatteng error(!FATAL, "unknown input character %o %c", c, c);
47513918Sslatteng done();
47613918Sslatteng }
47713918Sslatteng }
47813918Sslatteng }
47913918Sslatteng
48015277Sslatteng
48115277Sslatteng /*----------------------------------------------------------------------------*
48215277Sslatteng | Routine: setlimit
48315277Sslatteng |
48415946Sslatteng | Results: using "newup" and "newdown" decide when to start a new span.
48515946Sslatteng | maximum rise and/or fall of a vertical extent are saved.
48615277Sslatteng |
48715946Sslatteng | Side Efct: may start new span.
48815277Sslatteng *----------------------------------------------------------------------------*/
48915277Sslatteng
490*16548Sslatteng #define diffspan(x,y) ((x)/NLINES != (y)/NLINES)
49115946Sslatteng
setlimit(newup,newdown)49215946Sslatteng setlimit(newup, newdown)
49315946Sslatteng register int newup;
49415946Sslatteng register int newdown;
49514758Sslatteng {
49615946Sslatteng register int currup = vlp->u;
49715946Sslatteng register int currdown = vlp->d;
49813918Sslatteng
49915946Sslatteng if (newup < 0) newup = 0; /* don't go back beyond start of page */
50015946Sslatteng if (newdown < 0) newdown = 0;
50115946Sslatteng
50215946Sslatteng if (diffspan(currup, currdown)) { /* now spans > one band */
50316183Sslatteng if (diffspan(newup, currup) || diffspan(newdown, currdown)) {
50415946Sslatteng startspan (vpos);
50515946Sslatteng vlp->u = newup;
50615946Sslatteng vlp->d = newdown;
50716183Sslatteng } else {
50816183Sslatteng if (newup < currup) vlp->u = newup;
50916183Sslatteng if (newdown > currdown) vlp->d = newdown;
51015946Sslatteng }
51115946Sslatteng } else {
51215946Sslatteng if (newup < currup) { /* goes farther up than before */
51315946Sslatteng if (currup == vlp->v) { /* is new span, just set "up" */
51415946Sslatteng vlp->u = newup;
51515946Sslatteng } else {
51615946Sslatteng if (diffspan(newup, currup)) { /* goes up farther */
51715946Sslatteng startspan(vpos); /* than previously */
51815946Sslatteng vlp->u = newup; /* AND to a higher */
51915946Sslatteng vlp->d = newdown; /* band. */
52015946Sslatteng return;
52115946Sslatteng } else {
52215946Sslatteng vlp->u = newup;
52315946Sslatteng }
52415946Sslatteng }
52515946Sslatteng }
52615946Sslatteng if (newdown > currdown) {
52715946Sslatteng if (currdown == vlp->v) {
52815946Sslatteng vlp->d = newdown;
52915946Sslatteng return;
53015946Sslatteng } else {
53115946Sslatteng if (diffspan(newdown, currdown)) {
53215946Sslatteng startspan(vpos);
53315946Sslatteng vlp->u = newup;
53415946Sslatteng vlp->d = newdown;
53515946Sslatteng return;
53615946Sslatteng } else {
53715946Sslatteng vlp->d = newdown;
53815946Sslatteng }
53915946Sslatteng }
54015946Sslatteng }
54115946Sslatteng }
54214758Sslatteng }
54314758Sslatteng
54414758Sslatteng
54515277Sslatteng /*----------------------------------------------------------------------------*
54615277Sslatteng | Routine: arcbounds (h, v, h1, v1)
54715277Sslatteng |
54815277Sslatteng | Results: using the horizontal positions of the starting and ending
54915277Sslatteng | points relative to the center and vertically relative to
55015277Sslatteng | each other, arcbounds calculates the upper and lower extent
55115277Sslatteng | of the arc which is one of: starting point, ending point
55215277Sslatteng | or center + rad for bottom, and center - rad for top.
55315277Sslatteng |
55415946Sslatteng | Side Efct: calls setlimit(up, down) to save the extent information.
55515277Sslatteng *----------------------------------------------------------------------------*/
55615277Sslatteng
arcbounds(h,v,h1,v1)55715277Sslatteng arcbounds(h, v, h1, v1)
55815277Sslatteng int h, v, h1, v1;
55914758Sslatteng {
56015616Sslatteng register unsigned rad = (int)(sqrt((double)(h*h + v*v)) + 0.5);
56115277Sslatteng register int i = ((h >= 0) << 2) | ((h1 < 0) << 1) | ((v + v1) < 0);
56215277Sslatteng
56315277Sslatteng /* i is a set of flags for the points being on the */
56415277Sslatteng /* left of the center point, and which is higher */
56515277Sslatteng
56615277Sslatteng v1 += vpos + v; /* v1 is vertical position of ending point */
56715277Sslatteng /* test relative positions for maximums */
56815946Sslatteng setlimit( /* and set the up/down of the arc */
56915946Sslatteng ((((i&3)==1) ? v1 : (((i&5)==4) ? vpos : vpos+v-rad)) - thick/2),
57015946Sslatteng ((((i&3)==2) ? v1 : (((i&5)==1) ? vpos : vpos+v+rad)) + thick/2));
57114758Sslatteng }
57214758Sslatteng
57314758Sslatteng
oflush()57413918Sslatteng oflush() /* sort, then dump out contents of obuf */
57513918Sslatteng {
57613918Sslatteng register struct vlist *vp;
57714758Sslatteng register int notdone;
57814758Sslatteng register int topv;
57914758Sslatteng register int botv;
58014285Sslatteng register int i;
58114758Sslatteng register char *p;
58213918Sslatteng
58314297Sslatteng #ifdef DEBUGABLE
58413918Sslatteng if (dbg) fprintf(stderr, "into oflush, V=%d\n", vpos);
58514297Sslatteng #endif
58613918Sslatteng if (op == obuf)
58713918Sslatteng return;
58816183Sslatteng *op = 0;
58913918Sslatteng
59014758Sslatteng topv = 0;
59114758Sslatteng botv = NLINES - 1;
59214758Sslatteng do {
59314758Sslatteng notdone = 0;
59414758Sslatteng vp = vlist;
59514758Sslatteng #ifdef DEBUGABLE
59614758Sslatteng if (dbg) fprintf(stderr, "topv=%d, botv=%d\n", topv, botv);
59714758Sslatteng #endif
59814758Sslatteng for (i = 0; i < nvlist; i++, vp++) {
59914758Sslatteng #ifdef DEBUGABLE
60014758Sslatteng if(dbg>1)fprintf(stderr,"u=%d, d=%d,%.60s\n",vp->u,vp->d,vp->p);
60114758Sslatteng #endif
60214758Sslatteng if (vp->u <= botv && vp->d >= topv) {
603*16548Sslatteng printf("H%dV%ds%df%d\ni%d\nDs%d\nDt%d\n%s",
604*16548Sslatteng vp->h,vp->v,vp->s,vp->f,vp->l,vp->st,vp->t,vp->p);
60514758Sslatteng }
60614758Sslatteng notdone |= vp->d > botv; /* not done if there's still */
60714758Sslatteng } /* something to put lower */
60814758Sslatteng if (notdone) putchar('P'); /* mark the end of the spread */
60914758Sslatteng topv += NLINES; /* unless it's the last one */
61014758Sslatteng botv += NLINES;
61114758Sslatteng } while (notdone);
61214758Sslatteng
61313918Sslatteng fflush(stdout);
61413918Sslatteng vlp = vlist;
61513918Sslatteng vlp->p = op = obuf;
61613918Sslatteng vlp->h = hpos;
61713918Sslatteng vlp->v = vpos;
61814758Sslatteng vlp->u = vpos;
61914758Sslatteng vlp->d = vpos;
62013918Sslatteng vlp->s = size;
62113918Sslatteng vlp->f = font;
622*16548Sslatteng vlp->l = stip;
62314285Sslatteng vlp->st = style;
62414285Sslatteng vlp->t = thick;
62513918Sslatteng *op = 0;
62613918Sslatteng nvlist = 1;
62713918Sslatteng }
62813918Sslatteng
62913918Sslatteng
done()63013918Sslatteng done()
63113918Sslatteng {
63213918Sslatteng oflush();
63313918Sslatteng exit(0);
63413918Sslatteng }
63513918Sslatteng
error(f,s,a1,a2,a3,a4,a5,a6,a7)63613918Sslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) {
63713918Sslatteng fprintf(stderr, "vsort: ");
63813918Sslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
63913918Sslatteng fprintf(stderr, "\n");
64013918Sslatteng if (f)
64113918Sslatteng done();
64213918Sslatteng }
64313918Sslatteng
64413918Sslatteng #define MAXSTATE 5
64513918Sslatteng
64613918Sslatteng struct state {
64713918Sslatteng int ssize;
64813918Sslatteng int sfont;
64913918Sslatteng int shpos;
65013918Sslatteng int svpos;
65113918Sslatteng };
65213918Sslatteng struct state state[MAXSTATE];
65313918Sslatteng struct state *statep = state;
65413918Sslatteng
t_push()65513918Sslatteng t_push() /* begin a new block */
65613918Sslatteng {
65713918Sslatteng statep->ssize = size;
65813918Sslatteng statep->sfont = font;
65913918Sslatteng statep->shpos = hpos;
66013918Sslatteng statep->svpos = vpos;
66113918Sslatteng hpos = vpos = 0;
66213918Sslatteng if (statep++ >= state+MAXSTATE)
66313918Sslatteng error(FATAL, "{ nested too deep");
66413918Sslatteng hpos = vpos = 0;
66513918Sslatteng }
66613918Sslatteng
t_pop()66713918Sslatteng t_pop() /* pop to previous state */
66813918Sslatteng {
66913918Sslatteng if (--statep < state)
67013918Sslatteng error(FATAL, "extra }");
67113918Sslatteng size = statep->ssize;
67213918Sslatteng font = statep->sfont;
67313918Sslatteng hpos = statep->shpos;
67413918Sslatteng vpos = statep->svpos;
67513918Sslatteng }
67613918Sslatteng
67713918Sslatteng
67815946Sslatteng /*----------------------------------------------------------------------------*
67915946Sslatteng | Routine: t_page
68015946Sslatteng |
68115946Sslatteng | Results: new Margins are calculated for putting pages side-by-side.
68215946Sslatteng | If no more pages can fit across the paper (WIDTH wide)
68315946Sslatteng | a real page end is done and the currrent page is output.
68415946Sslatteng |
68515946Sslatteng | Side Efct: oflush is called on a REAL page boundary.
68615946Sslatteng *----------------------------------------------------------------------------*/
68715946Sslatteng
t_page(n)68814758Sslatteng t_page(n)
68914758Sslatteng int n;
69014758Sslatteng {
69115277Sslatteng static int first = 1; /* flag to catch the 1st time through */
69214758Sslatteng
69315277Sslatteng /* if we're near the edge, we'll go over on */
69415277Sslatteng if (leftmarg + 2*(pageno ? leftmarg/pageno : 0) > WIDTH /* this page, */
69515277Sslatteng || maxh > WIDTH - INCH || first) { /* or this is the first page */
69615277Sslatteng oflush();
69716375Sslatteng printf("p%d\n", spanno++); /* make it a REAL page-break */
69815277Sslatteng first = pageno = leftmarg = maxh = 0;
69915277Sslatteng } else { /* x = last page's width (in half-inches) */
70015277Sslatteng register int x = (maxh - leftmarg + (HALF - 1)) / HALF;
70115277Sslatteng
70215277Sslatteng if (x > 11 && x <= 17)
70314758Sslatteng leftmarg += (8 * INCH) + HALF; /* if close to 8.5" */
70414758Sslatteng else /* then make it so */
70514758Sslatteng leftmarg = ((maxh + HALF) / HALF) * HALF; /* else set it to the */
70615277Sslatteng pageno++; /* nearest half-inch */
70715277Sslatteng }
70814758Sslatteng }
70914758Sslatteng
71014758Sslatteng
startspan(n)71113918Sslatteng startspan(n)
71213918Sslatteng register int n;
71313918Sslatteng {
71413918Sslatteng *op++ = 0;
71513918Sslatteng if (nvlist >= NVLIST) {
71615946Sslatteng #ifdef DEBUGABLE
71715946Sslatteng error(!FATAL, "ran out of vlist");
71815946Sslatteng #endif
71913918Sslatteng oflush();
72013918Sslatteng }
72114758Sslatteng vlp++;
72213918Sslatteng vlp->p = op;
72313918Sslatteng vlp->v = n;
72414758Sslatteng vlp->d = n;
72514758Sslatteng vlp->u = n;
72613918Sslatteng vlp->h = hpos;
72713918Sslatteng vlp->s = size;
72813918Sslatteng vlp->f = font;
729*16548Sslatteng vlp->l = stip;
73014285Sslatteng vlp->st = style;
73114285Sslatteng vlp->t = thick;
73213918Sslatteng nvlist++;
73313918Sslatteng }
734*16548Sslatteng
735*16548Sslatteng
736*16548Sslatteng #define MAXX 0x7fff
737*16548Sslatteng #define MINX 0x8000
738*16548Sslatteng
739*16548Sslatteng typedef struct poly {
740*16548Sslatteng struct poly *next; /* doublely-linked lists of vectors */
741*16548Sslatteng struct poly *prev;
742*16548Sslatteng int param; /* bressenham line algorithm parameter */
743*16548Sslatteng short dx; /* delta-x for calculating line */
744*16548Sslatteng short dy; /* delta-y for calculating line */
745*16548Sslatteng short currx; /* current x in this vector */
746*16548Sslatteng short endy; /* where vector ends */
747*16548Sslatteng } polyvector;
748*16548Sslatteng
749*16548Sslatteng
750*16548Sslatteng /*----------------------------------------------------------------------------*
751*16548Sslatteng | Routine: polygon ( member, num_vectors, x_coor, y_coor, maxy, miny )
752*16548Sslatteng |
753*16548Sslatteng | Results: outputs commands to draw a polygon starting at (x[1], y[1])
754*16548Sslatteng | going through each of (x_coordinates, y_coordinates), and
755*16548Sslatteng | filled with "member" stipple pattern.
756*16548Sslatteng |
757*16548Sslatteng | A scan-line algorithm is simulated and pieces of the
758*16548Sslatteng | polygon are put out that fit on bands of the versatec
759*16548Sslatteng | output filter.
760*16548Sslatteng |
761*16548Sslatteng | The format of the polygons put out are:
762*16548Sslatteng | 'Dp member num miny maxy [p dx dy curx endy]'
763*16548Sslatteng | where "num" is the number of [..] entries in that
764*16548Sslatteng | section of the polygon.
765*16548Sslatteng *----------------------------------------------------------------------------*/
766*16548Sslatteng
polygon(member,nvect,x,y,maxy,miny)767*16548Sslatteng polygon(member, nvect, x, y, maxy, miny)
768*16548Sslatteng int member;
769*16548Sslatteng int nvect;
770*16548Sslatteng int x[];
771*16548Sslatteng int y[];
772*16548Sslatteng int maxy;
773*16548Sslatteng int miny;
774*16548Sslatteng {
775*16548Sslatteng int nexty; /* at what x value the next vector starts */
776*16548Sslatteng register int active; /* number of vectors in active list */
777*16548Sslatteng int firsttime; /* force out a polgon the first time through */
778*16548Sslatteng polyvector *activehead; /* doing fill, is active edge list */
779*16548Sslatteng polyvector *waitinghead; /* edges waiting to be active */
780*16548Sslatteng register polyvector *vectptr; /* random vector */
781*16548Sslatteng register int i; /* random register */
782*16548Sslatteng
783*16548Sslatteng
784*16548Sslatteng /* allocate space for raster-fill algorithm*/
785*16548Sslatteng vectptr = (polyvector *) malloc(sizeof(polyvector) * (nvect + 4));
786*16548Sslatteng if (vectptr == (polyvector *) NULL) {
787*16548Sslatteng error(!FATAL, "unable to allocate space for polygon");
788*16548Sslatteng return;
789*16548Sslatteng }
790*16548Sslatteng
791*16548Sslatteng waitinghead = vectptr;
792*16548Sslatteng vectptr->param = miny - 1;
793*16548Sslatteng (vectptr++)->prev = NULL; /* put dummy entry at start */
794*16548Sslatteng waitinghead->next = vectptr;
795*16548Sslatteng vectptr->prev = waitinghead;
796*16548Sslatteng i = 1; /* starting point of coords */
797*16548Sslatteng if (y[1] != y[nvect] || x[1] != x[nvect]) {
798*16548Sslatteng y[0] = y[nvect]; /* close polygon if it's not */
799*16548Sslatteng x[0] = x[nvect];
800*16548Sslatteng i = 0;
801*16548Sslatteng }
802*16548Sslatteng active = 0;
803*16548Sslatteng while (i < nvect) { /* set up the vectors */
804*16548Sslatteng register int j; /* indexes to work off of */
805*16548Sslatteng register int k;
806*16548Sslatteng
807*16548Sslatteng j = i; /* j "points" to the higher (lesser) point */
808*16548Sslatteng k = ++i;
809*16548Sslatteng if (y[j] == y[k]) /* ignore horizontal lines */
810*16548Sslatteng continue;
811*16548Sslatteng
812*16548Sslatteng if (y[j] > y[k]) {
813*16548Sslatteng j++;
814*16548Sslatteng k--;
815*16548Sslatteng }
816*16548Sslatteng active++;
817*16548Sslatteng vectptr->next = vectptr + 1;
818*16548Sslatteng vectptr->param = y[j]; /* starting point of vector */
819*16548Sslatteng vectptr->dx = x[k] - x[j]; /* line-calculating parameters */
820*16548Sslatteng vectptr->dy = y[k] - y[j];
821*16548Sslatteng vectptr->currx = x[j]; /* starting point */
822*16548Sslatteng (vectptr++)->endy = y[k]; /* ending point */
823*16548Sslatteng vectptr->prev = vectptr - 1;
824*16548Sslatteng }
825*16548Sslatteng /* if no useable vectors, quit */
826*16548Sslatteng if (active < 2)
827*16548Sslatteng goto leavepoly;
828*16548Sslatteng
829*16548Sslatteng vectptr->param = maxy + 1; /* dummy entry at end, too */
830*16548Sslatteng vectptr->next = NULL;
831*16548Sslatteng
832*16548Sslatteng activehead = ++vectptr; /* two dummy entries for active list */
833*16548Sslatteng vectptr->currx = MINX; /* head */
834*16548Sslatteng vectptr->endy = maxy + 1;
835*16548Sslatteng vectptr->param = vectptr->dx = vectptr->dy = 0;
836*16548Sslatteng activehead->next = ++vectptr;
837*16548Sslatteng activehead->prev = vectptr;
838*16548Sslatteng vectptr->prev = activehead; /* tail */
839*16548Sslatteng vectptr->next = activehead;
840*16548Sslatteng vectptr->currx = MAXX;
841*16548Sslatteng vectptr->endy = maxy + 1;
842*16548Sslatteng vectptr->param = vectptr->dx = vectptr->dy = 0;
843*16548Sslatteng
844*16548Sslatteng /* if there's no need to break the */
845*16548Sslatteng /* polygon into pieces, don't bother */
846*16548Sslatteng if (diffspan(miny, maxy)) {
847*16548Sslatteng active = 0; /* will keep track of # of vectors */
848*16548Sslatteng firsttime = 1;
849*16548Sslatteng } else { /* in the active list */
850*16548Sslatteng startspan(miny);
851*16548Sslatteng sprintf(op, "Dq %d %d %d %d", member, active, miny, maxy);
852*16548Sslatteng op += strlen(op);
853*16548Sslatteng for (vectptr = waitinghead->next; active--; vectptr++) {
854*16548Sslatteng sprintf(op, " %d %d %d %d %d",
855*16548Sslatteng vectptr->param, vectptr->dx, vectptr->dy,
856*16548Sslatteng vectptr->currx, vectptr->endy);
857*16548Sslatteng op += strlen(op);
858*16548Sslatteng }
859*16548Sslatteng *(op++) = '\n';
860*16548Sslatteng goto leavepoly;
861*16548Sslatteng }
862*16548Sslatteng /* main loop -- gets vectors off the waiting list, */
863*16548Sslatteng /* then displays spans while updating the vectors in */
864*16548Sslatteng /* the active list */
865*16548Sslatteng while (miny <= maxy) {
866*16548Sslatteng i = maxy + 1; /* this is the NEXT time to get a new vector */
867*16548Sslatteng for (vectptr = waitinghead->next; vectptr != NULL; ) {
868*16548Sslatteng if (miny == vectptr->param) {
869*16548Sslatteng /* the entry in waiting list (vectptr) is */
870*16548Sslatteng /* ready to go into active list. Need to */
871*16548Sslatteng /* convert some vector stuff and sort the */
872*16548Sslatteng /* entry into the list. */
873*16548Sslatteng register polyvector *p; /* random vector pointers */
874*16548Sslatteng register polyvector *v;
875*16548Sslatteng
876*16548Sslatteng /* convert this */
877*16548Sslatteng if (vectptr->dx < 0) /* entry to active */
878*16548Sslatteng vectptr->param = -((vectptr->dx >> 1) + (vectptr->dy >> 1));
879*16548Sslatteng else
880*16548Sslatteng vectptr->param = (vectptr->dx >> 1) - (vectptr->dy >> 1);
881*16548Sslatteng
882*16548Sslatteng p = vectptr; /* remove from the */
883*16548Sslatteng vectptr = vectptr->next; /* waiting list */
884*16548Sslatteng vectptr->prev = p->prev;
885*16548Sslatteng p->prev->next = vectptr;
886*16548Sslatteng /* find where it goes */
887*16548Sslatteng /* in the active list */
888*16548Sslatteng /* (sorted smallest first) */
889*16548Sslatteng for (v = activehead->next; v->currx < p->currx; v = v->next)
890*16548Sslatteng ;
891*16548Sslatteng p->next = v; /* insert into active list */
892*16548Sslatteng p->prev = v->prev; /* before the one it stopped on */
893*16548Sslatteng v->prev = p;
894*16548Sslatteng p->prev->next = p;
895*16548Sslatteng active++;
896*16548Sslatteng } else {
897*16548Sslatteng if (i > vectptr->param) {
898*16548Sslatteng i = vectptr->param;
899*16548Sslatteng }
900*16548Sslatteng vectptr = vectptr->next;
901*16548Sslatteng }
902*16548Sslatteng }
903*16548Sslatteng nexty = i;
904*16548Sslatteng
905*16548Sslatteng /* print the polygon while there */
906*16548Sslatteng /* are no more vectors to add */
907*16548Sslatteng while (miny < nexty) {
908*16548Sslatteng /* remove any finished vectors */
909*16548Sslatteng vectptr = activehead->next;
910*16548Sslatteng do {
911*16548Sslatteng if (vectptr->endy <= miny) {
912*16548Sslatteng vectptr->prev->next = vectptr->next;
913*16548Sslatteng vectptr->next->prev = vectptr->prev;
914*16548Sslatteng active--;
915*16548Sslatteng }
916*16548Sslatteng } while ((vectptr = vectptr->next) != activehead);
917*16548Sslatteng
918*16548Sslatteng /* output a polygon for this band */
919*16548Sslatteng if (firsttime || !(miny % NLINES)) {
920*16548Sslatteng register int numwait; /* number in the waiting list */
921*16548Sslatteng register int newmaxy; /* max for this band (bottom or maxy)*/
922*16548Sslatteng
923*16548Sslatteng
924*16548Sslatteng startspan(miny);
925*16548Sslatteng if ((newmaxy = (miny / NLINES) * NLINES + (NLINES - 1)) > maxy)
926*16548Sslatteng newmaxy = maxy;
927*16548Sslatteng
928*16548Sslatteng /* count up those vectors that WILL */
929*16548Sslatteng /* become active in this band */
930*16548Sslatteng for (numwait = 0, vectptr = waitinghead->next;
931*16548Sslatteng vectptr != NULL; vectptr = vectptr->next) {
932*16548Sslatteng if (vectptr->param <= newmaxy)
933*16548Sslatteng numwait++;
934*16548Sslatteng }
935*16548Sslatteng
936*16548Sslatteng sprintf(op,"Dq %d %d %d %d",member,active+numwait,miny,newmaxy);
937*16548Sslatteng op += strlen(op);
938*16548Sslatteng for (i = active, vectptr = activehead->next; i--;
939*16548Sslatteng vectptr = vectptr->next) {
940*16548Sslatteng sprintf(op, " %d %d %d %d %d",
941*16548Sslatteng vectptr->param, vectptr->dx, -vectptr->dy,
942*16548Sslatteng vectptr->currx, vectptr->endy);
943*16548Sslatteng op += strlen(op);
944*16548Sslatteng }
945*16548Sslatteng for (vectptr = waitinghead->next; vectptr != NULL;
946*16548Sslatteng vectptr = vectptr->next) {
947*16548Sslatteng if (vectptr->param <= newmaxy) {
948*16548Sslatteng sprintf(op, " %d %d %d %d %d",
949*16548Sslatteng vectptr->param, vectptr->dx, vectptr->dy,
950*16548Sslatteng vectptr->currx, vectptr->endy);
951*16548Sslatteng op += strlen(op);
952*16548Sslatteng }
953*16548Sslatteng }
954*16548Sslatteng *(op++) = '\n';
955*16548Sslatteng firsttime = 0;
956*16548Sslatteng }
957*16548Sslatteng
958*16548Sslatteng /* update the vectors */
959*16548Sslatteng vectptr = activehead->next;
960*16548Sslatteng do {
961*16548Sslatteng if (vectptr->dx > 0) {
962*16548Sslatteng while (vectptr->param >= 0) {
963*16548Sslatteng vectptr->param -= vectptr->dy;
964*16548Sslatteng vectptr->currx++;
965*16548Sslatteng }
966*16548Sslatteng vectptr->param += vectptr->dx;
967*16548Sslatteng } else if (vectptr->dx < 0) {
968*16548Sslatteng while (vectptr->param >= 0) {
969*16548Sslatteng vectptr->param -= vectptr->dy;
970*16548Sslatteng vectptr->currx--;
971*16548Sslatteng }
972*16548Sslatteng vectptr->param -= vectptr->dx;
973*16548Sslatteng }
974*16548Sslatteng /* must sort the vectors if updates */
975*16548Sslatteng /* caused them to cross */
976*16548Sslatteng /* also move to next vector here */
977*16548Sslatteng if (vectptr->currx < vectptr->prev->currx) {
978*16548Sslatteng register polyvector *v; /* vector to move */
979*16548Sslatteng register polyvector *p; /* vector to put it after */
980*16548Sslatteng
981*16548Sslatteng v = vectptr;
982*16548Sslatteng p = v->prev;
983*16548Sslatteng while (v->currx < p->currx) /* find the */
984*16548Sslatteng p = p->prev; /* right vector */
985*16548Sslatteng
986*16548Sslatteng vectptr = vectptr->next; /* remove from spot */
987*16548Sslatteng vectptr->prev = v->prev;
988*16548Sslatteng v->prev->next = vectptr;
989*16548Sslatteng
990*16548Sslatteng v->prev = p; /* put in new spot */
991*16548Sslatteng v->next = p->next;
992*16548Sslatteng p->next = v;
993*16548Sslatteng v->next->prev = v;
994*16548Sslatteng } else {
995*16548Sslatteng vectptr = vectptr->next;
996*16548Sslatteng }
997*16548Sslatteng } while (vectptr != activehead);
998*16548Sslatteng
999*16548Sslatteng ++miny;
1000*16548Sslatteng } /* while (miny < nexty) */
1001*16548Sslatteng } /* while (miny <= maxy) */
1002*16548Sslatteng
1003*16548Sslatteng leavepoly:
1004*16548Sslatteng startspan(vpos); /* make sure stuff after polygon is at correct vpos */
1005*16548Sslatteng free(waitinghead);
1006*16548Sslatteng } /* polygon function */
1007