|
|
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.