⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draw.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	dy = Dy(r);	z = allocdbuf();	if(z == nil)		return 0;	src = par->src;	mask = par->mask;		dst = par->dst;	sr = par->sr;	mr = par->mr;	op = par->op;	isgrey = dst->flags&Fgrey;	/*	 * Buffering when src and dst are the same bitmap is sufficient but not 	 * necessary.  There are stronger conditions we could use.  We could	 * check to see if the rectangles intersect, and if simply moving in the	 * correct y direction can avoid the need to buffer.	 */	needbuf = (src->data == dst->data);	ndrawbuf = 0;	getparam(&z->spar, src, sr, isgrey, needbuf, &ndrawbuf);	getparam(&z->dpar, dst, r, isgrey, needbuf, &ndrawbuf);	getparam(&z->mpar, mask, mr, 0, needbuf, &ndrawbuf);	dir = (needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min)) ? -1 : 1;	z->spar.dir = z->mpar.dir = z->dpar.dir = dir;	/*	 * If the mask is purely boolean, we can convert from src to dst format	 * when we read src, and then just copy it to dst where the mask tells us to.	 * This requires a boolean (1-bit grey) mask and lack of a source alpha channel.	 *	 * The computation is accomplished by assigning the function pointers as follows:	 *	rdsrc - read and convert source into dst format in a buffer	 * 	rdmask - convert mask to bytes, set pointer to it	 * 	rddst - fill with pointer to real dst data, but do no reads	 *	calc - copy src onto dst when mask says to.	 *	wrdst - do nothing	 * This is slightly sleazy, since things aren't doing exactly what their names say,	 * but it avoids a fair amount of code duplication to make this a case here	 * rather than have a separate booldraw.	 *///if(drawdebug) iprint("flag %lud mchan %lux=?%x dd %d\n", src->flags&Falpha, mask->chan, GREY1, dst->depth);	if(!(src->flags&Falpha) && mask->chan == GREY1 && dst->depth >= 8 && op == SoverD){//if(drawdebug) iprint("boolcopy...");		rdsrc = convfn(dst, &z->dpar, src, &z->spar, &ndrawbuf);		rddst = readptr;		rdmask = readfn(mask);		calc = boolcopyfn(dst, mask);		wrdst = nullwrite;	}else{		/* usual alphadraw parameter fetching */		rdsrc = readfn(src);		rddst = readfn(dst);		wrdst = writefn(dst);		calc = alphacalc[op];		/*		 * If there is no alpha channel, we'll ask for a grey channel		 * and pretend it is the alpha.		 */		if(mask->flags&Falpha){			rdmask = readalphafn(mask);			z->mpar.alphaonly = 1;		}else{			z->mpar.greymaskcall = readfn(mask);			z->mpar.convgrey = 1;			rdmask = greymaskread;			/*			 * Should really be above, but then boolcopyfns would have			 * to deal with bit alignment, and I haven't written that.			 *			 * This is a common case for things like ellipse drawing.			 * When there's no alpha involved and the mask is boolean,			 * we can avoid all the division and multiplication.			 */			if(mask->chan == GREY1 && !(src->flags&Falpha))				calc = boolcalc[op];			else if(op == SoverD && !(src->flags&Falpha))				calc = alphacalcS;		}	}	/*	 * If the image has a small enough repl rectangle,	 * we can just read each line once and cache them.	 */	if(z->spar.replcache){		z->spar.replcall = rdsrc;		rdsrc = replread;	}	if(z->mpar.replcache){		z->mpar.replcall = rdmask;		rdmask = replread;	}	if(z->n < ndrawbuf){		free(z->p);		if((z->p = mallocz(ndrawbuf, 0)) == nil){			z->inuse = 0;			return 0;		}		z->n = ndrawbuf;	}	drawbuf = z->p;	/*	 * Before we were saving only offsets from drawbuf in the parameter	 * structures; now that drawbuf has been grown to accomodate us,	 * we can fill in the pointers.	 */	z->spar.bufbase = drawbuf+z->spar.bufoff;	z->mpar.bufbase = drawbuf+z->mpar.bufoff;	z->dpar.bufbase = drawbuf+z->dpar.bufoff;	z->spar.convbuf = drawbuf+z->spar.convbufoff;	if(dir == 1){		starty = 0;		endy = dy;	}else{		starty = dy-1;		endy = -1;	}	/*	 * srcy, masky, and dsty are offsets from the top of their	 * respective Rectangles.  they need to be contained within	 * the rectangles, so clipy can keep them there without division. 	 */	srcy = (starty + sr.min.y - src->r.min.y)%Dy(src->r);	masky = (starty + mr.min.y - mask->r.min.y)%Dy(mask->r);	dsty = starty + r.min.y - dst->r.min.y;	assert(0 <= srcy && srcy < Dy(src->r));	assert(0 <= masky && masky < Dy(mask->r));	assert(0 <= dsty && dsty < Dy(dst->r));	for(y=starty; y!=endy; y+=dir, srcy+=dir, masky+=dir, dsty+=dir){		clipy(src, &srcy);		clipy(dst, &dsty);		clipy(mask, &masky);		bsrc = rdsrc(&z->spar, z->spar.bufbase, srcy);DBG print("[");		bmask = rdmask(&z->mpar, z->mpar.bufbase, masky);DBG print("]\n");		bdst = rddst(&z->dpar, z->dpar.bufbase, dsty);DBG		dumpbuf("src", bsrc, dx);DBG		dumpbuf("mask", bmask, dx);DBG		dumpbuf("dst", bdst, dx);		bdst = calc(bdst, bsrc, bmask, dx, isgrey, op);		wrdst(&z->dpar, z->dpar.bytermin+dsty*z->dpar.bwidth, bdst);	}	z->inuse = 0;	return 1;}#undef DBGstatic Bufferalphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op){	USED(grey);	USED(op);	USED(b1);	USED(b2);	memset(bdst.rgba, 0, dx*bdst.delta);	return bdst;}static Bufferalphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fd, sadelta;	int i, sa, ma, q;	ulong s, t;	obdst = bdst;	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;	q = bsrc.delta == 4 && bdst.delta == 4;	for(i=0; i<dx; i++){		sa = *bsrc.alpha;		ma = *bmask.alpha;		fd = MUL(sa, ma, t);		if(op == DoutS)			fd = 255-fd;		if(grey){			*bdst.grey = MUL(fd, *bdst.grey, t);			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(q){				*bdst.rgba = MUL0123(fd, *bdst.rgba, s, t);				bsrc.rgba++;				bdst.rgba++;				bsrc.alpha += sadelta;				bmask.alpha += bmask.delta;				continue;			}			*bdst.red = MUL(fd, *bdst.red, t);			*bdst.grn = MUL(fd, *bdst.grn, t);			*bdst.blu = MUL(fd, *bdst.blu, t);			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = MUL(fd, *bdst.alpha, t);			bdst.alpha += bdst.delta;		}		bmask.alpha += bmask.delta;		bsrc.alpha += sadelta;	}	return obdst;}static Bufferalphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fs, sadelta;	int i, ma, da, q;	ulong s, t;	obdst = bdst;	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;	q = bsrc.delta == 4 && bdst.delta == 4;	for(i=0; i<dx; i++){		ma = *bmask.alpha;		da = *bdst.alpha;		if(op == SoutD)			da = 255-da;		fs = ma;		if(op != S)			fs = MUL(fs, da, t);		if(grey){			*bdst.grey = MUL(fs, *bsrc.grey, t);			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(q){				*bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t);				bsrc.rgba++;				bdst.rgba++;				bmask.alpha += bmask.delta;				bdst.alpha += bdst.delta;				continue;			}			*bdst.red = MUL(fs, *bsrc.red, t);			*bdst.grn = MUL(fs, *bsrc.grn, t);			*bdst.blu = MUL(fs, *bsrc.blu, t);			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = MUL(fs, *bsrc.alpha, t);			bdst.alpha += bdst.delta;		}		bmask.alpha += bmask.delta;		bsrc.alpha += sadelta;	}	return obdst;}static Bufferalphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fs, fd, sadelta;	int i, sa, ma, da, q;	ulong s, t, u, v;	obdst = bdst;	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;	q = bsrc.delta == 4 && bdst.delta == 4;	for(i=0; i<dx; i++){		sa = *bsrc.alpha;		ma = *bmask.alpha;		da = *bdst.alpha;		if(op == SatopD)			fs = MUL(ma, da, t);		else			fs = MUL(ma, 255-da, t);		if(op == DoverS)			fd = 255;		else{			fd = MUL(sa, ma, t);			if(op != DatopS)				fd = 255-fd;		}		if(grey){			*bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(q){				*bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);				bsrc.rgba++;				bdst.rgba++;				bsrc.alpha += sadelta;				bmask.alpha += bmask.delta;				bdst.alpha += bdst.delta;				continue;			}			*bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);			*bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);			*bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = MUL(fs, sa, s)+MUL(fd, da, t);			bdst.alpha += bdst.delta;		}		bmask.alpha += bmask.delta;		bsrc.alpha += sadelta;	}	return obdst;}static Bufferalphacalc5(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op){	USED(dx);	USED(grey);	USED(op);	USED(b1);	USED(b2);	return bdst;}static Bufferalphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fd, sadelta;	int i, sa, ma, q;	ulong s, t, u, v;	USED(op);	obdst = bdst;	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;	q = bsrc.delta == 4 && bdst.delta == 4;	for(i=0; i<dx; i++){		sa = *bsrc.alpha;		ma = *bmask.alpha;		fd = 255-MUL(sa, ma, t);		if(grey){			*bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(q){				*bdst.rgba = MUL0123(ma, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);				bsrc.rgba++;				bdst.rgba++;				bsrc.alpha += sadelta;				bmask.alpha += bmask.delta;				continue;			}			*bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);			*bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);			*bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = MUL(ma, sa, s)+MUL(fd, *bdst.alpha, t);			bdst.alpha += bdst.delta;		}		bmask.alpha += bmask.delta;		bsrc.alpha += sadelta;	}	return obdst;}/*not used yetsource and mask alpha 1static BufferalphacalcS0(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int i;	USED(op);	obdst = bdst;	if(bsrc.delta == bdst.delta){		memmove(bdst.rgba, bsrc.rgba, dx*bdst.delta);		return obdst;	}	for(i=0; i<dx; i++){		if(grey){			*bdst.grey = *bsrc.grey;			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			*bdst.red = *bsrc.red;			*bdst.grn = *bsrc.grn;			*bdst.blu = *bsrc.blu;			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = 255;			bdst.alpha += bdst.delta;		}	}	return obdst;}*//* source alpha 1 */static BufferalphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fd;	int i, ma;	ulong s, t;	USED(op);	obdst = bdst;	for(i=0; i<dx; i++){		ma = *bmask.alpha;		fd = 255-ma;		if(grey){			*bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			*bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);			*bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);			*bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		if(bdst.alpha != &ones){			*bdst.alpha = ma+MUL(fd, *bdst.alpha, t);			bdst.alpha += bdst.delta;		}		bmask.alpha += bmask.delta;	}	return obdst;}static Bufferboolcalc14(Buffer bdst, Buffer b1, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int i, ma, zero;	USED(b1);	obdst = bdst;	for(i=0; i<dx; i++){		ma = *bmask.alpha;		zero = ma ? op == DoutS : op == DinS;		if(grey){			if(zero)				*bdst.grey = 0;			bdst.grey += bdst.delta;		}else{			if(zero)				*bdst.red = *bdst.grn = *bdst.blu = 0;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		bmask.alpha += bmask.delta;		if(bdst.alpha != &ones){			if(zero)				*bdst.alpha = 0;			bdst.alpha += bdst.delta;		}	}	return obdst;}static Bufferboolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int fs, fd;	int i, ma, da, zero;	ulong s, t;	obdst = bdst;	zero = !(op&1);	for(i=0; i<dx; i++){		ma = *bmask.alpha;		da = *bdst.alpha;		fs = da;		if(op&2)			fs = 255-da;		fd = 0;		if(op&4)			fd = 255;		if(grey){			if(ma)				*bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);			else if(zero)				*bdst.grey = 0;			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(ma){				*bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);				*bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);				*bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);			}			else if(zero)				*bdst.red = *bdst.grn = *bdst.blu = 0;			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		bmask.alpha += bmask.delta;		if(bdst.alpha != &ones){			if(ma)				*bdst.alpha = fs+MUL(fd, da, t);			else if(zero)				*bdst.alpha = 0;			bdst.alpha += bdst.delta;		}	}	return obdst;}static Bufferboolcalc1011(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op){	Buffer obdst;	int i, ma, zero;	obdst = bdst;	zero = !(op&1);	for(i=0; i<dx; i++){		ma = *bmask.alpha;		if(grey){			if(ma)				*bdst.grey = *bsrc.grey;			else if(zero)				*bdst.grey = 0;			bsrc.grey += bsrc.delta;			bdst.grey += bdst.delta;		}else{			if(ma){				*bdst.red = *bsrc.red;				*bdst.grn = *bsrc.grn;				*bdst.blu = *bsrc.blu;			}			else if(zero)				*bdst.red = *bdst.grn = *bdst.blu = 0;			bsrc.red += bsrc.delta;			bsrc.blu += bsrc.delta;			bsrc.grn += bsrc.delta;			bdst.red += bdst.delta;			bdst.blu += bdst.delta;			bdst.grn += bdst.delta;		}		bmask.alpha += bmask.delta;		if(bdst.alpha != &ones){			if(ma)				*bdst.alpha = 255;			else if(zero)				*bdst.alpha = 0;			bdst.alpha += bdst.delta;		}	}	return obdst;}/* * Replicated cached scan line read.  Call the function listed in the Param, * but cache the result so that for replicated images we only do the work once. */static Bufferreplread(Param *p, uchar *s, int y){	Buffer *b;	USED(s);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -