File:  [Plan 9 NeXT] / lucent / sys / src / libgnot / segtest.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:01:05 2018 UTC (8 years, 1 month ago) by root
Branches: lucent, MAIN
CVS tags: plan9, HEAD
Plan 9 NeXT

#include <u.h>
#include <libc.h>
#include <libg.h>
#include <gnot.h>

extern int _setdda(int, int, Linedesc*);
int check(GBitmap *, Point, Point, int);
int cleared(GBitmap *, Rectangle);
void clear(GBitmap *);
Bitmap *gtob(GBitmap *);
int dbg;

int
main(int argc, char *argv[])
{
	int iters, ld, simple, i, rx, ry, any;
	Point rmin, rmax, p0, p1, pp0, pp1;
	long seed;
	int good;
	Rectangle clipr, gbr;
	GBitmap *gb;
	Linedesc l;
	char c;

	binit(0, 0, 0);
	ld = 0;
	iters = 1000;
	simple = 0;
	ARGBEGIN {
	case 'i':
		iters = atoi(ARGF());
		break;
	case 's':
		simple = 1;
		break;
	} ARGEND
	if(argc > 0)
		ld = atoi(argv[0]);
	if(simple) {
		rmin = Pt(0,0);
		rmax = Pt(500,500);
	} else {
		seed = time(0);
		print("seed %lux\n", seed);
		srand(seed);
		rmin = Pt(nrand(63)-31,nrand(63)-31);
		rmax = Pt(rmin.x+500,rmin.y+500);
	}
	gbr = Rpt(rmin,rmax);
	gb = gballoc(gbr, ld);
	rmin = add(rmin,Pt(5,5));
	rmax = sub(rmax,Pt(5,5));
	rx = rmax.x - rmin.x;
	ry = rmax.y - rmin.y;
	print("unclipped lines\n");
	good = 0;
	for(i = 0; i < iters; i++) {
		p0 = add(rmin,Pt(nrand(rx),nrand(ry)));
		p1 = add(rmin,Pt(nrand(rx),nrand(ry)));
		pp0 = p0;
		pp1 = p1;
		any = _clipline(gb->r, &pp0, &pp1, &l);
		gsegment(gb, p0, p1, ~0, S);
		if(!check(gb, pp0, pp1, any)) {
			print("%d good\n", good);
			print("failure drawing [%d,%d][%d,%d], closed=[%d,%d][%d,%d]; dx %d dy %d\n",
				p0.x, p0.y, p1.x, p1.y,
				pp0.x, pp0.y, pp1.x, pp1.y,
				p1.x-p0.x, p1.y-p0.y);
			good = 0;
		}else
			good++;
		gsegment(gb, p0, p1, 0, Zero);
	}
	print("%d good\n", good);
	print("clipped lines\n");
	good = 0;
	for(i = 0; i < iters; i++) {
		p0 = add(rmin,Pt(nrand(rx),nrand(ry)));
		p1 = add(rmin,Pt(nrand(rx),nrand(ry)));
		pp0 = p0;
		pp1 = p1;
		clipr = rcanon(Rpt(add(rmin,Pt(nrand(rx),nrand(ry))),
				   add(rmin,Pt(nrand(rx),nrand(ry)))));
		any = _clipline(clipr, &pp0, &pp1, &l);
		gb->r = clipr;
		gsegment(gb, p0, p1, ~0, S);
		gb->r = gbr;
		if(!check(gb, pp0, pp1, any)) {
			print("%d good\n", good);
			print("failure drawing [%d,%d][%d,%d], clip rect [[%d,%d][%d,%d]], clipped,closed=[%d,%d][%d,%d]; dx %d dy %d\n",
				p0.x, p0.y, p1.x, p1.y,
				clipr.min.x, clipr.min.y, clipr.max.x, clipr.max.y,
				pp0.x, pp0.y, pp1.x, pp1.y,
				p1.x-p0.x, p1.y-p0.y);
			good = 0;
		}else
			good++;
		/*
		 * Zero out the line without clipping: see if same pixels touched
		 */
		gsegment(gb, p0, p1, 0, Zero);
		if(!cleared(gb, clipr)) {
			if(good) {
				print("%d good\n", good);
				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",
					p0.x, p0.y, p1.x, p1.y,
					clipr.min.x, clipr.min.y,
					clipr.max.x, clipr.max.y,
					pp0.x, pp0.y, pp1.x, pp1.y,
					p1.x-p0.x, p1.y-p0.y);
				good = 0;
			}
			clear(gb);
			bflush();
			read(0, &c, 1);
		}
	}
	print("%d good\n", good);
}

int
pixset(GBitmap *b, Point p)
{
	uchar *d;
	uchar mask;
	int l;
	ulong v;

	if(!ptinrect(p, b->r))
		return 0;
	d = gbaddr(b, p);
	l = b->ldepth;
	mask = (~0UL)<<(8-(1<<l));
	l = (p.x&(0x7>>l))<<l;
	mask >>= l;

	v = (*d & mask);
	if(dbg)
		print("pixset [%d,%d] -> %lux\n", p.x, p.y, v);
	return v;
}

int
check(GBitmap *b, Point p0, Point p1, int any)
{
	int ans, dirx, diry;

	dirx = (p0.x < p1.x)? 1 : -1;
	diry = (p0.y < p1.y)? 1 : -1;
	ans = (any? pixset(b, p0) : !pixset(b, p0)) &&
		!pixset(b, add(p0, Pt(0, -diry))) &&
		!pixset(b, add(p0, Pt(-dirx, 0))) &&
		!pixset(b, add(p0, Pt(-dirx, -diry))) &&
	      (any? pixset(b, p1) : !pixset(b, p1)) &&
		!pixset(b, add(p1, Pt(0, diry))) &&
		!pixset(b, add(p1, Pt(dirx, 0))) &&
		!pixset(b, add(p1, Pt(dirx, diry)));
	if(!ans) {
		dbg = 1;
		pixset(b, p0);
		pixset(b, add(p0, Pt(0, -diry)));
		pixset(b, add(p0, Pt(-dirx, 0)));
		pixset(b, add(p0, Pt(-dirx, -diry)));
		pixset(b, p1);
		pixset(b, add(p1, Pt(0, diry)));
		pixset(b, add(p1, Pt(dirx, 0)));
		pixset(b, add(p1, Pt(dirx, diry)));
		dbg = 0;
	}
	return ans;
}

long
bwords(GBitmap *b)
{
	long lsize;
	int wsize;

	wsize = 1<<(5-b->ldepth);
	if(b->r.max.x >= 0)
		lsize = (b->r.max.x+wsize-1)/wsize;
	else
		lsize = b->r.max.x/wsize;
	if(b->r.min.x >= 0)
		lsize -= b->r.min.x/wsize;
	else
		lsize -= (b->r.min.x-wsize+1)/wsize;
	lsize *= Dy(b->r);
	return lsize;
}

int
cleared(GBitmap *b, Rectangle r)
{
	ulong *p, *pe;
	ulong n;
	int i, j;
	Bitmap *bb;

	p = b->base;
	n = bwords(b);
	pe = b->base + n;
	while(p < pe)
		if(*p++){
			--p;
			for(i=b->r.min.x; i<b->r.max.x; i++)
			for(j=b->r.min.y; j<b->r.max.y; j++)
				if(gaddr(b, Pt(i, j)) == p){
					print("bad pixel [%d,%d] %.8lux\n", i, j, *p);
					bb = gtob(b);
					bitblt(&screen, bb->r.min, bb, bb->r, S);
					border(&screen, inset(r, -5), 5, ~D);
					return 0;
				}
			return 0;
		}
	return 1;
}

void
clear(GBitmap *b)
{
	memset(b->base, 0, bwords(b)*sizeof(long));
}

Bitmap*
gtob(GBitmap *g)
{
	Bitmap *b;
	uchar *u;
	int y;

	b = balloc(g->r, g->ldepth);
	if(b == 0){
		print("can't balloc %R\n", g->r);
		exits(0);
	}
	u = (uchar*)gaddr(g, g->r.min);
	u += (g->r.min.x&31)/8;
	for(y=g->r.min.y; y<g->r.max.y; y++, u+=sizeof(long)*g->width)
		wrbitmap(b, y, y+1, u);
	return b;
}

unix.superglobalmegacorp.com

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