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

📄 devdraw.c

📁 the embedded GUI for SamSung s3c2410 cpu based board.is microwindows0.90
💻 C
📖 第 1 页 / 共 4 页
字号:
/** * A proper stretch blit.  Supports flipping the image. * Paramaters are co-ordinates of two points in the source, and * two corresponding points in the destination.  The image is scaled * and flipped as needed to make the two points correspond.  The * top-left corner is drawn, the bottom right one isn't [i.e. * (0,0)-(2,2) specifies a 2x2 rectangle consisting of the points * at (0,0), (0,1), (1,0), (1,1).  It does not include the points * where x=2 or y=2.] * * Raster ops are not yet fully implemented - see the low-level * drivers for details. * * Note that we do not support overlapping blits. * * @param dstpsd Drawing surface to draw to. * @param d1_x Destination X co-ordinate of first corner. * @param d1_y Destination Y co-ordinate of first corner. * @param d2_x Destination X co-ordinate of second corner. * @param d2_y Destination Y co-ordinate of second corner. * @param srcpsd Drawing surface to copy from. * @param s1_x Source X co-ordinate of first corner. * @param s1_y Source Y co-ordinate of first corner. * @param s2_x Source X co-ordinate of second corner. * @param s2_y Source Y co-ordinate of second corner. * @param rop Raster operation. */voidGdStretchBlitEx(PSD dstpsd, MWCOORD d1_x, MWCOORD d1_y, MWCOORD d2_x,	MWCOORD d2_y, PSD srcpsd, MWCOORD s1_x, MWCOORD s1_y, MWCOORD s2_x,	MWCOORD s2_y, long rop){	/* Scale factors (as fractions, numerator/denominator) */	int src_x_step_numerator;	int src_x_step_denominator;	int src_y_step_numerator;	int src_y_step_denominator;	/* Clipped dest co-ords */	MWCOORD c1_x;	MWCOORD c1_y;	MWCOORD c2_x;	MWCOORD c2_y;	/* Initial source co-ordinates, as a fraction (denominators as above) */	int src_x_start_exact;	int src_y_start_exact;	/* Used by the clipping code. */#if DYNAMICREGIONS	int count;	MWRECT *prc;	extern MWCLIPREGION *clipregion;#else	int count;	MWCLIPRECT *prc;	extern MWCLIPRECT cliprects[];	extern int clipcount;#endif	assert(srcpsd);	assert(dstpsd);	/* DPRINTF("Nano-X: GdStretchBlitEx(dst=%x (%d,%d)-(%d,%d), src=%x (%d,%d)-(%d,%d), op=0x%lx\n",	           (int) dstpsd, (int) d1_x, (int) d1_y, (int) d2_x, (int) d2_y,	           (int) srcpsd, (int) s1_x, (int) s1_y, (int) s2_x, (int) s2_y, rop); */	/* Sort co-ordinates so d1 is top left, d2 is bottom right. */	if (d1_x > d2_x) {		register MWCOORD tmp;		tmp = d2_x;		d2_x = d1_x;		d1_x = tmp;		tmp = s2_x;		s2_x = s1_x;		s1_x = tmp;	}	if (d1_y > d2_y) {		register MWCOORD tmp;		tmp = d2_y;		d2_y = d1_y;		d1_y = tmp;		tmp = s2_y;		s2_y = s1_y;		s1_y = tmp;	}	if ((d2_x < 0)	    || (d2_y < 0)	    || (d1_x > dstpsd->xvirtres)	    || (d1_y > dstpsd->yvirtres)	    || (d1_x == d2_x)	    || (d1_y == d2_y)) {		/* Destination rectangle is entirely off screen,		 * or is zero-sized - bail ASAP		 */		/* DPRINTF("Nano-X: GdStretchBlitEx: CLIPPED OFF (dest rect offscreen or 0)\n"); */		return;	}	/* If we're not stretching or flipping, use the standard blit	 * (faster).	 */	if ((d2_x - d1_x == s2_x - s1_x) && (d2_y - d1_y == s2_y - s1_y)) {		GdBlit(dstpsd, d1_x, d1_y, d2_x - d1_x, d2_y - d1_y,		       srcpsd, s1_x, s1_y, rop);		return;	}	if (!dstpsd->StretchBlitEx) {		EPRINTF("GdStretchBlitEx NOT SUPPORTED on this target\n");		return;	}	/* Need to preserve original values, so make a copy we can clip. */	c1_x = d1_x;	c1_y = d1_y;	c2_x = d2_x;	c2_y = d2_y;	/* Calculate how far in source co-ordinates is	 * equivalent to one pixel in dest co-ordinates.	 * This is stored as a fraction (numerator/denominator).	 * The numerator may be > denominator.  The numerator	 * may be negative, the denominator is always positive.	 *	 * We need half this distance for some purposes,	 * hence the *2.	 *	 * The +1s are because we care about *sizes*, not	 * deltas.  (Without the +1s it just doesn't	 * work properly.)	 */	src_x_step_numerator = (s2_x - s1_x + 1) << 1;	src_x_step_denominator = (d2_x - d1_x + 1) << 1;	src_y_step_numerator = (s2_y - s1_y + 1) << 1;	src_y_step_denominator = (d2_y - d1_y + 1) << 1;	/* Clip the image so that the destination X co-ordinates	 * in c1_x and c2_x map to a point on the source image.	 */	if ((s1_x < 0) || (s1_x > srcpsd->xvirtres)	    || (s2_x < 0) || (s2_x > srcpsd->xvirtres)) {		/* Calculate where the left of the source image will end up,		 * in dest co-ordinates.		 */		int i1_x = d1_x - (s1_x * src_x_step_denominator) / src_x_step_numerator;		/* Calculate where the right of the source image will end up,		 * in dest co-ordinates.		 */		int i2_x = d1_x + ((srcpsd->xvirtres - s1_x) * src_x_step_denominator + src_x_step_denominator - 1) / src_x_step_numerator;		/* Since we may be doing a flip, "left" and "right" in the statements		 * above do not necessarily correspond to "left" and "right" in the		 * destination image, which is where we're clipping.  So sort the		 * X co-ordinates.		 */		if (i1_x > i2_x) {			register int temp;			temp = i1_x;			i1_x = i2_x;			i2_x = temp;		}		/* Check for total invisibility */		if ((c2_x < i1_x) || (c1_x > i2_x)) {			/* DPRINTF("Nano-X: GdStretchBlitEx: CLIPPED OFF (source X checks)\n"); */			return;		}		/* Perform partial clip */		if (c1_x < i1_x)			c1_x = i1_x;		if (c2_x > i2_x)			c2_x = i2_x;	}	/* Clip the image so that the destination Y co-ordinates	 * in c1_y and c2_y map to a point on the source image.	 */	if ((s1_y < 0) || (s1_y > srcpsd->yvirtres)	    || (s2_y < 0) || (s2_y > srcpsd->yvirtres)) {		/* Calculate where the top of the source image will end up,		 * in dest co-ordinates.		 */		int i1_y = d1_y - (s1_y * src_y_step_denominator) / src_y_step_numerator;		/* Calculate where the bottom of the source image will end up,		 * in dest co-ordinates.		 */		int i2_y = d1_y + ((srcpsd->yvirtres - s1_y) * src_y_step_denominator + src_y_step_denominator - 1) / src_y_step_numerator;		/* Since we may be doing a flip, "top" and bottom" in the statements		 * above do not necessarily correspond to "top" and bottom" in the		 * destination image, which is where we're clipping.  So sort the		 * Y co-ordinates.		 */		if (i1_y > i2_y) {			register int temp;			temp = i1_y;			i1_y = i2_y;			i2_y = temp;		}		/* Check for total invisibility */		if ((c2_y < i1_y) || (c1_y > i2_y)) {			/* DPRINTF("Nano-X: GdStretchBlitEx: CLIPPED OFF (source Y checks)\n"); */			return;		}		/* Perform partial clip */		if (c1_y < i1_y)			c1_y = i1_y;		if (c2_y > i2_y)			c2_y = i2_y;	}	/* Clip against dest window (NOT dest clipping region). */	if (c1_x < 0)		c1_x = 0;	if (c1_y < 0)		c1_y = 0;	if (c2_x > dstpsd->xvirtres)		c2_x = dstpsd->xvirtres;	if (c2_y > dstpsd->yvirtres)		c2_y = dstpsd->yvirtres;	/* Final fully-offscreen check */	if ((c1_x >= c2_x)	    || (c1_y >= c2_y)) {		/* DPRINTF("Nano-X: GdStretchBlitEx: CLIPPED OFF (final check)\n"); */		return;	}	/* Well, if we survived that lot, then we now have a destination	 * rectangle defined in (c1_x,c1_y)-(c2_x,c2_y).	 */	/* DPRINTF("Nano-X: GdStretchBlitEx: Clipped rect: (%d,%d)-(%d,%d)\n",	       (int) c1_x, (int) c1_y, (int) c2_x, (int) c2_y); */	/* Calculate the position in the source rectange that is equivalent	 * to the top-left of the destination rectangle.	 */	src_x_start_exact = s1_x * src_x_step_denominator		+ (c1_x - d1_x) * src_x_step_numerator;	src_y_start_exact = s1_y * src_y_step_denominator		+ (c1_y - d1_y) * src_y_step_numerator;	/* OK, clipping so far has been against physical bounds, we now have	 * to worry about user defined clip regions.	 */	switch (GdClipArea(dstpsd, c1_x, c1_y, c2_x - 1, c2_y - 1)) {	case CLIP_INVISIBLE:		/* DPRINTF("Nano-X: GdStretchBlitEx: CLIPPED OFF (GdClipArea check)\n"); */		return;	case CLIP_VISIBLE:		/* FIXME: check cursor in src region */		/* GdCheckCursor(srcpsd, c1_x, c1_y, c2_x-1, c2_y-1); */		/* DPRINTF("Nano-X: GdStretchBlitEx: no more clipping needed\n"); */		dstpsd->StretchBlitEx(dstpsd,					srcpsd,					c1_x,					c1_y,					c2_x - c1_x,					c2_y - c1_y,					src_x_step_denominator,					src_y_step_denominator,					src_x_start_exact,					src_y_start_exact,					src_x_step_numerator,					src_y_step_numerator, rop);		/* GdFixCursor(srcpsd); */		GdFixCursor(dstpsd);		return;	}	/* DPRINTF("Nano-X: GdStretchBlitEx: complex clipping needed\n"); */	/* FIXME: check cursor in src region */	/* GdCheckCursor(srcpsd, c1_x, c1_y, c2_x-1, c2_y-1); */	/* Partly clipped, we'll blit using destination clip	 * rectangles, and offset the blit accordingly.	 * Since the destination is already clipped, we	 * only need to clip the source here.	 */#if DYNAMICREGIONS	prc = clipregion->rects;	count = clipregion->numRects;#else	prc = cliprects;	count = clipcount;#endif	while (--count >= 0) {		int r1_x, r2_x, r1_y, r2_y;#if DYNAMICREGIONS		r1_x = prc->left;		r1_y = prc->top;		r2_x = prc->right;		r2_y = prc->bottom;#else		r1_x = prc->x;		r1_y = prc->y;		r2_x = prc->x + prc->width;		r2_y = prc->y + prc->height;#endif		/* Check:  does this rect intersect the one we want to draw? */		/* Clip r1-r2 so it's inside c1-c2 */		if (r1_x < c1_x)			r1_x = c1_x;		if (r1_y < c1_y)			r1_y = c1_y;		if (r2_x > c2_x)			r2_x = c2_x;		if (r2_y > c2_y)			r2_y = c2_y;		if ((r1_x < r2_x) && (r1_y < r2_y)) {			/* So we're drawing to:			 * destination rectangle (r1_x, r1_y) - (r2_x, r2_y)			 * source start co-ords:			 * x = src_x_start_exact + (r1_x - c1_x)*src_x_step_numerator			 * y = src_y_start_exact + (r1_y - c1_y)*src_y_step_numerator			 */			/* check cursor in dest region */			GdCheckCursor(dstpsd, r1_x, r1_y, r2_x - 1,					  r2_y - 1);			dstpsd->StretchBlitEx(dstpsd,						srcpsd,						r1_x,						r1_y,						r2_x - r1_x,						r2_y - r1_y,						src_x_step_denominator,						src_y_step_denominator,						src_x_start_exact + (r1_x - c1_x) * src_x_step_numerator,						src_y_start_exact + (r1_y - c1_y) * src_y_step_numerator,						src_x_step_numerator,						src_y_step_numerator,						rop);		}		++prc;	}	GdFixCursor(dstpsd);	/* GdFixCursor(srcpsd); */}/* * Calculate size and linelen of memory gc. * If bpp or planes is 0, use passed psd's bpp/planes. * Note: linelen is calculated to be DWORD aligned for speed * for bpp <= 8.  Linelen is converted to bytelen for bpp > 8. */intGdCalcMemGCAlloc(PSD psd, unsigned int width, unsigned int height, int planes,	int bpp, int *psize, int *plinelen){	int	bytelen, linelen, tmp;	if(!planes)		planes = psd->planes;	if(!bpp)		bpp = psd->bpp;	/* 	 * swap width and height in left/right portrait modes,	 * so imagesize is calculated properly	 */	if(psd->portrait & (MWPORTRAIT_LEFT|MWPORTRAIT_RIGHT)) {		tmp = width;		width = height;		height = tmp;	}	/*	 * use bpp and planes to create size and linelen.	 * linelen is in bytes for bpp 1, 2, 4, 8, and pixels for bpp 16,24,32.	 */	if(planes == 1) {		switch(bpp) {		case 1:			linelen = (width+7)/8;			bytelen = linelen = (linelen+3) & ~3;			break;		case 2:			linelen = (width+3)/4;			bytelen = linelen = (linelen+3) & ~3;			break;		case 4:			linelen = (width+1)/2;			bytelen = linelen = (linelen+3) & ~3;			break;		case 8:			bytelen = linelen = (width+3) & ~3;			break;		case 16:			linelen = width;			bytelen = width * 2;			break;		case 24:			linelen = width;			bytelen = width * 3;			break;		case 32:			linelen = width;			bytelen = width * 4;			break;		default:			return 0;		}	} else if(planes == 4) {		/* FIXME assumes VGA 4 planes 4bpp*/		/* we use 4bpp linear for memdc format*/		linelen = (width+1)/2;		linelen = (linelen+3) & ~3;		bytelen = linelen;	} else {		*psize = *plinelen = 0;		return 0;	}	*plinelen = linelen;	*psize = bytelen * height;	return 1;}/** * Translate a rectangle of color values * * The pixels are packed according to inpixtype/outpixtype: * * pixtype		array of * MWPF_RGB		MWCOLORVAL (unsigned long) * MWPF_PIXELVAL	MWPIXELVAL (compile-time dependent) * MWPF_PALETTE		unsigned char * MWPF_TRUECOLOR8888	unsigned long * MWPF_TRUECOLOR0888	unsigned long * MWPF_TRUECOLOR888	packed struct {char r,char g,char b} (24 bits) * MWPF_TRUECOLOR565	unsigned short * MWPF_TRUECOLOR555	unsigned short * MWPF_TRUECOLOR332	unsigned char * * @param width Width of rectangle to translate. * @param height Height of rectangle to translate. * @param in Source pixels buffer. * @param inpixtype Source pixel type. * @param inpitch Source pitch. * @param out Destination pixels buffer. * @param outpixtype Destination pixel type. * @param outpitch Destination pitch. */voidGdTranslateArea(MWCOORD width, MWCOORD height, void *in, int inpixtype,	MWCOORD inpitch, void *out, int outpixtype, int outpitch){	unsigned char *	inbuf = in;	unsigned char *	outbuf = out;	unsigned long	pixelval;	MWCOLORVAL	colorval;	MWCOORD		x, y;	unsigned char 	r, g, b;	extern MWPALENTRY gr_palette[256];	int	  gr_palsize = 256;	/* FIXME*/	for(y=0; y<height; ++y) {	    for(x=0; x<width; ++x) {		/* read pixel value and convert to BGR colorval (0x00BBGGRR)*/		switch (inpixtype) {		case MWPF_RGB:			colorval = *(MWCOLORVAL *)inbuf;			inbuf += sizeof(MWCOLORVAL);			break;		case MWPF_PIXELVAL:			pixelval = *(MWPIXELVAL *)inbuf;			inbuf += sizeof(MWPIXELVAL);			/* convert based on compile-time MWPIXEL_FORMAT*/#if MWPIXEL_FORMAT == MWPF_PALETTE			colorval = GETPALENTRY(gr_palette, pixelval);#else			colorval = PIXELVALTOCOLORVAL(pixelval);#endif			break;		case MWPF_PALETTE:			pixelval = *inbuf++;			colorval = GETPALENTRY(gr_palette, pixelval);			break;		case MWPF_TRUECOLOR332:			pixelval = *inbuf++;			colorval = PIXEL332TOCOLORVAL(pixelval);			break;		case MWPF_TRUECOLOR0888:			pixelval = *(unsigned long *)inbuf;			colorval = PIXEL888TOCOLORVAL(pixelval);			inbuf += sizeof(unsigned long);			break;		case MWPF_TRUECOLOR8888:			pixelval = *(unsigned long *) inbuf;			colorval = PIXEL8888TOCOLORVAL(pixelval);			inbuf += sizeof(unsigned long);			break;		case MWPF_TRUECOLOR888:			r = *inbuf++;			g = *inbuf++;			b = *inbuf++;			colorval = (MWPIXELVAL)MWRGB(r, g, b);			break;		case MWPF_TRUECOLOR565:			pixelval = *(unsigned short *)inbuf;			colorval = PIXEL565TOCOLORVAL(pixelval);			inbuf += sizeof(unsigned short);			break;		case MWPF_TRUECOLOR555:			pixelval = *(unsigned short *)inbuf;			colorval = PIXEL555TOCOLORVAL(pixelval);			inbuf += sizeof(unsigned short);			break;		default:			return;		}		/* convert from BGR colorval to desired output pixel format*/		switch (outpixtype) {		case MWPF_RGB:			*(MWCOLORVAL *)outbuf = colorval;			outbuf += sizeof(MWCOLORVAL);			break;		case MWPF_PIXELVAL:			/* convert based on compile-time MWPIXEL_FORMAT*/#if MWPIXEL_FORMAT == MWPF_PALETTE			*(MWPIXELVAL *)outbuf = GdFindNearestColor(gr_palette,					gr_palsize, colorval);#else			*(MWPIXELVAL *)outbuf = COLORVALTOPIXELVAL(colorval);#endif			outbuf += sizeof(MWPIXELVAL);			break;		case MWPF_PALETTE:			*outbuf++ = GdFindNearestColor(gr_palette, gr_palsize,					colorval);			break;		case MWPF_TRUECOLOR332:			*outbuf++ = COLOR2PIXEL332(colorval);			break;		case MWPF_TRUECOLOR0888:			*(unsigned long *)outbuf = COLOR2PIXEL888(colorval);			outbuf += sizeof(unsigned long);			break;		case MWPF_TRUECOLOR8888:			*(unsigned long *) outbuf =				COLOR2PIXEL8888(colorval);			outbuf += sizeof(unsigned long);			break;		case MWPF_TRUECOLOR888:			*outbuf++ = REDVALUE(colorval);			*outbuf++ = GREENVALUE(colorval);			*outbuf++ = BLUEVALUE(colorval);			break;		case MWPF_TRUECOLOR565:			*(unsigned short *)outbuf = COLOR2PIXEL565(colorval);			outbuf += sizeof(unsigned short);			break;		case MWPF_TRUECOLOR555:			*(unsigned short *)outbuf = COLOR2PIXEL555(colorval);			outbuf += sizeof(unsigned short);			break;		}	    }	    /* adjust line widths, if necessary*/	    if(inpitch > width)		    inbuf += inpitch - width;	    if(outpitch > width)		    outbuf += outpitch - width;	}}

⌨️ 快捷键说明

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