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

📄 fblin8.c

📁 the embedded GUI for SamSung s3c2410 cpu based board.is microwindows0.90
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1999, 2000, 2001, 2003 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V. * * 8bpp Linear Video Driver for Microwindows * 	00/01/26 added alpha blending with lookup tables (64k total) * * Inspired from Ben Pfaff's BOGL <pfaffben@debian.org> *//*#define NDEBUG*/#include <assert.h>/* We want to do string copying fast, so inline assembly if possible */#ifndef __OPTIMIZE__#define __OPTIMIZE__#endif#include <string.h>#include "device.h"#include "fb.h"#if ALPHABLEND/* * Alpha lookup tables for 256 color palette systems * A 5 bit alpha value is used to keep tables smaller. * * Two tables are created.  The first, alpha_to_rgb contains 15 bit RGB  * values for each alpha value for each color: 32*256 short words. * RGB values can then be blended.  The second, rgb_to_palindex contains * the closest color (palette index) for each of the 5-bit * R, G, and B values: 32*32*32 bytes. */static unsigned short *alpha_to_rgb = NULL;static unsigned char  *rgb_to_palindex = NULL;void init_alpha_lookup(void);#endif/* Calc linelen and mmap size, return 0 on fail*/static intlinear8_init(PSD psd){	if (!psd->size)		psd->size = psd->yres * psd->linelen;	/* linelen in bytes for bpp 1, 2, 4, 8 so no change*/	return 1;}/* Set pixel at x, y, to pixelval c*/static voidlinear8_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c){	ADDR8	addr = psd->addr;	assert (addr != 0);	assert (x >= 0 && x < psd->xres);	assert (y >= 0 && y < psd->yres);	assert (c < psd->ncolors);	DRAWON;	if(gr_mode == MWMODE_COPY)		addr[x + y * psd->linelen] = c;	else		applyOp(gr_mode, c, &addr[ x + y * psd->linelen], ADDR8);	DRAWOFF;}/* Read pixel at x, y*/static MWPIXELVALlinear8_readpixel(PSD psd, MWCOORD x, MWCOORD y){	ADDR8	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 voidlinear8_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c){	ADDR8	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);	assert (c < psd->ncolors);	DRAWON;	addr += x1 + y * psd->linelen;	if(gr_mode == MWMODE_COPY)		memset(addr, c, x2 - x1 + 1);	else {		while(x1++ <= x2) {			applyOp(gr_mode, c, addr, ADDR8);			++addr;		}	}	DRAWOFF;}/* Draw a vertical line from x,y1 to x,y2 including final point*/static voidlinear8_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c){	ADDR8	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);	assert (c < psd->ncolors);	DRAWON;	addr += x + y1 * linelen;	if(gr_mode == MWMODE_COPY) {		while(y1++ <= y2) {			*addr = c;			addr += linelen;		}	} else {		while(y1++ <= y2) {			applyOp(gr_mode, c, addr, ADDR8);			addr += linelen;		}	}	DRAWOFF;}/* srccopy bitblt*/static voidlinear8_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,	PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op){	ADDR8	dst;	ADDR8	src;	int	dlinelen = dstpsd->linelen;	int	slinelen = srcpsd->linelen;#if ALPHABLEND	unsigned int srcalpha, dstalpha;#endif	assert (dstpsd->addr != 0);	assert (dstx >= 0 && dstx < dstpsd->xres);	assert (dsty >= 0 && dsty < dstpsd->yres);	assert (w > 0);	assert (h > 0);	assert (srcpsd->addr != 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 = ((ADDR8)dstpsd->addr) + dstx + dsty * dlinelen;	src = ((ADDR8)srcpsd->addr) + srcx + srcy * slinelen;#if ALPHABLEND	if((op & MWROP_EXTENSION) != MWROP_BLENDCONSTANT)		goto stdblit;	srcalpha = op & 0xff;	/* FIXME create lookup table after palette is stabilized...*/	if(!rgb_to_palindex || !alpha_to_rgb) {		init_alpha_lookup();		if(!rgb_to_palindex || !alpha_to_rgb)			goto stdblit;	}	/* Create 5 bit alpha value index for 256 color indexing*/	/* destination alpha is (1 - source) alpha*/	dstalpha = ((srcalpha>>3) ^ 31) << 8;	srcalpha = (srcalpha>>3) << 8;	while(--h >= 0) {	    int	i;	    for(i=0; i<w; ++i) {		/* Get source RGB555 value for source alpha value*/		unsigned short s = alpha_to_rgb[srcalpha + *src++];		/* Get destination RGB555 value for dest alpha value*/		unsigned short d = alpha_to_rgb[dstalpha + *dst];		/* Add RGB values together and get closest palette index to it*/		*dst++ = rgb_to_palindex[s + d];	    }	    dst += dlinelen - w;	    src += slinelen - w;	}	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_ memcpy is a _must_ in this routine*/			memmove(dst, src, w);			dst += dlinelen;			src += slinelen;		}	} else {		while (--h >= 0) {			int i;			for (i=0; i<w; i++) {				applyOp(MWROP_TO_MODE(op), *src, dst, ADDR8);				++src;				++dst;			}			dst += dlinelen - w;			src += slinelen - w;		}	}	DRAWOFF;}/* srccopy stretchblt*/static voidlinear8_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw,	MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw,	MWCOORD srch, long op){	ADDR8	dst;	ADDR8	src;	int	dlinelen = dstpsd->linelen;	int	slinelen = srcpsd->linelen;	int	i, ymax;	int	row_pos, row_inc;	int	col_pos, col_inc;	unsigned char pixel = 0;	assert (dstpsd->addr != 0);	assert (dstx >= 0 && dstx < dstpsd->xres);	assert (dsty >= 0 && dsty < dstpsd->yres);	assert (dstw > 0);	assert (dsth > 0);	assert (srcpsd->addr != 0);	assert (srcx >= 0 && srcx < srcpsd->xres);	assert (srcy >= 0 && srcy < srcpsd->yres);	assert (srcw > 0);	assert (srch > 0);	assert (dstx+dstw <= dstpsd->xres);	assert (dsty+dsth <= dstpsd->yres);	assert (srcx+srcw <= srcpsd->xres);	assert (srcy+srch <= srcpsd->yres);	DRAWON;	row_pos = 0x10000;	row_inc = (srch << 16) / dsth;	/* stretch blit using integer ratio between src/dst height/width*/	for (ymax = dsty+dsth; dsty<ymax; ++dsty) {		/* find source y position*/		while (row_pos >= 0x10000L) {			++srcy;			row_pos -= 0x10000L;		}		dst = ((ADDR8)dstpsd->addr) + dstx + dsty*dlinelen;		src = ((ADDR8)srcpsd->addr) + srcx + (srcy-1)*slinelen;		/* copy a row of pixels*/		col_pos = 0x10000;		col_inc = (srcw << 16) / dstw;		for (i=0; i<dstw; ++i) {			/* get source x pixel*/			while (col_pos >= 0x10000L) {				pixel = *src++;				col_pos -= 0x10000L;			}			*dst++ = pixel;			col_pos += col_inc;		}		row_pos += row_inc;	}	DRAWOFF;}#if ALPHABLENDvoidinit_alpha_lookup(void){	int	i, a;	int	r, g, b;	extern MWPALENTRY gr_palette[256];	if(!alpha_to_rgb)		alpha_to_rgb = (unsigned short *)malloc(			sizeof(unsigned short)*32*256);	if(!rgb_to_palindex)		rgb_to_palindex = (unsigned char *)malloc(			sizeof(unsigned char)*32*32*32);	if(!rgb_to_palindex || !alpha_to_rgb)		return;	/*	 * Precompute alpha to rgb lookup by premultiplying	 * each palette rgb value by each possible alpha	 * and storing it as RGB555.	 */	for(i=0; i<256; ++i) {		MWPALENTRY *p = &gr_palette[i];		for(a=0; a<32; ++a) {			alpha_to_rgb[(a<<8)+i] =				(((p->r * a / 31)>>3) << 10) |				(((p->g * a / 31)>>3) << 5) |				 ((p->b * a / 31)>>3);		}	}	/*	 * Precompute RGB555 to palette index table by	 * finding the nearest palette index for all RGB555 colors.	 */	for(r=0; r<32; ++r) {		for(g=0; g<32; ++g)			for(b=0; b<32; ++b)				rgb_to_palindex[ (r<<10)|(g<<5)|b] =					GdFindNearestColor(gr_palette, 256,						MWRGB(r<<3, g<<3, b<<3));	}}#endif#if MW_FEATURE_PSDOP_BITMAP_BYTES_LSB_FIRST/* psd->DrawArea operation PSDOP_BITMAP_BYTES_LSB_FIRST which * takes a pixmap, each line is byte aligned, and copies it * to the screen using fg_color and bg_color to replace a 1 * and 0 in the pixmap.  This pixmap is ordered the wrong * way around; it has the leftmost pixel (on the screen) in * LSB (Bit 0) of the bytes. * * The reason why this non-intuitive bit ordering is used is * to match the bit ordering used in the T1lib font rendering * library. * * Variables used in the gc: *       dstx, dsty, dsth, dstw   Destination rectangle *       srcx, srcy               Source rectangle *       src_linelen              Linesize in bytes of source *       pixels                   Pixmap data *       fg_color                 Color of a '1' bit *       bg_color                 Color of a '0' bit *       gr_usebg                 If set, bg_color is used.  If zero, *                                then '0' bits are transparent. */static voidlinear8_drawarea_bitmap_bytes_lsb_first(PSD psd, driver_gc_t * gc){/* * The difference between the MSB_FIRST and LSB_FIRST variants of * this function is simply the definition of these three #defines. * * MWI_IS_BIT_BEFORE_OR_EQUAL(A,B) returns true if bit A is before *     (i.e. to the left of) bit B. * MWI_ADVANCE_BIT(X) advances X on to the next bit to the right, *     and stores the result back in X. * MWI_BIT_NO(N), where 0<=n<=7, gives the Nth bit, where 0 is the *     leftmost bit and 7 is the rightmost bit.  This is a constant *     iff N is a constant. */#define MWI_IS_BIT_BEFORE_OR_EQUAL(a,b) ((a) <= (b))#define MWI_ADVANCE_BIT(target) ((target) <<= 1)#define MWI_BIT_NO(n) (0x01 << (n))/* * Two convenience defines - these are the same for MSB_FIRST and * LSB_FIRST. */#define MWI_FIRST_BIT MWI_BIT_NO(0)#define MWI_LAST_BIT  MWI_BIT_NO(7)	unsigned char prefix_first_bit;	unsigned char postfix_first_bit = MWI_FIRST_BIT;	unsigned char postfix_last_bit;	unsigned char bitmap_byte;	unsigned char mask;	unsigned long fg, bg;	int first_byte, last_byte;	int size_main;	int t, y;	unsigned int advance_src, advance_dst;	ADDR8 src;	ADDR8 dst;	/* The bit in the first byte, which corresponds to the leftmost pixel. */	prefix_first_bit = MWI_BIT_NO(gc->srcx & 7);	/* The bit in the last byte, which corresponds to the rightmost pixel. */	postfix_last_bit = MWI_BIT_NO((gc->srcx + gc->dstw - 1) & 7);	/* The index into each scanline of the first byte to use. */	first_byte = gc->srcx >> 3;	/* The index into each scanline of the last byte to use. */	last_byte = (gc->srcx + gc->dstw - 1) >> 3;	src = ((ADDR8) gc->pixels) + gc->src_linelen * gc->srcy + first_byte;	dst = ((ADDR8) psd->addr) + psd->linelen * gc->dsty + gc->dstx;	fg = gc->fg_color;	bg = gc->bg_color;	advance_src = gc->src_linelen - last_byte + first_byte - 1;	advance_dst = psd->linelen - gc->dstw;	if (first_byte != last_byte) {		/* The total number of bytes to use, less the two special-cased		 * bytes (first and last).

⌨️ 快捷键说明

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