/* 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);}
/* 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);
}