Annotation of researchv10no/cmd/view2d/fill.c, revision 1.1.1.1

1.1       root        1: #include       <jerq.h>
                      2: #define                SILLY           -20
                      3: 
                      4: /* Filling interior of arbitrary polygons on the Blit */
                      5: static draw(), xcut(), place(), realfill();
                      6: 
                      7: #ifdef TEST
                      8: #include       <font.h>
                      9: Texture black =
                     10: {
                     11:        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
                     12:        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
                     13: };
                     14: 
                     15: main()
                     16: {
                     17:        Point pts[40], *p;
                     18: 
                     19:        request(MOUSE);
                     20:        string(&defont, "b1 vertex; b2 end; b3 exit", &display, Drect.origin, F_XOR);
                     21:        p = pts;
                     22:        for(;;)
                     23:        {
                     24:                wait(CPU);
                     25:                wait(MOUSE);
                     26:                if((own()&MOUSE) && button1())
                     27:                {
                     28:                        *p++ = mouse.xy;
                     29:                        if(p != pts) segment(&display, p[-2], p[-1], F_OR);
                     30:                        while(button1()) nap(1);
                     31:                }
                     32:                if((own()&MOUSE) && button2())
                     33:                {
                     34:                        *p++ = pts[0];
                     35:                        while(button2()) nap(1);
                     36:                        ppfill(pts, (int)(p-pts), &display, &black, F_OR);
                     37:                        p = pts;
                     38:                }
                     39:                if((own()&MOUSE) && button3())
                     40:                {
                     41:                        while(button3()) nap(1);
                     42:                        exit(0);
                     43:                }
                     44:        }
                     45: }
                     46: #endif TEST
                     47: 
                     48: struct seg { short x, y, X, Y; char stat;} ;
                     49: typedef struct seg segS;
                     50: typedef struct seg * segP;
                     51: typedef Point *pointP;
                     52: #ifdef BRAVE
                     53: segP sinp;
                     54: #else
                     55: segS sinp[128];
                     56: #endif
                     57: 
                     58: static short ymin;
                     59: 
                     60: #define COMP(A)  if(p1->A>p2->A) return(-1); else if(p1->A<p2->A) return(1);
                     61: 
                     62: static
                     63: place(p1,p2) segP p1, p2;
                     64: {
                     65:        COMP(y) else { 
                     66:                COMP(x) else { 
                     67:                        COMP(X) else { 
                     68:                                COMP(Y) else return(0);
                     69:                        }
                     70:                }
                     71:        }
                     72: }
                     73: 
                     74: #define SWITCH { xyt=y; y=Y; Y=xyt; xyt=x; x=X; X=xyt; ren=0;}
                     75: 
                     76: ppfill(pts, npts, bm, text, mode)
                     77:        Point *pts;
                     78:        Bitmap *bm;
                     79:        Texture *text;
                     80: {
                     81:        short  so;
                     82:        short x, y, X, Y;
                     83:        short xyt, ren, newc;
                     84:        register pointP pp, qq, opp;
                     85:        register segP sp;
                     86:        register j;
                     87: 
                     88: #ifdef BRAVE
                     89:        sinp = (segP)alloc((unsigned)((npts+2)*sizeof(segS)));
                     90:        if(!sinp) return(-1);
                     91: #else
                     92:        if(npts>125) return(-1);
                     93: #endif
                     94: #ifdef EFFIC
                     95:        if(npts==4){
                     96:                rectf(bm,Rect(pts->x,pts->y,
                     97:                        (pts[2]).x,(pts[2]).y),mode);
                     98:        }
                     99: #endif
                    100:        ymin = Drect.origin.y;
                    101:        qq = pts;
                    102:        x = qq->x;      y = qq->y;
                    103:        pp = qq + 1;
                    104:        for(j=1,sp=sinp,so=0;j<=npts;j++,pp++) {
                    105:                /* missing: we should take precaution abt HH */
                    106:                if(j==npts) pp = qq;
                    107:                if(pp->x < SILLY) {     /*break in contour*/
                    108:                        opp = pp;
                    109:                        pp = qq;
                    110:                        newc = 1;
                    111:                }
                    112:                else newc = 0;
                    113:                X = pp->x;      Y = pp->y;
                    114:                if(Y<ymin) ymin = Y;
                    115:                if(Y>y) SWITCH
                    116:                else {if(Y==y && x<X) SWITCH    else ren=1;}
                    117:                sp->x=x; sp->y=y; sp->X=X; sp->Y=Y; sp->stat=1;
                    118:                if(ren) { x = X; y = Y;}
                    119:                sp++; so++;
                    120:                if(newc) {
                    121:                        qq = opp + 1;
                    122:                        if(!qq) break;
                    123:                        x = qq->x;      y = qq->y;
                    124:                        pp = qq;        /*will be incr. in loop*/
                    125:                        j++;
                    126:                }
                    127:        }
                    128:        realfill(so,ymin,bm,text,mode);
                    129: #ifdef BRAVE
                    130:        free(sinp);
                    131: #endif
                    132:        return(1);
                    133: }
                    134: 
                    135: /* Fill a contour defined by a set of line segments */
                    136: 
                    137: static
                    138: realfill(so, yymin, bm, text, mode)
                    139:        int so, yymin;
                    140:        Bitmap *bm;
                    141:        Texture *text;
                    142: {
                    143:        int i, n;
                    144:        int yb;
                    145:        segP  sp, s1, s2, sfin, st, sbf, snx;
                    146:        for(i=0,sp=sinp;i<so;i++,sp++) sp->stat = 1;
                    147:        sfin = sp;      /*sp was not incremented last time*/
                    148:        /* edit horizontal lines */
                    149:        for(i=0,sp=sinp;i<so;i++,sp++){
                    150:                if(!(sp->stat)) continue;
                    151:                if(sp->y != sp->Y) continue;
                    152:                if(sp==sinp) sbf = sp+so-1; 
                    153:                else sbf = sp-1;
                    154:                if(sp<sfin) snx = sp+1;
                    155:                else snx = sp;
                    156:                if(sbf->y==sp->y){      /* point before is below*/
                    157:                        if(snx->y==sp->y){      /* both below */
                    158:                                sp->stat = 0;
                    159:                        }
                    160:                        continue;
                    161:                }
                    162:                else if(sbf->Y==sp->y){ /*previous point above*/
                    163:                        if(snx->Y==sp->y){      /* both above */
                    164:                                sp->stat = 0;
                    165:                        }
                    166:                        continue;
                    167:                }
                    168:        }
                    169:        /* finished with horizontal editing */
                    170: 
                    171:        qsort(sinp,so,sizeof(struct seg),place);
                    172: 
                    173:        sp = sinp; 
                    174:        i = 0;
                    175:        n = so;
                    176:        s1 = sp; 
                    177:        yb = s1->y;
                    178:        for(;yb<=sp->y;sp++,i++);
                    179:        s2 = sp - 1;
                    180:        for(;yb>=yymin;yb--){
                    181:                draw(yb,s1,s2, bm, text, mode);
                    182:                for(st=s1;st<=s2;st++){
                    183:                        if(!(st->stat)) continue;
                    184:                        if(yb<=st->Y) st->stat=0;
                    185:                }
                    186:                if(sp >= sfin) continue; /*nomore*/
                    187:                if(i>=n) continue;
                    188:                for(;yb<=(sp->y+1)&&i<n;sp++,i++){ /*we have gone below next element */
                    189:                        for(st=s1;st<=s2;st++){
                    190:                                if(sp->y==st->Y){
                    191:                                        if(sp->x==st->X) st->stat=0;
                    192:                                        else if(sp->Y==sp->y&&sp->X==st->X) st->stat=0;
                    193:                                }
                    194:                        }
                    195:                }
                    196:                /*cleanup*/
                    197:                s2 = sp - 1;
                    198:                while(!(s1->stat)) s1++;
                    199:        }
                    200: }
                    201: 
                    202: #define NCUTS 32
                    203: #define NCUTS_1 31
                    204: 
                    205: static
                    206: draw(y,pr1,pr2, bm, text, mode)
                    207:        int y;  segP pr1, pr2;
                    208:        Bitmap *bm;
                    209:        Texture *text;
                    210: {
                    211:        register segP pr;
                    212:        register i, j, k, n;
                    213:        int x[NCUTS];
                    214:        for(pr=pr1,n=0;pr<=pr2;pr++){
                    215:                if(!(pr->stat)) continue;
                    216:                if(pr->y==pr->Y) continue; /* ignore horizontals */
                    217:                x[n++] = xcut(y,pr->x,pr->y,pr->X,pr->Y);
                    218:                if(n>NCUTS_1) /*jtag(1,"Too many intersections")*/;
                    219:        }
                    220:        if(n<=1) return(0);
                    221:        k=1;
                    222:        while(k){
                    223:                k = 0;
                    224:                for(i=1;i<n;i++){
                    225:                        if(x[i-1]>x[i]) {
                    226:                                j=x[i-1]; 
                    227:                                x[i-1]=x[i]; 
                    228:                                x[i]=j; 
                    229:                                k=1;
                    230:                        }
                    231:                }
                    232:        }
                    233:        for(i=1;i<n;i +=2) 
                    234:                texture(bm,Rect(x[i-1],y,x[i]+1,y+2),text, mode);
                    235: 
                    236:        return(1);
                    237: }
                    238: 
                    239: static
                    240: xcut(y,x1,y1,x2,y2){
                    241:        long dx, dy, xy;
                    242:        int x;
                    243:        if(y1==y2) {
                    244:                x = x1>x2? x1: x2; 
                    245:                return(x);
                    246:        }
                    247:        dy = y1-y2; 
                    248:        dx = x1-x2; 
                    249:        xy = (long)y1*x2-x1*(long)y2;
                    250:        x = (y*dx+xy)/dy;       /*dy non zero because of prev. check*/
                    251:        return(x);
                    252: }

unix.superglobalmegacorp.com

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