Annotation of researchv9/jerq/src/lib/jj/polyture.c, revision 1.1.1.1

1.1       root        1: #include       <jerq.h>
                      2: 
                      3: static emax(a,b) { return((a<b)? b:a); }
                      4: static emin(a,b) { return((a>b)? b:a); }
                      5: static ycmp(), xcmp(), xcut();
                      6: 
                      7: typedef struct Edge
                      8: {
                      9:        Point p1, p2;
                     10:        short dolow;
                     11: } Edge;
                     12: static Edge edges[300];
                     13: static Edge *canon();
                     14: 
                     15: polyture(bp, pts, n, t, mode)
                     16:        Bitmap *bp;
                     17:        Point *pts;
                     18:        Texture *t;
                     19: {
                     20:        register Edge *eend, *e, *estart;
                     21:        register y;
                     22:        int ymin, ymax, flag;
                     23:        Point p;
                     24:        int xcuts[64], *xp, *x;
                     25: 
                     26:        eend = canon(pts, n, &ymax);
                     27:        qsort(edges, eend-edges, sizeof(edges[0]), ycmp);
                     28:        ymin = edges->p1.y;
                     29:        eend->p1.y = eend->p2.y = ymax+1;
                     30:        /*
                     31:                traditional scanline
                     32:        */
                     33:        for(estart = eend = edges, y = ymin; y <= ymax; y++)
                     34:        {
                     35:                while(estart->p2.y < y) estart++;
                     36:                while(eend->p1.y <= y) eend++;
                     37:                for(e = estart, xp = xcuts; e < eend; e++)
                     38:                        if((y < e->p2.y) || (e->dolow && (y == e->p2.y)))
                     39:                                *xp++ = xcut(y, e);
                     40:                qsort(xcuts, xp-xcuts, sizeof(*xp), xcmp);
                     41:                for(x = xcuts; x < xp; x += 2)
                     42:                        texture(bp, Rect(*x, y, x[1]+1, y+1), t, mode);
                     43:        }
                     44: }
                     45: 
                     46: static Edge *
                     47: canon(pts, n, ymax)
                     48:        register Point *pts;
                     49:        register *ymax;
                     50: {
                     51:        register Edge *le, *e;
                     52:        register Point *p, *lp, pt;
                     53:        int vert;
                     54: 
                     55:        /*
                     56:                delete horizontal edges; compact vertical edges into one
                     57:        */
                     58:        p = pts;
                     59:        lp = p+n;
                     60:        e = edges;
                     61:        *ymax = p->y;
                     62:        e->p1 = *p++;
                     63:        for(vert = 0; p < lp; p++)
                     64:        {
                     65:                if(*ymax < p->y) *ymax = p->y;
                     66:                if(p->y != p[-1].y)
                     67:                        e++->p2 = *p;
                     68:                e->p1 = *p;
                     69:        }
                     70:        if(vert) e++;
                     71:        le = e;
                     72:        *le = edges[0];
                     73:        le[1] = edges[1];
                     74:        for(e = edges+1; e <= le; e++)
                     75:        {
                     76:                if(e->p1.y < e->p2.y)   /* going down */
                     77:                        e->dolow = (e[1].p1.y-e[1].p2.y) > 0;
                     78:                else
                     79:                        e->dolow = (e[-1].p1.y-e[-1].p2.y) < 0;
                     80:        }
                     81:        edges[0] = *le;
                     82:        /*
                     83:                canonise the edges so that p1.y < p2.y
                     84:                or if p1.y == p2.y then p1.x < p2.x.
                     85:        */
                     86:        for(e = edges; e < le; e++)
                     87:        {
                     88:                if((e->p1.y > e->p2.y) || ((e->p1.y == e->p2.y)&&(e->p1.x > e->p2.x)))
                     89:                        pt = e->p1, e->p1 = e->p2, e->p2 = pt;
                     90:        }
                     91:        return(le);
                     92: }
                     93: 
                     94: static
                     95: ycmp(a, b)
                     96:        register Edge *a, *b;
                     97: {
                     98:        register k;
                     99: 
                    100:        if(k = a->p1.y - b->p1.y)
                    101:                return(k);
                    102:        return(a->p2.y - b->p2.y);
                    103: }
                    104: 
                    105: static
                    106: xcmp(a, b)
                    107:        register int *a, *b;
                    108: {
                    109:        return(*a - *b);
                    110: }
                    111: 
                    112: static
                    113: xcut(y, e)
                    114:        register Edge *e;
                    115: {
                    116:        return(e->p1.x + muldiv(e->p2.x-e->p1.x, y-e->p1.y, e->p2.y-e->p1.y));
                    117: }
                    118: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.