168 lines · 3.0 KB · JavaScript
RawDownload
/* See /sys/src/libmemdraw/draw.c */ function MUL(x, y){	var t; 	t = (x * y) + 128;	return (t + (t >> 8)) >> 8;} function alphacalcfake(dst, src, mask, dx, op){	var i; 	for(i = 0; i < dst.data.length; ++i)		dst.data[i] = i%4==3? 255:255-mask.data[i+(4-(i%4))];		//dst.data[i] = mask.data[i];	return;} function alphacalc11(dst, src, mask, dx, op){	var i, j;	var sa, ma;	var fd; 	sa = 0;	ma = 0;	for(i = 0; i < dx; ++i){		fd = 255 - MUL(src.data[(sa * 4) + 3], mask.data[(ma * 4)]); 		for(j = 0; j < 4; ++j){			if(j == 3){				dst.data[(i * 4) + j] = 255;			}else			dst.data[(i * 4) + j] =				MUL(src.data[(sa * 4) + j], mask.data[(ma * 4) + 3]) +				MUL(dst.data[(i * 4) + j], fd);		}		if(++sa >= src.width)			sa = 0;		if(++ma >= mask.width)			ma = 0;	}	return dst;} function alphacalc(dst, src, mask, dx, op){	switch(op){		case 11:		default:			return alphacalc11(dst, src, mask, dx, op);	}} function yydata(img, r, y){	var data;	var yd; 	yd = img.width * y;	data = img.data.subarray(yd * 4, (yd + img.width) * 4);	return {		width: img.width,		height: 1,		name: r,		y: y,		data: data	}} /* XXX should use point manipulation. */function yzdata(img, r, y){	var data;	var line; 	line = img.data.width * (r.min.y - img.r.min.y + y);	data = img.data.data.subarray((line + r.min.x - img.r.min.x) * 4, (line + r.min.x - img.r.min.x+ Dx(r)) * 4);	return {		width: Dx(r),		height: 1,		y: y,		data: data	}} function getrect(img, r){ 	if(img.repl)		return img.getrect(img.r);	else		return img.getrect(r);} function drawY(dst, src, mask, op){ 	//if(op == 11)		return alphacalc11(dst, src, mask, dst.width, op);} function clipy(r, y){	if(y >= Dy(r))		return 0;	else if(y < 0)		return Dy(r);	else		return y;} function copysrc(data, srceq){	if(!srceq)		return data; 	data.data = new Uint8ClampedArray(data.data);	return data;} function drawalpha(dst, r, src, sr, mask, mr, op){	var dy;	var dd, sd, md;	var dsty, srcy, masky;	var starty, endy;	var i;	var needbuf, dir; 	dy = Dy(r); 	sr = Rect.copy(sr);	mr = Rect.copy(mr); 	needbuf = src.data == dst.data;	//if(needbuf && (r.min.y * Dx(dst.r) + r.min.x) > (sr.min.y * Dx(src.r) + sr.min.x))	if(needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min))		dir = -1;	else		dir = 1; 	//dir = 1; 	rectclip(sr, src.r);	rectclip(mr, mask.r);	//dd = getrect(dst, r);	//sd = getrect(src, sr);	//md = getrect(mask, mr);	if(dir == 1){		starty = 0;		endy = dy;	}else{		starty = dy - 1;		endy = -1;	}	srcy = starty;//(starty + sr.min.y - src.r.min.y) % Dy(src.r);	masky = starty;//(starty + mr.min.y - mask.r.min.y) % Dy(mask.r)	dsty = starty; // + r.min.y - dst.r.min.y; 	for(i = 0; i < dy; ++i){		dsty = clipy(dst.r, dsty);		srcy = clipy(src.r, srcy);		masky = clipy(mask.r, masky);		//drawY(yydata(dd, r, i), yydata(sd, sr, srcy), yydata(md, mr, masky), op);		drawY(			yzdata(dst, r, dsty),			copysrc(yzdata(src, sr, srcy), needbuf),			yzdata(mask, mr, masky),			op);		dsty += dir;		srcy += dir;		masky += dir;	} 	dst.putrect(dst.data, dst.r.min);}