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

📄 draw.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	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);	spar = getparam(src, sr, isgrey, needbuf);	dpar = getparam(dst, r, isgrey, needbuf);	mpar = getparam(mask, mr, 0, needbuf);	dir = (needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min)) ? -1 : 1;	spar.dir = mpar.dir = 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, &dpar, src, &spar);		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);			mpar.alphaonly = 1;		}else{			mpar.greymaskcall = readfn(mask);			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(spar.replcache){		spar.replcall = rdsrc;		rdsrc = replread;	}	if(mpar.replcache){		mpar.replcall = rdmask;		rdmask = replread;	}	if(allocdrawbuf() < 0)		return 0;	/*	 * 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.	 */	spar.bufbase = drawbuf+spar.bufoff;	mpar.bufbase = drawbuf+mpar.bufoff;	dpar.bufbase = drawbuf+dpar.bufoff;	spar.convbuf = drawbuf+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(&spar, spar.bufbase, srcy);DBG print("[");		bmask = rdmask(&mpar, mpar.bufbase, masky);DBG print("]\n");		bdst = rddst(&dpar, 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(&dpar, dpar.bytermin+dsty*dpar.bwidth, bdst);	}	return 1;}#undef DBGstatic Bufferalphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op){	USED(grey);	USED(op);	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);	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;	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);	b = &p->bcache[y];	if((p->bfilled & (1<<y)) == 0){		p->bfilled |= 1<<y;		*b = p->replcall(p, p->bufbase+y*p->bufdelta, y);	}	return *b;}/* * Alpha reading function that simply relabels the grey pointer. */static Buffergreymaskread(Param *p, uchar *buf, int y){	Buffer b;	b = p->greymaskcall(p, buf, y);	b.alpha = b.grey;	return b;

⌨️ 快捷键说明

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