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

📄 fblin32alpha.c

📁 the embedded GUI for SamSung s3c2410 cpu based board.is microwindows0.90
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 32bpp (With Alpha) Linear Video Driver for Microwindows * * Written by Koninklijke Philips Electronics N.V. * Based on the existing 32bpp (no alpha) driver: * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com> * Inspired from Ben Pfaff's BOGL <pfaffben@debian.org> * * Portions contributed by Koninklijke Philips Electronics N.V. * These portions are Copyright 2002, 2003 Koninklijke Philips Electronics * N.V.  All Rights Reserved.  These portions are licensed under the * terms of the Mozilla Public License, version 1.1, or, at your * option, the GNU General Public License version 2.0.  Please see * the file "ChangeLog" for documentation regarding these * contributions. *//*#define NDEBUG*/#include <assert.h>#include <string.h>#include "device.h"#include "fb.h"typedef unsigned long MW_U32;typedef long MW_S32;/* It's a lot easier to treat the buffer as an array of bytes when * alpha blending, and an array of MW_U32 otherwise.  However, * without some care, that would not be portable due to endian * issues. * * These macros help solve this problem.  They define which bytes * in memory correspond to which field. */#if MW_CPU_BIG_ENDIAN#define MWI_BYTE_OFFSET_ALPHA 0#define MWI_BYTE_OFFSET_R 1#define MWI_BYTE_OFFSET_G 2#define MWI_BYTE_OFFSET_B 3#else#define MWI_BYTE_OFFSET_ALPHA 3#define MWI_BYTE_OFFSET_R 2#define MWI_BYTE_OFFSET_G 1#define MWI_BYTE_OFFSET_B 0#endif/* Calc linelen and mmap size, return 0 on fail*/static intlinear32a_init(PSD psd){#ifndef NDEBUG	/*	 * Check the endian mode of the CPU matches what was specified	 * in the config file at compile time.	 *	 * (Also validates that the various #defines are internally	 *  consistent).	 */	unsigned long endian_check = COLOR2PIXEL8888(MWARGB(1, 2, 3, 4));	assert(((char *) (&endian_check))[MWI_BYTE_OFFSET_ALPHA] == 1);	assert(((char *) (&endian_check))[MWI_BYTE_OFFSET_R] == 2);	assert(((char *) (&endian_check))[MWI_BYTE_OFFSET_G] == 3);	assert(((char *) (&endian_check))[MWI_BYTE_OFFSET_B] == 4);#endif	if (!psd->size) {		psd->size = psd->yres * psd->linelen;		/* convert linelen from byte to pixel len for bpp 16, 24, 32 */		psd->linelen /= 4;	}	return 1;}/* * For alpha blending, we use 2 different 'alpha' values: * * psa = specified alpha. 0 <= psa <= 255 * * psa_inv = 256 - psa * This flips the direction of alpha, so it's * backwards from it's usual meaning. * This is because some of the equations below are most * easily written with source and dest interchanged * (since we can split the source color into it's * components beforehand) *//* Set pixel at x, y, to pixelval c*/static voidlinear32a_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c){	ADDR32 addr = psd->addr;	assert(addr != 0);	assert(x >= 0 && x < psd->xres);	assert(y >= 0 && y < psd->yres);	addr += x + y * psd->linelen;	DRAWON;	if (gr_mode == MWMODE_COPY) {		*addr = c;	} else if (gr_mode <= MWMODE_SIMPLE_MAX) {		applyOp(gr_mode, c, addr, ADDR32);	} else {		MW_S32 psr, psg, psb;		MW_S32 psa, psa_inv;		MW_U32 pd;		psa = (((MW_U32) c) >> 24);		switch (gr_mode) {		case MWMODE_SRC_OVER:			if (psa == 255) {				*addr = c;			} else if (psa != 0) {				psa_inv = 256 - psa;				psr = (MW_S32) (c & 0x00FF0000UL);				psg = (MW_S32) (c & 0x0000FF00UL);				psb = (MW_S32) (c & 0x000000FFUL);				pd = *addr;				*addr = ((MW_U32)					 (((((MW_S32) (pd & 0x00FF0000UL) -					     psr) * psa_inv) >> 8) +					  psr) & 0x00FF0000UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x0000FF00UL) -					       psg) * psa_inv) >> 8) +					    psg) & 0x0000FF00UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x000000FFUL) -					       psb) * psa_inv) >> 8) +					    psb) & 0x000000FFUL)					|					(((psa << 24) +					  ((pd & 0xFF000000UL) >> 8) *					  (MW_U32) psa_inv) & 0xFF000000UL);			}			break;		case MWMODE_SRC_IN:		case MWMODE_SRC_ATOP:		case MWMODE_DST_OVER:		case MWMODE_DST_IN:		case MWMODE_DST_ATOP:		case MWMODE_SRC_OUT:		case MWMODE_DST_OUT:		case MWMODE_PORTERDUFF_XOR:			/* FIXME!!! */			break;		default:			assert(0);		}	}	DRAWOFF;}/* Read pixel at x, y*/static MWPIXELVALlinear32a_readpixel(PSD psd, MWCOORD x, MWCOORD y){	ADDR32 addr = psd->addr;	assert(addr != 0);	assert(x >= 0 && x < psd->xres);	assert(y >= 0 && y < psd->yres);	return addr[x + y * psd->linelen];}/* Draw horizontal line from x1,y to x2,y including final point*/static voidlinear32a_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y,		       MWPIXELVAL c){	ADDR32 addr = psd->addr;	assert(addr != 0);	assert(x1 >= 0 && x1 < psd->xres);	assert(x2 >= 0 && x2 < psd->xres);	assert(x2 >= x1);	assert(y >= 0 && y < psd->yres);	addr += x1 + y * psd->linelen;	DRAWON;	if (gr_mode == MWMODE_COPY) {		/* FIXME: memsetl(dst, c, x2-x1+1) */		while (x1++ <= x2)			*addr++ = c;	} else if (gr_mode <= MWMODE_SIMPLE_MAX) {		while (x1++ <= x2) {			applyOp(gr_mode, c, addr, ADDR32);			++addr;		}	} else {		MW_S32 psr, psg, psb;		MW_S32 psa, psa_inv;		MW_U32 pd;		MW_U32 cache_input, cache_output;		psa = (((MW_U32) c) >> 24);		switch (gr_mode) {		case MWMODE_SRC_OVER:			if (psa == 255) {				while (x1++ <= x2)					*addr++ = c;			} else if (psa != 0) {				psa_inv = 256 - psa;				psr = (MW_S32) (c & 0x00FF0000UL);				psg = (MW_S32) (c & 0x0000FF00UL);				psb = (MW_S32) (c & 0x000000FFUL);				pd = *addr;				cache_input = pd;				cache_output = ((MW_U32)						(((((MW_S32)						    (pd & 0x00FF0000UL) -						    psr) * psa_inv) >> 8) +						 psr) & 0x00FF0000UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x0000FF00UL) -					       psg) * psa_inv) >> 8) +					    psg) & 0x0000FF00UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x000000FFUL) -					       psb) * psa_inv) >> 8) +					    psb) & 0x000000FFUL)					|					(((psa << 24) +					  ((pd & 0xFF000000UL) >> 8) *					  ((MW_U32) psa_inv)) & 0xFF000000UL);				*addr++ = cache_output;				while (++x1 <= x2) {					pd = *addr;					if (cache_input != pd) {						cache_input = pd;						cache_output = ((MW_U32)								(((((MW_S32)								    (pd &								     0x00FF0000UL)								    -								    psr) *								   psa_inv) >>								  8) +								 psr) &								0x00FF0000UL)							| ((MW_U32)							   (((((MW_S32)							       (pd &								0x0000FF00UL)							       -							       psg) *							      psa_inv) >> 8) +							    psg) &							   0x0000FF00UL)							| ((MW_U32)							   (((((MW_S32)							       (pd &								0x000000FFUL)							       -							       psb) *							      psa_inv) >> 8) +							    psb) &							   0x000000FFUL)							|							(((psa << 24) +							  ((pd & 0xFF000000UL)							   >> 8) *							  ((MW_U32) psa_inv))							 & 0xFF000000UL);					}					*addr++ = cache_output;				}			}			break;		case MWMODE_SRC_IN:		case MWMODE_SRC_ATOP:		case MWMODE_DST_OVER:		case MWMODE_DST_IN:		case MWMODE_DST_ATOP:		case MWMODE_SRC_OUT:		case MWMODE_DST_OUT:		case MWMODE_PORTERDUFF_XOR:			/* FIXME!!! */			break;		default:			assert(0);		}	}	DRAWOFF;}/* Draw a vertical line from x,y1 to x,y2 including final point*/static voidlinear32a_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2,		       MWPIXELVAL c){	ADDR32 addr = psd->addr;	int linelen = psd->linelen;	assert(addr != 0);	assert(x >= 0 && x < psd->xres);	assert(y1 >= 0 && y1 < psd->yres);	assert(y2 >= 0 && y2 < psd->yres);	assert(y2 >= y1);	DRAWON;	addr += x + y1 * linelen;	if (gr_mode == MWMODE_COPY) {		while (y1++ <= y2) {			*addr = c;			addr += linelen;		}	} else if (gr_mode <= MWMODE_SIMPLE_MAX) {		while (y1++ <= y2) {			applyOp(gr_mode, c, addr, ADDR32);			addr += linelen;		}	} else {		MW_S32 psr, psg, psb;		MW_S32 psa, psa_inv;		MW_U32 pd;		MW_U32 cache_input, cache_output;		psa = (((MW_U32) c) >> 24);		switch (gr_mode) {		case MWMODE_SRC_OVER:			if (psa == 255) {				while (y1++ <= y2) {					*addr = c;					addr += linelen;				}			} else if (psa != 0) {				psa_inv = 256 - psa;				psr = (MW_S32) (c & 0x00FF0000UL);				psg = (MW_S32) (c & 0x0000FF00UL);				psb = (MW_S32) (c & 0x000000FFUL);				pd = *addr;				cache_input = pd;				cache_output = ((MW_U32)						(((((MW_S32)						    (pd & 0x00FF0000UL) -						    psr) * psa_inv) >> 8) +						 psr) & 0x00FF0000UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x0000FF00UL) -					       psg) * psa_inv) >> 8) +					    psg) & 0x0000FF00UL)					| ((MW_U32)					   (((((MW_S32) (pd & 0x000000FFUL) -					       psb) * psa_inv) >> 8) +					    psb) & 0x000000FFUL)					|					(((psa << 24) +					  ((pd & 0xFF000000UL) >> 8) *					  ((MW_U32) psa_inv)) & 0xFF000000UL);				*addr = cache_output;				addr += linelen;				while (++y1 <= y2) {					pd = *addr;					if (cache_input != pd) {						cache_input = pd;						cache_output = ((MW_U32)								(((((MW_S32)								    (pd &								     0x00FF0000UL)								    -								    psr) *								   psa_inv) >>								  8) +								 psr) &								0x00FF0000UL)							| ((MW_U32)							   (((((MW_S32)							       (pd &								0x0000FF00UL)							       -							       psg) *							      psa_inv) >> 8) +							    psg) &							   0x0000FF00UL)							| ((MW_U32)							   (((((MW_S32)							       (pd &								0x000000FFUL)							       -							       psb) *							      psa_inv) >> 8) +							    psb) &							   0x000000FFUL)							|							(((psa << 24) +							  ((pd & 0xFF000000UL)							   >> 8) *							  ((MW_U32) psa_inv))							 & 0xFF000000UL);					}					*addr = cache_output;					addr += linelen;				}			}			break;		case MWMODE_SRC_IN:		case MWMODE_SRC_ATOP:		case MWMODE_DST_OVER:		case MWMODE_DST_IN:		case MWMODE_DST_ATOP:		case MWMODE_SRC_OUT:		case MWMODE_DST_OUT:		case MWMODE_PORTERDUFF_XOR:			/* FIXME!!! */			break;		default:			assert(0);		}	}	DRAWOFF;}/* srccopy bitblt*/static voidlinear32a_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,	       PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op){	ADDR8 dst8, src8;	ADDR32 dst = dstpsd->addr;	ADDR32 src = srcpsd->addr;	int i;	int dlinelen = dstpsd->linelen;	int slinelen = srcpsd->linelen;	int dlinelen_minus_w4;	int slinelen_minus_w4;#if ALPHABLEND	unsigned int alpha;#endif	assert(dst != 0);	assert(dstx >= 0 && dstx < dstpsd->xres);	assert(dsty >= 0 && dsty < dstpsd->yres);	assert(w > 0);	assert(h > 0);	assert(src != 0);	assert(srcx >= 0 && srcx < srcpsd->xres);	assert(srcy >= 0 && srcy < srcpsd->yres);	assert(dstx + w <= dstpsd->xres);	assert(dsty + h <= dstpsd->yres);	assert(srcx + w <= srcpsd->xres);	assert(srcy + h <= srcpsd->yres);	DRAWON;	dst += dstx + dsty * dlinelen;	src += srcx + srcy * slinelen;#if ALPHABLEND	if ((op & MWROP_EXTENSION) != MWROP_BLENDCONSTANT)		goto stdblit;	alpha = op & 0xff;	src8 = (ADDR8) src;	dst8 = (ADDR8) dst;	dlinelen_minus_w4 = (dlinelen - w) * 4;	slinelen_minus_w4 = (slinelen - w) * 4;	while (--h >= 0) {		for (i = 0; i < w; ++i) {			register unsigned long s;			register unsigned long d;			s = src8[MWI_BYTE_OFFSET_R];			d = dst8[MWI_BYTE_OFFSET_R];			dst8[MWI_BYTE_OFFSET_R] =				(unsigned char) (((s - d) * alpha) >> 8) + d;			s = src8[MWI_BYTE_OFFSET_G];			d = dst8[MWI_BYTE_OFFSET_G];			dst8[MWI_BYTE_OFFSET_G] =				(unsigned char) (((s - d) * alpha) >> 8) + d;			s = src8[MWI_BYTE_OFFSET_B];			d = dst8[MWI_BYTE_OFFSET_B];			dst8[MWI_BYTE_OFFSET_B] =				(unsigned char) (((s - d) * alpha) >> 8) + d;			s = src8[MWI_BYTE_OFFSET_ALPHA];			d = dst8[MWI_BYTE_OFFSET_ALPHA];			dst8[MWI_BYTE_OFFSET_ALPHA] =				(unsigned char) (((s - d) * alpha) >> 8) + d;			dst8 += 4;			src8 += 4;		}		dst8 += dlinelen_minus_w4;		src8 += slinelen_minus_w4;	}	DRAWOFF;	return;      stdblit:#endif	if (op == MWROP_COPY) {		/* copy from bottom up if dst in src rectangle */		/* memmove is used to handle x case */		if (srcy < dsty) {			src += (h - 1) * slinelen;			dst += (h - 1) * dlinelen;			slinelen *= -1;			dlinelen *= -1;		}		while (--h >= 0) {			/* a _fast_ memmove is a _must_ in this routine */			memmove(dst, src, w << 2);			dst += dlinelen;			src += slinelen;		}	} else if (MWROP_TO_MODE(op) <= MWMODE_SIMPLE_MAX) {		for (i = 0; i < w; ++i) {			applyOp(MWROP_TO_MODE(op), *src, dst, ADDR32);			++src;			++dst;		}		dst += dlinelen - w;		src += slinelen - w;	} else if (MWROP_TO_MODE(op) == MWMODE_SRC_OVER) {		src8 = (ADDR8) src;		dst8 = (ADDR8) dst;		while (h--) {			for (i = w; --i >= 0;) {				register int a;				register int s;

⌨️ 快捷键说明

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