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

📄 devstipple.c

📁 the embedded GUI for SamSung s3c2410 cpu based board.is microwindows0.90
💻 C
字号:
/* * Copyright (c) 2001, 2002 Century Embedded Technologies * * Written by Jordan Crouse *  * Stipple and tile engine routines */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "device.h"extern MWPIXELVAL gr_foreground;	/* current foreground color */extern MWPIXELVAL gr_background;	/* current background color */extern int gr_fillmode;			/* current fill mode        */extern MWSTIPPLE gr_stipple;		/* The current stipple as set by the GC */extern MWTILE gr_tile;			/* The current tile as set by the GC */extern MWPOINT gr_ts_offset;		/* The x and y offset of the tile / stipple */static int ts_origin_x = 0;static int ts_origin_y = 0;/* Some useful macros */#define SPITCH ((gr_stipple.width + (MWIMAGE_BITSPERIMAGE - 1)) / MWIMAGE_BITSPERIMAGE)/* This is when the bits are least significantly aligned *//* #define BIT_SET(data, w, h) \	(data[(h * SPITCH) + (w / MWIMAGE_BITSPERIMAGE)] & (1 << (w % MWIMAGE_BITSPERIMAGE))) *//* This is when the bits are most significantly aligned */#define BIT_SET(data, w, h) \	(data[(h * SPITCH) + (w / MWIMAGE_BITSPERIMAGE)] & (1 << ((MWIMAGE_BITSPERIMAGE - 1) - (w % MWIMAGE_BITSPERIMAGE))))voidGdSetStippleBitmap(MWIMAGEBITS *stipple, MWCOORD width, MWCOORD height){	int x, y;	int size;	if (gr_stipple.bitmap)		free(gr_stipple.bitmap);	gr_stipple.width = 0;	gr_stipple.height = 0;	if (!stipple) {		gr_stipple.bitmap = 0;		return;	}	size = MWIMAGE_SIZE(width, height) * sizeof(MWIMAGEBITS);	gr_stipple.bitmap = malloc(size);	if (!gr_stipple.bitmap)		return;	gr_stipple.width = width;	gr_stipple.height = height;	memcpy(gr_stipple.bitmap, stipple, size);	/* debug output*/	for (y = 0; y < height; y++) {		for (x = 0; x < width; x++) {			if (BIT_SET(gr_stipple.bitmap, x, y))				DPRINTF("X");			else				DPRINTF("_");		}		DPRINTF("\n");	}}voidGdSetTilePixmap(PSD src, MWCOORD width, MWCOORD height){	gr_tile.psd = src;	if (!src) {		gr_tile.width = 0;		gr_tile.height = 0;	} else {		gr_tile.width = width;		gr_tile.height = height;	}}/* This sets the stipple offset to the specified offset */voidGdSetTSOffset(int x, int y){	gr_ts_offset.x = x;	gr_ts_offset.y = y;}/* Set the bounding rect for the stipple.  This also constructs a bitmap that gives us an easy   lookup when the time comes *//* This only works for tiles */static voidtile_drawrect(PSD psd, MWCOORD x, MWCOORD y, MWCOORD w, MWCOORD h){	int sx = x, sy = y;	int px = 0, py = 0;	int dw = w;	int dh = h;	/* This is where the tile starts */	int tilex = x - ts_origin_x;	int tiley = y - ts_origin_y;	/* Sanity check */	if (!gr_tile.psd || !gr_tile.width || !gr_tile.height)		return;	/* Adjust the starting point to correspond with the tile offset */	if (tilex < 0) {		sx += -tilex;		dw -= -tilex;		if (sx > (x + w - 1))			return;		tilex = sx - ts_origin_x;	}	if (tiley < 0) {		sy += -tiley;		dh -= -tiley;		if (sy > (y + h - 1))			return;		tiley = sy - ts_origin_y;	}	while (dh) {		int ch = (gr_tile.height - ((tiley + py) % gr_tile.height));		if (ch > dh)			ch = dh;		dw = w;		px = 0;		while (dw) {			int cw = (gr_tile.width -				 ((tilex + px) % gr_tile.width));			if (cw > dw)				cw = dw;			GdBlit(psd, sx + px, sy + py, cw, ch, gr_tile.psd,			       ((tilex + px) % gr_tile.width),			       ((tiley + py) % gr_tile.height), MWROP_SRCCOPY);			dw -= cw;			px += cw;		}		dh -= ch;		py += ch;	}}/* This sets the origin of the stipple (we add the offset) *//* We use this in the following functions                  */voidset_ts_origin(int x, int y){	ts_origin_x = x + gr_ts_offset.x;	ts_origin_y = y + gr_ts_offset.y;}/* For these, we need to ensure that the points fall within the stipple box */voidts_drawpoint(PSD psd, MWCOORD x, MWCOORD y){	int bx = x - ts_origin_x;	int by = y - ts_origin_y;	/* Sanity check - If no stipple / tile is set, then just ignore the request */	/* FIXME:  X returns an error - Should we too?                              */	if (gr_fillmode == MWFILL_STIPPLE	    || gr_fillmode == MWFILL_OPAQUE_STIPPLE) {		if (!gr_stipple.bitmap || !gr_stipple.width		    || !gr_stipple.height)		    	return;	} else {		if (!gr_tile.psd || !gr_tile.width || !gr_tile.height)			return;	}	if (!GdClipPoint(psd, x, y))		return;	/* If the bit offset is less than zero    */	/* Meaning that the pixel in question     */	/* is to the left or above the current    */	/* offset - Then just draw the foreground */	/* FIXME:  Should we just skip the pixel instead? */	if (bx < 0 || by < 0) {		psd->DrawPixel(psd, x, y, gr_foreground);		return;	}	switch (gr_fillmode) {	case MWFILL_OPAQUE_STIPPLE:		/* FIXME: precompute bitset, don't do it twice */		if (!BIT_SET(gr_stipple.bitmap, (bx % gr_stipple.width), (by % gr_stipple.height)))		     	psd->DrawPixel(psd, x, y, gr_background);		/* Fall through */	case MWFILL_STIPPLE:		if (BIT_SET(gr_stipple.bitmap, (bx % gr_stipple.width), (by % gr_stipple.height)))			psd->DrawPixel(psd, x, y, gr_foreground);		break;	case MWFILL_TILE:		/* Read the bit from the PSD and write it to the current PSD */		/* FIXME:  This does no checks for depth correctness         */		psd->DrawPixel(psd, x, y,			gr_tile.psd->ReadPixel(gr_tile.psd,				(bx % gr_tile.width), (by % gr_tile.height)));		break;	}}/* FIXME:  Optimize the stipple so it uses more bliting and less pixel by pixel stuff */voidts_drawrow(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y){	int x;	int dstwidth = x2 - x1 + 1;	switch (gr_fillmode) {	case MWFILL_STIPPLE:	case MWFILL_OPAQUE_STIPPLE:		for (x = x1; x <= x2; x++)			ts_drawpoint(psd, x, y);		break;	case MWFILL_TILE:		tile_drawrect(psd, x1, y, dstwidth, 1);	}}voidts_fillrect(PSD psd, MWCOORD x, MWCOORD y, MWCOORD w, MWCOORD h){	int x1 = x;	int x2 = x + w - 1;	int y1 = y;	int y2 = y + h - 1;	if (GdClipArea(psd, x1, y1, x2, y2) == CLIP_INVISIBLE)		return;	if (gr_fillmode == MWFILL_TILE)		tile_drawrect(psd, x, y, w, h);	else		for (; y1 <= y2; y1++)			ts_drawrow(psd, x1, x2, y1);}

⌨️ 快捷键说明

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