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

📄 devdraw.c

📁 the embedded GUI for SamSung s3c2410 cpu based board.is microwindows0.90
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1999, 2000, 2001, 2003 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V. * Portions Copyright (c) 1991 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * Device-independent mid level drawing and color routines. * * These routines do the necessary range checking, clipping, and cursor * overwriting checks, and then call the lower level device dependent * routines to actually do the drawing.  The lower level routines are * only called when it is known that all the pixels to be drawn are * within the device area and are visible. *//*#define NDEBUG*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "device.h"extern MWPIXELVAL gr_foreground;      /* current foreground color */extern MWPIXELVAL gr_background;      /* current background color */extern MWBOOL 	  gr_usebg;    	      /* TRUE if background drawn in pixmaps */extern int 	  gr_mode; 	      /* drawing mode */extern MWPALENTRY gr_palette[256];    /* current palette*/extern int	  gr_firstuserpalentry;/* first user-changable palette entry*/extern int 	  gr_nextpalentry;    /* next available palette entry*//* These support drawing dashed lines */extern unsigned long gr_dashmask;     /* An actual bitmask of the dash values */extern unsigned long gr_dashcount;    /* The number of bits defined in the dashmask */extern int        gr_fillmode;/*static*/ void drawpoint(PSD psd,MWCOORD x, MWCOORD y);/*static*/ void drawrow(PSD psd,MWCOORD x1,MWCOORD x2,MWCOORD y);static void drawcol(PSD psd,MWCOORD x,MWCOORD y1,MWCOORD y2);/** * Set the drawing mode for future calls. * * @param mode New drawing mode. * @return Old drawing mode. */intGdSetMode(int mode){	int oldmode = gr_mode;	gr_mode = mode;	return oldmode;}/** * Set the fill mode for future calls. * * @param mode New fill mode. * @return Old fill mode. */intGdSetFillMode(int mode){	int oldmode = gr_fillmode;	gr_fillmode = mode;	return oldmode;}/** * Set whether or not the background is used for drawing pixmaps and text. * * @param flag Flag indicating whether or not to draw the background. * @return Old value of flag. */MWBOOLGdSetUseBackground(MWBOOL flag){	MWBOOL oldusebg = gr_usebg;	gr_usebg = flag;	return oldusebg;}/* * Set the foreground color for drawing from passed pixel value. * * @param psd Screen device. * @param bg Background pixel value. */MWPIXELVALGdSetForegroundPixelVal(PSD psd, MWPIXELVAL fg){	MWPIXELVAL oldfg = gr_foreground;	gr_foreground = fg;	return oldfg;}/* * Set the background color for bitmap and text backgrounds * from passed pixel value. * * @param psd Screen device. * @param bg Background pixel value. */MWPIXELVALGdSetBackgroundPixelVal(PSD psd, MWPIXELVAL bg){	MWPIXELVAL oldbg = gr_background;	gr_background = bg;	return oldbg;}/** * Set the foreground color for drawing from passed RGB color value. * * @param psd Screen device. * @param fg Foreground RGB color to use for drawing. * @return Old foreground color. */MWPIXELVALGdSetForegroundColor(PSD psd, MWCOLORVAL fg){	MWPIXELVAL oldfg = gr_foreground;	gr_foreground = GdFindColor(psd, fg);	return oldfg;}/** * Set the background color for bitmap and text backgrounds * from passed RGB color value. * * @param psd Screen device. * @param bg Background color to use for drawing. * @return Old background color. */MWPIXELVALGdSetBackgroundColor(PSD psd, MWCOLORVAL bg){	MWPIXELVAL oldbg = gr_background;	gr_background = GdFindColor(psd, bg);	return oldbg;}/** * Set the dash mode for future drawing */voidGdSetDash(unsigned long *mask, int *count){	int oldm = gr_dashmask;	int oldc = gr_dashcount;	if (!mask || !count)		return;	gr_dashmask = *mask;	gr_dashcount = *count;	*mask = oldm;	*count = oldc;}/** * Draw a point using the current clipping region and foreground color. * * @param psd Drawing surface. * @param x X co-ordinate to draw point. * @param y Y co-ordinate to draw point. */voidGdPoint(PSD psd, MWCOORD x, MWCOORD y){	if (GdClipPoint(psd, x, y)) {		psd->DrawPixel(psd, x, y, gr_foreground);		GdFixCursor(psd);	}}/** * Draw an arbitrary line using the current clipping region and foreground color * If bDrawLastPoint is FALSE, draw up to but not including point x2, y2. * * This routine is the only routine that adjusts coordinates for supporting * two different types of upper levels, those that draw the last point * in a line, and those that draw up to the last point.  All other local * routines draw the last point.  This gives this routine a bit more overhead, * but keeps overall complexity down. * * @param psd Drawing surface. * @param x1 Start X co-ordinate * @param y1 Start Y co-ordinate * @param x2 End X co-ordinate * @param y2 End Y co-ordinate * @param bDrawLastPoint TRUE to draw the point at (x2, y2).  FALSE to omit it. */voidGdLine(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2,       MWBOOL bDrawLastPoint) {	int xdelta;		/* width of rectangle around line */	int ydelta;		/* height of rectangle around line */	int xinc;		/* increment for moving x coordinate */	int yinc;		/* increment for moving y coordinate */	int rem;		/* current remainder */	unsigned int bit = 0;	/* used for dashed lines */	MWCOORD temp;	/* See if the line is horizontal or vertical. If so, then call	 * special routines.	 */	if (y1 == y2) {		/*		 * Adjust coordinates if not drawing last point.  Tricky.		 */		if (!bDrawLastPoint) {			if (x1 > x2) {				temp = x1;				x1 = x2 + 1;				x2 = temp;			} else				--x2;		}		/* call faster line drawing routine */		drawrow(psd, x1, x2, y1);		GdFixCursor(psd);		return;	}	if (x1 == x2) {		/*		 * Adjust coordinates if not drawing last point.  Tricky.		 */		if (!bDrawLastPoint) {			if (y1 > y2) {				temp = y1;				y1 = y2 + 1;				y2 = temp;			} else				--y2;		}		/* call faster line drawing routine */		drawcol(psd, x1, y1, y2);		GdFixCursor(psd);		return;	}	/* See if the line is either totally visible or totally invisible. If	 * so, then the line drawing is easy.	 */	switch (GdClipArea(psd, x1, y1, x2, y2)) {	case CLIP_VISIBLE:		/*		 * For size considerations, there's no low-level bresenham		 * line draw, so we've got to draw all non-vertical		 * and non-horizontal lines with per-point		 * clipping for the time being		 psd->Line(psd, x1, y1, x2, y2, gr_foreground);		 GdFixCursor(psd);		 return;		 */		break;	case CLIP_INVISIBLE:		return;	}	/* The line may be partially obscured. Do the draw line algorithm	 * checking each point against the clipping regions.	 */	xdelta = x2 - x1;	ydelta = y2 - y1;	if (xdelta < 0)		xdelta = -xdelta;	if (ydelta < 0)		ydelta = -ydelta;	xinc = (x2 > x1)? 1 : -1;	yinc = (y2 > y1)? 1 : -1;	/* draw first point*/	if (GdClipPoint(psd, x1, y1))		psd->DrawPixel(psd, x1, y1, gr_foreground);	if (xdelta >= ydelta) {		rem = xdelta / 2;		for (;;) {			if (!bDrawLastPoint && x1 == x2)				break;			x1 += xinc;			rem += ydelta;			if (rem >= xdelta) {				rem -= xdelta;				y1 += yinc;			}			if (gr_dashcount) {				if ((gr_dashmask & (1 << bit)) && GdClipPoint(psd, x1, y1))					psd->DrawPixel(psd, x1, y1, gr_foreground);				bit = (bit + 1) % gr_dashcount;			} else {	/* No dashes */				if (GdClipPoint(psd, x1, y1))					psd->DrawPixel(psd, x1, y1, gr_foreground);			}			if (bDrawLastPoint && x1 == x2)				break;		}	} else {		rem = ydelta / 2;		for (;;) {			if (!bDrawLastPoint && y1 == y2)				break;			y1 += yinc;			rem += xdelta;			if (rem >= ydelta) {				rem -= ydelta;				x1 += xinc;			}			/* If we are trying to draw to a dash mask */			if (gr_dashcount) {				if ((gr_dashmask & (1 << bit)) && GdClipPoint(psd, x1, y1))					psd->DrawPixel(psd, x1, y1, gr_foreground);				bit = (bit + 1) % gr_dashcount;			} else {	/* No dashes */				if (GdClipPoint(psd, x1, y1))					psd->DrawPixel(psd, x1, y1, gr_foreground);			}			if (bDrawLastPoint && y1 == y2)				break;		}	}	GdFixCursor(psd);}/* Draw a point in the foreground color, applying clipping if necessary*//*static*/ voiddrawpoint(PSD psd, MWCOORD x, MWCOORD y){	if (GdClipPoint(psd, x, y))		psd->DrawPixel(psd, x, y, gr_foreground);}/* Draw a horizontal line from x1 to and including x2 in the * foreground color, applying clipping if necessary. *//*static*/ voiddrawrow(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y){	MWCOORD temp;	/* reverse endpoints if necessary */	if (x1 > x2) {		temp = x1;		x1 = x2;		x2 = temp;	}	/* clip to physical device */	if (x1 < 0)		x1 = 0;	if (x2 >= psd->xvirtres)		x2 = psd->xvirtres - 1;	/* check cursor intersect once for whole line */	GdCheckCursor(psd, x1, y, x2, y);	/* If aren't trying to draw a dash, then head for the speed */	if (!gr_dashcount) {		while (x1 <= x2) {			if (GdClipPoint(psd, x1, y)) {				temp = MWMIN(clipmaxx, x2);				psd->DrawHorzLine(psd, x1, temp, y, gr_foreground);			} else				temp = MWMIN(clipmaxx, x2);			x1 = temp + 1;		}	} else {		unsigned int p, bit = 0;		/* We want to draw a dashed line instead */		for (p = x1; p <= x2; p++) {			if ((gr_dashmask & (1 << bit)) && GdClipPoint(psd, p, y))				psd->DrawPixel(psd, p, y, gr_foreground);			bit = (bit + 1) % gr_dashcount;		}	}}/* Draw a vertical line from y1 to and including y2 in the * foreground color, applying clipping if necessary. */static voiddrawcol(PSD psd, MWCOORD x,MWCOORD y1,MWCOORD y2){	MWCOORD temp;	/* reverse endpoints if necessary */	if (y1 > y2) {		temp = y1;		y1 = y2;		y2 = temp;	}	/* clip to physical device */	if (y1 < 0)		y1 = 0;	if (y2 >= psd->yvirtres)		y2 = psd->yvirtres - 1;	/* check cursor intersect once for whole line */	GdCheckCursor(psd, x, y1, x, y2);	if (!gr_dashcount) {		while (y1 <= y2) {			if (GdClipPoint(psd, x, y1)) {				temp = MWMIN(clipmaxy, y2);				psd->DrawVertLine(psd, x, y1, temp, gr_foreground);			} else				temp = MWMIN(clipmaxy, y2);			y1 = temp + 1;		}	} else {		unsigned int p, bit = 0;		/* We want to draw a dashed line instead */		for (p = y1; p <= y2; p++) {			if ((gr_dashmask & (1<<bit)) && GdClipPoint(psd, x, p))				psd->DrawPixel(psd, x, p, gr_foreground);			bit = (bit + 1) % gr_dashcount;		}	}}/** * Draw a rectangle in the foreground color, applying clipping if necessary. * This is careful to not draw points multiple times in case the rectangle * is being drawn using XOR. * * @param psd Drawing surface. * @param x Left edge of rectangle. * @param y Top edge of rectangle. * @param width Width of rectangle. * @param height Height of rectangle. */voidGdRect(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height){	MWCOORD maxx;	MWCOORD maxy;	if (width <= 0 || height <= 0)		return;	maxx = x + width - 1;	maxy = y + height - 1;	drawrow(psd, x, maxx, y);	if (height > 1)		drawrow(psd, x, maxx, maxy);	if (height < 3)		return;	++y;	--maxy;	drawcol(psd, x, y, maxy);	if (width > 1)		drawcol(psd, maxx, y, maxy);	GdFixCursor(psd);}/** * Draw a filled in rectangle in the foreground color, applying * clipping if necessary. * * @param psd Drawing surface. * @param x1 Left edge of rectangle. * @param y1 Top edge of rectangle. * @param width Width of rectangle. * @param height Height of rectangle. */voidGdFillRect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD width, MWCOORD height){	unsigned long dm = 0, dc = 0;	MWCOORD x2 = x1 + width - 1;	MWCOORD y2 = y1 + height - 1;	if (width <= 0 || height <= 0)		return;	/* Stipples and tiles have their own drawing routines */	if (gr_fillmode != MWFILL_SOLID) {		set_ts_origin(x1, y1);		ts_fillrect(psd, x1, y1, width, height);		GdFixCursor(psd);		return;	}	/* See if the rectangle is either totally visible or totally	 * invisible. If so, then the rectangle drawing is easy.	 */	switch (GdClipArea(psd, x1, y1, x2, y2)) {	case CLIP_VISIBLE:		psd->FillRect(psd, x1, y1, x2, y2, gr_foreground);		GdFixCursor(psd);		return;	case CLIP_INVISIBLE:		return;	}	/* Quickly save off the dash settings to avoid problems with drawrow */	GdSetDash(&dm, (int *) &dc);	/* The rectangle may be partially obstructed. So do it line by line. */	while (y1 <= y2)		drawrow(psd, x1, x2, y1++);	/* Restore the dash settings */	GdSetDash(&dm, (int *) &dc);	GdFixCursor(psd);}/** * Draw a rectangular area using the current clipping region and the * specified bit map.  This differs from rectangle drawing in that the * rectangle is drawn using the foreground color and possibly the background * color as determined by the bit map.  Each row of bits is aligned to the * next bitmap word boundary (so there is padding at the end of the row). * (I.e. each row begins at the start of a new MWIMAGEBITS value). * The background bit values are only written if the gr_usebg flag * is set. * The function drawbitmap performs no clipping, GdBitmap clips. * * @param psd Drawing surface. * @param x Left edge of destination rectangle. * @param y Top edge of destination rectangle. * @param width Width of bitmap.  Equal to width of destination rectangle. * @param height Height of bitmap.  Equal to height of destination rectangle. * @param imagebits The bitmap to draw. */voiddrawbitmap(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,	const MWIMAGEBITS *imagebits){	MWCOORD minx;	MWCOORD maxx;	MWIMAGEBITS bitvalue = 0;	/* bitmap word value */	int bitcount;			/* number of bits left in bitmap word */	if (width <= 0 || height <= 0)		return;	if (gr_usebg)		psd->FillRect(psd, x, y, x + width - 1, y + height - 1,			gr_background);	/* FIXME think of the speedups if this existed...	psd->DrawBitmap(psd, x, y, width, height, imagebits, gr_foreground);	return;	*/	minx = x;	maxx = x + width - 1;	bitcount = 0;	while (height > 0) {		if (bitcount <= 0) {			bitcount = MWIMAGE_BITSPERIMAGE;			bitvalue = *imagebits++;		}		/* draw without clipping*/

⌨️ 快捷键说明

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