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

📄 draw.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
	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;}#define DBG if(0)static Bufferreadnbit(Param *p, uchar *buf, int y){	Buffer b;	Memimage *img;	uchar *repl, *r, *w, *ow, bits;	int i, n, sh, depth, x, dx, npack, nbits;	b.rgba = (ulong*)buf;	b.grey = w = buf;	b.red = b.blu = b.grn = w;	b.alpha = &ones;	b.delta = 1;	dx = p->dx;	img = p->img;	depth = img->depth;	repl = &replbit[depth][0];	npack = 8/depth;	sh = 8-depth;	/* copy from p->r.min.x until end of repl rectangle */	x = p->r.min.x;	n = dx;	if(n > p->img->r.max.x - x)		n = p->img->r.max.x - x;	r = p->bytermin + y*p->bwidth;DBG print("readnbit dx %d %p=%p+%d*%d, *r=%d fetch %d ", dx, r, p->bytermin, y, p->bwidth, *r, n);	bits = *r++;	nbits = 8;	if(i=x&(npack-1)){DBG print("throwaway %d...", i);		bits <<= depth*i;		nbits -= depth*i;	}	for(i=0; i<n; i++){		if(nbits == 0){DBG print("(%.2ux)...", *r);			bits = *r++;			nbits = 8;		}		*w++ = repl[bits>>sh];DBG print("bit %x...", repl[bits>>sh]);		bits <<= depth;		nbits -= depth;	}	dx -= n;	if(dx == 0)		return b;	assert(x+i == p->img->r.max.x);	/* copy from beginning of repl rectangle until where we were before. */	x = p->img->r.min.x;	n = dx;	if(n > p->r.min.x - x)		n = p->r.min.x - x;	r = p->bytey0s + y*p->bwidth;DBG print("x=%d r=%p...", x, r);	bits = *r++;	nbits = 8;	if(i=x&(npack-1)){		bits <<= depth*i;		nbits -= depth*i;	}DBG print("nbits=%d...", nbits);	for(i=0; i<n; i++){		if(nbits == 0){			bits = *r++;			nbits = 8;		}		*w++ = repl[bits>>sh];DBG print("bit %x...", repl[bits>>sh]);		bits <<= depth;		nbits -= depth;DBG print("bits %x nbits %d...", bits, nbits);	}	dx -= n;	if(dx == 0)		return b;	assert(dx > 0);	/* now we have exactly one full scan line: just replicate the buffer itself until we are done */	ow = buf;	while(dx--)		*w++ = *ow++;	return b;}#undef DBG#define DBG if(0)static voidwritenbit(Param *p, uchar *w, Buffer src){	uchar *r;	ulong bits;	int i, sh, depth, npack, nbits, x, ex;	assert(src.grey != nil && src.delta == 1);	x = p->r.min.x;	ex = x+p->dx;	depth = p->img->depth;	npack = 8/depth;	i=x&(npack-1);	bits = i ? (*w >> (8-depth*i)) : 0;	nbits = depth*i;	sh = 8-depth;	r = src.grey;	for(; x<ex; x++){		bits <<= depth;DBG print(" %x", *r);		bits |= (*r++ >> sh);		nbits += depth;		if(nbits == 8){			*w++ = bits;			nbits = 0;		}	}	if(nbits){		sh = 8-nbits;		bits <<= sh;		bits |= *w & ((1<<sh)-1);		*w = bits;	}DBG print("\n");	return;}#undef DBGstatic Bufferreadcmap(Param *p, uchar *buf, int y){	Buffer b;	int a, convgrey, copyalpha, dx, i, m;	uchar *q, *cmap, *begin, *end, *r, *w;	begin = p->bytey0s + y*p->bwidth;	r = p->bytermin + y*p->bwidth;	end = p->bytey0e + y*p->bwidth;	cmap = p->img->cmap->cmap2rgb;	convgrey = p->convgrey;	copyalpha = (p->img->flags&Falpha) ? 1 : 0;	w = buf;	dx = p->dx;	if(copyalpha){		b.alpha = buf++;		a = p->img->shift[CAlpha]/8;		m = p->img->shift[CMap]/8;		for(i=0; i<dx; i++){			*w++ = r[a];			q = cmap+r[m]*3;			r += 2;			if(r == end)				r = begin;			if(convgrey){				*w++ = RGB2K(q[0], q[1], q[2]);			}else{				*w++ = q[2];	/* blue */				*w++ = q[1];	/* green */				*w++ = q[0];	/* red */			}		}	}else{		b.alpha = &ones;		for(i=0; i<dx; i++){			q = cmap+*r++*3;			if(r == end)				r = begin;			if(convgrey){				*w++ = RGB2K(q[0], q[1], q[2]);			}else{				*w++ = q[2];	/* blue */				*w++ = q[1];	/* green */				*w++ = q[0];	/* red */			}		}	}	b.rgba = (ulong*)(buf-copyalpha);	if(convgrey){		b.grey = buf;		b.red = b.blu = b.grn = buf;		b.delta = 1+copyalpha;	}else{		b.blu = buf;		b.grn = buf+1;		b.red = buf+2;		b.grey = nil;		b.delta = 3+copyalpha;	}	return b;}static voidwritecmap(Param *p, uchar *w, Buffer src){	uchar *cmap, *red, *grn, *blu;	int i, dx, delta;	cmap = p->img->cmap->rgb2cmap;		delta = src.delta;	red= src.red;	grn = src.grn;	blu = src.blu;	dx = p->dx;	for(i=0; i<dx; i++, red+=delta, grn+=delta, blu+=delta)		*w++ = cmap[(*red>>4)*256+(*grn>>4)*16+(*blu>>4)];}#define DBG if(0)static Bufferreadbyte(Param *p, uchar *buf, int y){	Buffer b;	Memimage *img;	int dx, isgrey, convgrey, alphaonly, copyalpha, i, nb;	uchar *begin, *end, *r, *w, *rrepl, *grepl, *brepl, *arepl, *krepl;	uchar ured, ugrn, ublu;	ulong u;	img = p->img;	begin = p->bytey0s + y*p->bwidth;	r = p->bytermin + y*p->bwidth;	end = p->bytey0e + y*p->bwidth;	w = buf;	dx = p->dx;	nb = img->depth/8;	convgrey = p->convgrey;	/* convert rgb to grey */	isgrey = img->flags&Fgrey;	alphaonly = p->alphaonly;	copyalpha = (img->flags&Falpha) ? 1 : 0;DBG print("copyalpha %d alphaonly %d convgrey %d isgrey %d\n", copyalpha, alphaonly, convgrey, isgrey);	/* if we can, avoid processing everything */	if(!(img->flags&Frepl) && !convgrey && (img->flags&Fbytes)){		memset(&b, 0, sizeof b);		if(p->needbuf){			memmove(buf, r, dx*nb);			r = buf;		}		b.rgba = (ulong*)r;		if(copyalpha)			b.alpha = r+img->shift[CAlpha]/8;		else			b.alpha = &ones;		if(isgrey){			b.grey = r+img->shift[CGrey]/8;			b.red = b.grn = b.blu = b.grey;		}else{			b.red = r+img->shift[CRed]/8;			b.grn = r+img->shift[CGreen]/8;			b.blu = r+img->shift[CBlue]/8;		}		b.delta = nb;		return b;	}DBG print("2\n");	rrepl = replbit[img->nbits[CRed]];	grepl = replbit[img->nbits[CGreen]];	brepl = replbit[img->nbits[CBlue]];	arepl = replbit[img->nbits[CAlpha]];	krepl = replbit[img->nbits[CGrey]];	for(i=0; i<dx; i++){		u = r[0] | (r[1]<<8) | (r[2]<<16) | (r[3]<<24);		if(copyalpha) {			*w++ = arepl[(u>>img->shift[CAlpha]) & img->mask[CAlpha]];DBG print("a %x\n", w[-1]);		}		if(isgrey)			*w++ = krepl[(u >> img->shift[CGrey]) & img->mask[CGrey]];		else if(!alphaonly){			ured = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]];			ugrn = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]];			ublu = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]];			if(convgrey){DBG print("g %x %x %x\n", ured, ugrn, ublu);				*w++ = RGB2K(ured, ugrn, ublu);DBG print("%x\n", w[-1]);			}else{				*w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]];				*w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]];				*w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]];			}		}		r += nb;		if(r == end)			r = begin;	}		b.alpha = copyalpha ? buf : &ones;	b.rgba = (ulong*)buf;	if(alphaonly){		b.red = b.grn = b.blu = b.grey = nil;		if(!copyalpha)			b.rgba = nil;		b.delta = 1;	}else if(isgrey || convgrey){		b.grey = buf+copyalpha;		b.red = b.grn = b.blu = buf+copyalpha;		b.delta = copyalpha+1;DBG print("alpha %x grey %x\n", b.alpha ? *b.alpha : 0xFF, *b.grey);	}else{		b.blu = buf+copyalpha;		b.grn = buf+copyalpha+1;		b.grey = nil;		b.red = buf+copyalpha+2;		b.delta = copyalpha+3;	}	return b;}#undef DBG#define DBG if(0)static voidwritebyte(Param *p, uchar *w, Buffer src){	Memimage *img;	int i, isalpha, isgrey, nb, delta, dx, adelta;	uchar ff, *red, *grn, *blu, *grey, *alpha;	ulong u, mask;	img = p->img;	red = src.red;	grn = src.grn;	blu = src.blu;	alpha = src.alpha;	delta = src.delta;	grey = src.grey;	dx = p->dx;	nb = img->depth/8;	mask = (nb==4) ? 0 : ~((1<<img->depth)-1);	isalpha = img->flags&Falpha;	isgrey = img->flags&Fgrey;	adelta = src.delta;	if(isalpha && (alpha == nil || alpha == &ones)){		ff = 0xFF;		alpha = &ff;		adelta = 0;	}	for(i=0; i<dx; i++){		u = w[0] | (w[1]<<8) | (w[2]<<16) | (w[3]<<24);DBG print("u %.8lux...", u);		u &= mask;DBG print("&mask %.8lux...", u);		if(isgrey){			u |= ((*grey >> (8-img->nbits[CGrey])) & img->mask[CGrey]) << img->shift[CGrey];DBG print("|grey %.8lux...", u);			grey += delta;		}else{			u |= ((*red >> (8-img->nbits[CRed])) & img->mask[CRed]) << img->shift[CRed];			u |= ((*grn >> (8-img->nbits[CGreen])) & img->mask[CGreen]) << img->shift[CGreen];			u |= ((*blu >> (8-img->nbits[CBlue])) & img->mask[CBlue]) << img->shift[CBlue];			red += delta;			grn += delta;			blu += delta;DBG print("|rgb %.8lux...", u);		}		if(isalpha){			u |= ((*alpha >> (8-img->nbits[CAlpha])) & img->mask[CAlpha]) << img->shift[CAlpha];			alpha += adelta;DBG print("|alpha %.8lux...", u);		}		w[0] = u;		w[1] = u>>8;		w[2] = u>>16;		w[3] = u>>24;		w += nb;	}}#undef DBGstatic Readfn*readfn(Memimage *img){	if(img->depth < 8)		return readnbit;	if(img->nbits[CMap] == 8)		return readcmap;	return readbyte;}static Readfn*readalphafn(Memimage *m){	USED(m);	return readbyte;}static Writefn*writefn(Memimage *img){	if(img->depth < 8)		return writenbit;	if(img->chan == CMAP8)		return writecmap;	return writebyte;}static voidnullwrite(Param *p, uchar *s, Buffer b){	USED(p);	USED(s);	USED(b);}static Bufferreadptr(Param *p, uchar *s, int y){	Buffer b;	uchar *q;	USED(s);	q = p->bytermin + y*p->bwidth;	b.red = q;	/* ptr to data */	b.grn = b.blu = b.grey = b.alpha = nil;	b.rgba = (ulong*)q;	b.delta = p->img->depth/8;	return b;}static Bufferboolmemmove(Buffer bdst, Buffer bsrc, Buffer b1, int dx, int i, int o){	USED(i);	USED(o);	USED(b1);	USED(bsrc);	memmove(bdst.red, bsrc.red, dx*bdst.delta);	return bdst;}static Bufferboolcopy8(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){	uchar *m, *r, *w, *ew;	USED(i);	USED(o);	m = bmask.grey;	w = bdst.red;	r = bsrc.red;	ew = w+dx;	for(; w < ew; w++,r++)		if(*m++)			*w = *r;	return bdst;	/* not used */}static Bufferboolcopy16(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){	uchar *m;	ushort *r, *w, *ew;	USED(i);	USED(o);	m = bmask.grey;	w = (ushort*)bdst.red;	r = (ushort*)bsrc.red;	ew = w+dx;	for(; w < ew; w++,r++)		if(*m++)			*w = *r;	return bdst;	/* not used */}static Bufferboolcopy24(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){	uchar *m;	uchar *r, *w, *ew;	USED(i);	USED(o);	m = bmask.grey;	w = bdst.red;	r = bsrc.red;	ew = w+dx*3;	while(w < ew){		if(*m++){			*w++ = *r++;			*w++ = *r++;			*w++ = *r++;		}else{			w += 3;			r += 3;		}	}	return bdst;	/* not used */}static Bufferboolcopy32(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){	uchar *m;	ulong *r, *w, *ew;	USED(i);	USED(o);	m = bmask.grey;	w = (ulong*)bdst.red;	r = (ulong*)bsrc.red;	ew = w+dx;	for(; w < ew; w++,r++)		if(*m++)			*w = *r;	return bdst;	/* not used */}static Buffergenconv(Param *p, uchar *buf, int y){	Buffer b;	int nb;	uchar *r, *w, *ew;	/* read from source into RGB format in convbuf */	b = p->convreadcall(p, p->convbuf, y);	/* write RGB format into dst format in buf */	p->convwritecall(p->convdpar, buf, b);	if(p->convdx){		nb = p->convdpar->img->depth/8;		r = buf;		w = buf+nb*p->dx;		ew = buf+nb*p->convdx;		while(w<ew)			*w++ = *r++;	}	b.red = buf;	b.blu = b.grn = b.grey = b.alpha = nil;	b.rgba = (ulong*)buf;	b.delta = 0;		return b;}static Readfn*convfn(Memimage *dst, Param *dpar, Memimage *src, Param *spar, int *ndrawbuf){	if(dst->chan == src->chan && !(src->flags&Frepl)){//if(drawdebug) iprint("readptr...");		return readptr;	}	if(dst->chan==CMAP8 && (src->chan==GREY1||src->chan==GREY2||src->chan==GREY4)){		/* cheat because we know the replicated value is exactly the color map entry. *///if(drawdebug) iprint("Readnbit...");		return readnbit;	}	spar->convreadcall = readfn(src);	spar->convwritecall = writefn(dst);	spar->convdpar = dpar;	/* allocate a conversion buffer */	spar->convbufoff = *ndrawbuf;	*ndrawbuf += spar->dx*4;	if(spar->dx > Dx(spar->img->r)){		spar->convdx = spar->dx;		spar->dx = Dx(spar->img->r);	}//if(drawdebug) iprint("genconv...");	return genconv;}static ulongpixelbits(Memimage *i, Point pt){	uchar *p;	ulong val;	int off, bpp, npack;	val = 0;	p = byteaddr(i, pt);	switch(bpp=i->depth){	case 1:	case 2:	case 4:		npack = 8/bpp;

⌨️ 快捷键说明

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