104 lines · 2.8 KB · JavaScript
RawDownload
function rw(r) {	return r[2] - r[0];} function rh(r) {	return r[3] - r[1];} function min(a, b) {	return (a > b) ? b : a;} function max(a, b) {	return (a > b) ? a : b;} function intersect(r, s) {	return [max(r[0], s[0]), max(r[1], s[1]), min(r[2], s[2]), min(r[3], s[3])];} function offset(r, p) {	return [r[0] + p[0], r[1] + p[1], r[2] + p[0], r[3] + p[1]];} function allocimg(rect, fill, repl) {	i = {r: rect, clipr: [0,0,65535,65535], repl: repl};	i.canvas = document.createElement("canvas");	i.canvas.width = rw(i.r);	i.canvas.height = rh(i.r);	i.ctx = i.canvas.getContext("2d");	i.ctx.beginPath();	i.ctx.rect(0, 0, rw(i.r), rh(i.r));	i.ctx.fillStyle = "rgb(" + fill[0] + "," + fill[1] + "," + fill[2] + ")";	i.ctx.fill();//	i.data = i.ctx.getImageData(0, 0, i.canvas.width, i.canvas.height);	return i;} function alphablend(d, s, m) {	var ms; 	ms = m / 255.0; 	return Math.round((s * ms + d * (1.0 - ms)));} defmask = allocimg([0,0,1,1], [255,255,255,255], 1); function memdraw(dst, r, src, sp, mask, mp, op) {	var spr, dx, dy, sx, sy, mx, my, d, s, m, doff, soff, moff; 	spr = [sp[0] + r[0], sp[1] + r[1]];	r = intersect(r, dst.r);	r = intersect(r, offset(src.clipr, spr));	if(src.repl == 0)		r = intersect(r, offset(src.r, spr));	if(mask != undefined){//		throw "mask unimplemented";		r = intersect(r, offset(mask.clipr, mp));		if(mask.repl == 0)			r = intersect(r, offset(mask.r, mp));	}else{		// TODO this is gonna be slow...		mask = defmask;		mp = [0,0];	} 	d = dst.ctx.getImageData(0, 0, dst.canvas.width, dst.canvas.height);	s = src.ctx.getImageData(0, 0, src.canvas.width, src.canvas.height);	m = mask.ctx.getImageData(0, 0, mask.canvas.width, mask.canvas.height);	for(dy = r[1], sy = sp[1], my = mp[1]; dy < r[3]; dy++, sy++, my++){		if(sy == src.canvas.height)			sy -= src.canvas.height;		if(my == mask.canvas.height)			my -= mask.canvas.height;		for(dx = r[0], sx = sp[0], mx = mp[0]; dx < r[2]; dx++, sx++, mx++){			if(sx == src.canvas.width)				sx -= src.canvas.width;			if(mx == mask.canvas.width)				mx -= mask.canvas.width;			doff = (dy * dst.canvas.width + dx) * 4;			soff = (sy * src.canvas.width + sx) * 4;			moff = (my * mask.canvas.width + mx) * 4;			d.data[doff++] = alphablend(d.data[doff], s.data[soff++], m.data[moff++]);			d.data[doff++] = alphablend(d.data[doff], s.data[soff++], m.data[moff++]);			d.data[doff++] = alphablend(d.data[doff], s.data[soff++], m.data[moff++]);			d.data[doff] = 0xFF; // d[doff] = s[soff]; ??? TODO		}	} 	dst.ctx.putImageData(d, 0, 0);} function testdraw() {	var a, b; 	a = allocimg([0, 0, 200, 200], [0,0,0,255], 0);	b = allocimg([0, 0, 8, 8], [255,0,0,255], 1);	c = allocimg([0, 0, 4, 4], [0,255,0,255], 0);	memdraw(b, b.r, c, [0, 0])	memdraw(b, [4, 4, 8, 8], c, [0, 0])	memdraw(a, a.r, b, [0, 0])	canv.putImageData(a.data, 0, 0)}