|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.