|
|
1.1 ! root 1: #include <u.h> ! 2: #include <libc.h> ! 3: #include <libg.h> ! 4: #include <gnot.h> ! 5: ! 6: extern int _setdda(int, int, Linedesc*); ! 7: int check(GBitmap *, Point, Point, int); ! 8: int cleared(GBitmap *, Rectangle); ! 9: void clear(GBitmap *); ! 10: Bitmap *gtob(GBitmap *); ! 11: int dbg; ! 12: ! 13: int ! 14: main(int argc, char *argv[]) ! 15: { ! 16: int iters, ld, simple, i, rx, ry, any; ! 17: Point rmin, rmax, p0, p1, pp0, pp1; ! 18: long seed; ! 19: int good; ! 20: Rectangle clipr, gbr; ! 21: GBitmap *gb; ! 22: Linedesc l; ! 23: char c; ! 24: ! 25: binit(0, 0, 0); ! 26: ld = 0; ! 27: iters = 1000; ! 28: simple = 0; ! 29: ARGBEGIN { ! 30: case 'i': ! 31: iters = atoi(ARGF()); ! 32: break; ! 33: case 's': ! 34: simple = 1; ! 35: break; ! 36: } ARGEND ! 37: if(argc > 0) ! 38: ld = atoi(argv[0]); ! 39: if(simple) { ! 40: rmin = Pt(0,0); ! 41: rmax = Pt(500,500); ! 42: } else { ! 43: seed = time(0); ! 44: print("seed %lux\n", seed); ! 45: srand(seed); ! 46: rmin = Pt(nrand(63)-31,nrand(63)-31); ! 47: rmax = Pt(rmin.x+500,rmin.y+500); ! 48: } ! 49: gbr = Rpt(rmin,rmax); ! 50: gb = gballoc(gbr, ld); ! 51: rmin = add(rmin,Pt(5,5)); ! 52: rmax = sub(rmax,Pt(5,5)); ! 53: rx = rmax.x - rmin.x; ! 54: ry = rmax.y - rmin.y; ! 55: print("unclipped lines\n"); ! 56: good = 0; ! 57: for(i = 0; i < iters; i++) { ! 58: p0 = add(rmin,Pt(nrand(rx),nrand(ry))); ! 59: p1 = add(rmin,Pt(nrand(rx),nrand(ry))); ! 60: pp0 = p0; ! 61: pp1 = p1; ! 62: any = _clipline(gb->r, &pp0, &pp1, &l); ! 63: gsegment(gb, p0, p1, ~0, S); ! 64: if(!check(gb, pp0, pp1, any)) { ! 65: print("%d good\n", good); ! 66: print("failure drawing [%d,%d][%d,%d], closed=[%d,%d][%d,%d]; dx %d dy %d\n", ! 67: p0.x, p0.y, p1.x, p1.y, ! 68: pp0.x, pp0.y, pp1.x, pp1.y, ! 69: p1.x-p0.x, p1.y-p0.y); ! 70: good = 0; ! 71: }else ! 72: good++; ! 73: gsegment(gb, p0, p1, 0, Zero); ! 74: } ! 75: print("%d good\n", good); ! 76: print("clipped lines\n"); ! 77: good = 0; ! 78: for(i = 0; i < iters; i++) { ! 79: p0 = add(rmin,Pt(nrand(rx),nrand(ry))); ! 80: p1 = add(rmin,Pt(nrand(rx),nrand(ry))); ! 81: pp0 = p0; ! 82: pp1 = p1; ! 83: clipr = rcanon(Rpt(add(rmin,Pt(nrand(rx),nrand(ry))), ! 84: add(rmin,Pt(nrand(rx),nrand(ry))))); ! 85: any = _clipline(clipr, &pp0, &pp1, &l); ! 86: gb->r = clipr; ! 87: gsegment(gb, p0, p1, ~0, S); ! 88: gb->r = gbr; ! 89: if(!check(gb, pp0, pp1, any)) { ! 90: print("%d good\n", good); ! 91: print("failure drawing [%d,%d][%d,%d], clip rect [[%d,%d][%d,%d]], clipped,closed=[%d,%d][%d,%d]; dx %d dy %d\n", ! 92: p0.x, p0.y, p1.x, p1.y, ! 93: clipr.min.x, clipr.min.y, clipr.max.x, clipr.max.y, ! 94: pp0.x, pp0.y, pp1.x, pp1.y, ! 95: p1.x-p0.x, p1.y-p0.y); ! 96: good = 0; ! 97: }else ! 98: good++; ! 99: /* ! 100: * Zero out the line without clipping: see if same pixels touched ! 101: */ ! 102: gsegment(gb, p0, p1, 0, Zero); ! 103: if(!cleared(gb, clipr)) { ! 104: if(good) { ! 105: print("%d good\n", good); ! 106: print("failure to clear [%d,%d][%d,%d], clip rect [[%d,%d][%d,%d]], clipped,closed=[%d,%d][%d,%d]; dx %d dy %d\n", ! 107: p0.x, p0.y, p1.x, p1.y, ! 108: clipr.min.x, clipr.min.y, ! 109: clipr.max.x, clipr.max.y, ! 110: pp0.x, pp0.y, pp1.x, pp1.y, ! 111: p1.x-p0.x, p1.y-p0.y); ! 112: good = 0; ! 113: } ! 114: clear(gb); ! 115: bflush(); ! 116: read(0, &c, 1); ! 117: } ! 118: } ! 119: print("%d good\n", good); ! 120: } ! 121: ! 122: int ! 123: pixset(GBitmap *b, Point p) ! 124: { ! 125: uchar *d; ! 126: uchar mask; ! 127: int l; ! 128: ulong v; ! 129: ! 130: if(!ptinrect(p, b->r)) ! 131: return 0; ! 132: d = gbaddr(b, p); ! 133: l = b->ldepth; ! 134: mask = (~0UL)<<(8-(1<<l)); ! 135: l = (p.x&(0x7>>l))<<l; ! 136: mask >>= l; ! 137: ! 138: v = (*d & mask); ! 139: if(dbg) ! 140: print("pixset [%d,%d] -> %lux\n", p.x, p.y, v); ! 141: return v; ! 142: } ! 143: ! 144: int ! 145: check(GBitmap *b, Point p0, Point p1, int any) ! 146: { ! 147: int ans, dirx, diry; ! 148: ! 149: dirx = (p0.x < p1.x)? 1 : -1; ! 150: diry = (p0.y < p1.y)? 1 : -1; ! 151: ans = (any? pixset(b, p0) : !pixset(b, p0)) && ! 152: !pixset(b, add(p0, Pt(0, -diry))) && ! 153: !pixset(b, add(p0, Pt(-dirx, 0))) && ! 154: !pixset(b, add(p0, Pt(-dirx, -diry))) && ! 155: (any? pixset(b, p1) : !pixset(b, p1)) && ! 156: !pixset(b, add(p1, Pt(0, diry))) && ! 157: !pixset(b, add(p1, Pt(dirx, 0))) && ! 158: !pixset(b, add(p1, Pt(dirx, diry))); ! 159: if(!ans) { ! 160: dbg = 1; ! 161: pixset(b, p0); ! 162: pixset(b, add(p0, Pt(0, -diry))); ! 163: pixset(b, add(p0, Pt(-dirx, 0))); ! 164: pixset(b, add(p0, Pt(-dirx, -diry))); ! 165: pixset(b, p1); ! 166: pixset(b, add(p1, Pt(0, diry))); ! 167: pixset(b, add(p1, Pt(dirx, 0))); ! 168: pixset(b, add(p1, Pt(dirx, diry))); ! 169: dbg = 0; ! 170: } ! 171: return ans; ! 172: } ! 173: ! 174: long ! 175: bwords(GBitmap *b) ! 176: { ! 177: long lsize; ! 178: int wsize; ! 179: ! 180: wsize = 1<<(5-b->ldepth); ! 181: if(b->r.max.x >= 0) ! 182: lsize = (b->r.max.x+wsize-1)/wsize; ! 183: else ! 184: lsize = b->r.max.x/wsize; ! 185: if(b->r.min.x >= 0) ! 186: lsize -= b->r.min.x/wsize; ! 187: else ! 188: lsize -= (b->r.min.x-wsize+1)/wsize; ! 189: lsize *= Dy(b->r); ! 190: return lsize; ! 191: } ! 192: ! 193: int ! 194: cleared(GBitmap *b, Rectangle r) ! 195: { ! 196: ulong *p, *pe; ! 197: ulong n; ! 198: int i, j; ! 199: Bitmap *bb; ! 200: ! 201: p = b->base; ! 202: n = bwords(b); ! 203: pe = b->base + n; ! 204: while(p < pe) ! 205: if(*p++){ ! 206: --p; ! 207: for(i=b->r.min.x; i<b->r.max.x; i++) ! 208: for(j=b->r.min.y; j<b->r.max.y; j++) ! 209: if(gaddr(b, Pt(i, j)) == p){ ! 210: print("bad pixel [%d,%d] %.8lux\n", i, j, *p); ! 211: bb = gtob(b); ! 212: bitblt(&screen, bb->r.min, bb, bb->r, S); ! 213: border(&screen, inset(r, -5), 5, ~D); ! 214: return 0; ! 215: } ! 216: return 0; ! 217: } ! 218: return 1; ! 219: } ! 220: ! 221: void ! 222: clear(GBitmap *b) ! 223: { ! 224: memset(b->base, 0, bwords(b)*sizeof(long)); ! 225: } ! 226: ! 227: Bitmap* ! 228: gtob(GBitmap *g) ! 229: { ! 230: Bitmap *b; ! 231: uchar *u; ! 232: int y; ! 233: ! 234: b = balloc(g->r, g->ldepth); ! 235: if(b == 0){ ! 236: print("can't balloc %R\n", g->r); ! 237: exits(0); ! 238: } ! 239: u = (uchar*)gaddr(g, g->r.min); ! 240: u += (g->r.min.x&31)/8; ! 241: for(y=g->r.min.y; y<g->r.max.y; y++, u+=sizeof(long)*g->width) ! 242: wrbitmap(b, y, y+1, u); ! 243: return b; ! 244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.