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

📄 devdraw.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
		cr = GETPALENTRY(palette, i);
		convtable[i] = GdFindColor(cr);
	}
}

/*
 * Draw a color bitmap image in 1, 4, 8, 24 or 32 bits per pixel.  The
 * Microwindows color image format is DWORD padded bytes, with
 * the upper bits corresponding to the left side (identical to 
 * the MS Windows format).  This format is currently different
 * than the MWIMAGEBITS format, which uses word-padded bits
 * for monochrome display only, where the upper bits in the word
 * correspond with the left side.
 */
void
GdDrawImage(PSD psd, MWCOORD x, MWCOORD y, PMWIMAGEHDR pimage)
{
  MWCOORD minx;
  MWCOORD maxx;
  MWUCHAR bitvalue = 0;
  int bitcount;
  MWUCHAR *imagebits;
  MWCOORD	height, width;
  MWPIXELVAL pixel;
  int clip;
  int extra, linesize;
  int	rgborder;
  MWCOLORVAL cr;
  MWCOORD yoff;
  unsigned long transcolor;
  MWPIXELVAL convtable[256];

  height = pimage->height;
  width = pimage->width;

  /* determine if entire image is clipped out, save clipresult for later*/
  clip = GdClipArea(psd, x, y, x + width - 1, y + height - 1);
  if(clip == CLIP_INVISIBLE)
	return;

  transcolor = pimage->transcolor;

  /*
   * Merge the images's palette and build a palette index conversion table.
   */
  if (pimage->bpp <= 8) {
	if(!pimage->palette) {
		/* for jpeg's without a palette*/
		for(yoff=0; yoff<pimage->palsize; ++yoff)
			convtable[yoff] = yoff;
	} else GdMakePaletteConversionTable(psd, pimage->palette,
		pimage->palsize, convtable, MERGEPALETTE);

	/* The following is no longer used.  One reason is that it required */
	/* the transparent color to be unique, which was unnessecary        */

	/* convert transcolor to converted palette index for speed*/
	/* if (transcolor != -1L)
	   transcolor = (unsigned long) convtable[transcolor];  */
  }

  minx = x;
  maxx = x + width - 1;
  imagebits = pimage->imagebits;

  /* check for bottom-up image*/
  if(pimage->compression & MWIMAGE_UPSIDEDOWN) {
	y += height - 1;
	yoff = -1;
  } else
	yoff = 1;

#define PIX2BYTES(n)	(((n)+7)/8)
  /* imagebits are dword aligned*/
  switch(pimage->bpp) {
  default:
  case 8:
	linesize = width;
	break;
  case 32:
	linesize = width*4;
	break;
  case 24:
	linesize = width*3;
	break;
  case 4:
	linesize = PIX2BYTES(width<<2);
	break;
  case 1:
	linesize = PIX2BYTES(width);
	break;
  }
  extra = pimage->pitch - linesize;

  /* 24bpp RGB rather than BGR byte order?*/
  rgborder = pimage->compression & MWIMAGE_RGB; 

  bitcount = 0;
  while(height > 0) {
	unsigned long trans = 0;

	if (bitcount <= 0) {
		bitcount = sizeof(MWUCHAR) * 8;
		bitvalue = *imagebits++;
	}
	switch(pimage->bpp) {
	case 24:
	case 32:
		cr = rgborder? MWRGB(bitvalue, imagebits[0], imagebits[1]):
			MWRGB(imagebits[1], imagebits[0], bitvalue);
                 
		/* Include the upper bits for transcolor stuff */
		if (imagebits[2])	/* FIXME: 24bpp error*/
		    trans = cr | 0x01000000L;

		if (pimage->bpp == 32)
			imagebits += 3;
		else imagebits += 2;
		bitcount = 0;

		/* handle transparent color*/
		if (transcolor == trans)
		    goto next;

		switch(psd->pixtype) {
		case MWPF_PALETTE:
		default:
			pixel = GdFindColor(cr);
			break;
		case MWPF_TRUECOLOR0888:
		case MWPF_TRUECOLOR888:
			pixel = COLOR2PIXEL888(cr);
			break;
		case MWPF_TRUECOLOR565:
			pixel = COLOR2PIXEL565(cr);
			break;
		case MWPF_TRUECOLOR555:
			pixel = COLOR2PIXEL555(cr);
			break;
		case MWPF_TRUECOLOR332:
			pixel = COLOR2PIXEL332(cr);
			break;
		case MWPF_TRUECOLOR233:
			pixel = COLOR2PIXEL233(cr);
			break;
		}
		break;
	default:
	case 8:
	  bitcount = 0;
	  if (bitvalue == transcolor)
	      goto next;

	  pixel = convtable[bitvalue];
	  break;
	case 4:
	  if (((bitvalue & 0xf0) >> 4) == transcolor) {
	       bitvalue <<= 4;
	       bitcount -= 4;
	       goto next;
	  }

	  pixel = convtable[(bitvalue & 0xf0) >> 4];
	  bitvalue <<= 4;
	  bitcount -= 4;
	  break;
	case 1:
	  --bitcount;
	  if (((bitvalue & 0x80) ? 1 : 0) == transcolor) {
	      bitvalue <<= 1;
	      goto next;
	    }
	
	  pixel = convtable[(bitvalue & 0x80)? 1: 0];
	  bitvalue <<= 1;
	  break;
	}

	/* if((unsigned long)pixel != transcolor &&*/
	if (clip == CLIP_VISIBLE || GdClipPoint(psd, x, y))
	    psd->DrawPixel(psd, x, y, pixel);
#if 0
	/* fix: use clipmaxx to clip quicker*/
	else if(clip != CLIP_VISIBLE && !clipresult && x > clipmaxx) {
		x = maxx;
	}
#endif
next:
	if(x++ == maxx) {
		x = minx;
		y += yoff;
		height--;
		bitcount = 0;
		imagebits += extra;
	}
  }
  GdFixCursor(psd);
}

/*
 * Read a rectangular area of the screen.  
 * The color table is indexed row by row.
 */
void
GdReadArea(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
	MWPIXELVAL *pixels)
{
	MWCOORD 		row;
	MWCOORD 		col;

	if (width <= 0 || height <= 0)
		return;

	GdCheckCursor(psd, x, y, x+width-1, y+height-1);
	for (row = y; row < height+y; row++)
		for (col = x; col < width+x; col++)
			if (row < 0 || row >= psd->yvirtres ||
			    col < 0 || col >= psd->xvirtres)
				*pixels++ = 0;
			else *pixels++ = psd->ReadPixel(psd, col, row);

	GdFixCursor(psd);
}

/* Draw a rectangle of color values, clipping if necessary.
 * If a color matches the background color,
 * then that pixel is only drawn if the gr_usebg flag is set.
 *
 * The pixels are packed according to pixtype:
 *
 * pixtype		array of
 * MWPF_RGB		MWCOLORVAL (unsigned long)
 * MWPF_PIXELVAL	MWPIXELVAL (compile-time dependent)
 * MWPF_PALETTE		unsigned char
 * 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
 * MWPF_TRUECOLOR233	unsigned char
 *
 * NOTE: Currently, no translation is performed if the pixtype
 * is not MWPF_RGB.  Pixtype is only then used to determine the 
 * packed size of the pixel data, and is then stored unmodified
 * in a MWPIXELVAL and passed to the screen driver.  Virtually,
 * this means there's only three reasonable options for client
 * programs: (1) pass all data as RGB MWCOLORVALs, (2) pass
 * data as unpacked 32-bit MWPIXELVALs in the format the current
 * screen driver is running, or (3) pass data as packed values
 * in the format the screen driver is running.  Options 2 and 3
 * are identical except for the packing structure.
 */
void
GdArea(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height, void *pixels,
	int pixtype)
{
	unsigned char *PIXELS = pixels;	/* for ANSI compilers, can't use void*/
	long cellstodo;			/* remaining number of cells */
	long count;			/* number of cells of same color */
	long cc;			/* current cell count */
	long rows;			/* number of complete rows */
	MWCOORD minx;			/* minimum x value */
	MWCOORD maxx;			/* maximum x value */
	MWPIXELVAL savecolor;		/* saved foreground color */
	MWBOOL dodraw;			/* TRUE if draw these points */
	MWCOLORVAL rgbcolor = 0L;
	int pixsize;
	unsigned char r, g, b;

	minx = x;
	maxx = x + width - 1;

	/* Set up area clipping, and just return if nothing is visible */
	if ( GdClipArea(psd, minx, y, maxx, y + height - 1) == CLIP_INVISIBLE )
		return;

/* psd->DrawArea driver call temp removed, doesn't work with new blit routines*/
#if 0000
{
	driver_gc_t hwgc;
	int px1, px2, py1, py2, pw, ph, rx1, rx2, ry1, ry2;
#if DYNAMICREGIONS
	MWRECT *prc;
	extern MWCLIPREGION *clipregion;
#else
	MWCLIPRECT *prc;
	extern MWCLIPRECT cliprects[];
	extern int clipcount;
#endif

#if HAVE_T1LIB_SUPPORT | HAVE_FREETYPE_SUPPORT
	/* can't use drawarea driver in 16 bpp mode yet with font routines*/
	goto fallback;
#endif
	if ( !(psd->flags & PSF_HAVEOP_COPY) )
		goto fallback;

#if DYNAMICREGIONS
	prc = clipregion->rects;
	count = clipregion->numRects;
#else
	prc = cliprects;
	count = clipcount;
#endif

	hwgc.pixels = PIXELS;
	hwgc.src_linelen = width;
	hwgc.gr_usebg = gr_usebg;
	hwgc.bg_color = gr_background;

	while ( count-- > 0 ) {
#if DYNAMICREGIONS
		rx1 = prc->left;
		ry1 = prc->top;
		rx2 = prc->right;
		ry2 = prc->bottom;
#else
		/* New clip-code by Morten */
		rx1 = prc->x;
		ry1 = prc->y;
		rx2 = prc->x + prc->width;
		ry2 = prc->y + prc->height;
#endif

		/* Check if this rect intersects with the one we draw */
		px1 = x;
		py1 = y;
		px2 = x + width;
		py2 = y + height;
		if ( px1 < rx1 ) px1 = rx1;
		if ( py1 < ry1 ) py1 = ry1;
		if ( px2 > rx2 ) px2 = rx2;
		if ( py2 > ry2 ) py2 = ry2;

		pw = px2 - px1;
		ph = py2 - py1;

		if ( pw > 0 && ph > 0 ) {
			hwgc.dstx = px1;
			hwgc.dsty = py1;
			hwgc.dstw = pw;
			hwgc.dsth = ph;
			hwgc.srcx = px1 - x;
			hwgc.srcy = py1 - y;
			GdCheckCursor(psd,px1,py1,px1+pw-1,py1+ph-1);
			psd->DrawArea(psd,&hwgc,PSDOP_COPY);
		}
		prc++;
	}
	GdFixCursor(psd);
	return;
 fallback:
}
#endif /* if 0000 temp removed*/

	/* Calculate size of packed pixels*/
	switch(pixtype) {
	case MWPF_RGB:
		pixsize = sizeof(MWCOLORVAL);
		break;
	case MWPF_PIXELVAL:
		pixsize = sizeof(MWPIXELVAL);
		break;
	case MWPF_PALETTE:
	case MWPF_TRUECOLOR332:
	case MWPF_TRUECOLOR233:
		pixsize = sizeof(unsigned char);
		break;
	case MWPF_TRUECOLOR0888:
		pixsize = sizeof(unsigned long);
		break;
	case MWPF_TRUECOLOR888:
		pixsize = 3;
		break;
	case MWPF_TRUECOLOR565:
	case MWPF_TRUECOLOR555:
		pixsize = sizeof(unsigned short);
		break;
	default:
		return;
	}

  savecolor = gr_foreground;
  cellstodo = (long)width * height;
  while (cellstodo > 0) {
	/* read the pixel value from the pixtype*/
	switch(pixtype) {
	case MWPF_RGB:
		rgbcolor = *(MWCOLORVAL *)PIXELS;
		PIXELS += sizeof(MWCOLORVAL);
		gr_foreground = GdFindColor(rgbcolor);
		break;
	case MWPF_PIXELVAL:
		gr_foreground = *(MWPIXELVAL *)PIXELS;
		PIXELS += sizeof(MWPIXELVAL);
		break;
	case MWPF_PALETTE:
	case MWPF_TRUECOLOR332:
	case MWPF_TRUECOLOR233:
		gr_foreground = *PIXELS++;
		break;
	case MWPF_TRUECOLOR0888:
		gr_foreground = *(unsigned long *)PIXELS;
		PIXELS += sizeof(unsigned long);
		break;
	case MWPF_TRUECOLOR888:
		r = *PIXELS++;
		g = *PIXELS++;
		b = *PIXELS++;
		gr_foreground = (MWPIXELVAL)MWRGB(r, g, b);
		break;
	case MWPF_TRUECOLOR565:
	case MWPF_TRUECOLOR555:
		gr_foreground = *(unsigned short *)PIXELS;
		PIXELS += sizeof(unsigned short);
		break;
	}
	dodraw = (gr_usebg || (gr_foreground != gr_background));
	count = 1;
	--cellstodo;

	/* See how many of the adjacent remaining points have the
	 * same color as the next point.
	 *
	 * NOTE: Yes, with the addition of the pixel unpacking,
	 * it's almost slower to look ahead than to just draw
	 * the pixel...  FIXME
	 */
	while (cellstodo > 0) {
		switch(pixtype) {
		case MWPF_RGB:
			if(rgbcolor != *(MWCOLORVAL *)PIXELS)
				goto breakwhile;
			PIXELS += sizeof(MWCOLORVAL);
			break;
		case MWPF_PIXELVAL:
			if(gr_foreground != *(MWPIXELVAL *)PIXELS)
				goto breakwhile;
			PIXELS += sizeof(MWPIXELVAL);
			break;
		case MWPF_PALETTE:
		case MWPF_TRUECOLOR332:
		case MWPF_TRUECOLOR233:
			if(gr_foreground != *(unsigned char *)PIXELS)
				goto breakwhile;
			++PIXELS;
			break;
		case MWPF_TRUECOLOR0888:
			if(gr_foreground != *(unsigned long *)PIXELS)
				goto breakwhile;
			PIXELS += sizeof(unsigned long);
			break;
		case MWPF_TRUECOLOR888:
			r = *(unsigned char *)PIXELS;
			g = *(unsigned char *)(PIXELS + 1);
			b = *(unsigned char *)(PIXELS + 2);
			if(gr_foreground != (MWPIXELVAL)MWRGB(r, g, b))
				goto breakwhile;
			PIXELS += 3;
			break;
		case MWPF_TRUECOLOR565:
		case MWPF_TRUECOLOR555:
			if(gr_foreground != *(unsigned short *)PIXELS)
				goto breakwhile;
			PIXELS += sizeof(unsigned short);
			break;
		}
		++count;
		--cellstodo;
	}
breakwhile:

	/* If there is only one point with this color, then draw it
	 * by itself.
	 */
	if (count == 1) {
		if (dodraw)
			drawpoint(psd, x, y);
		if (++x > maxx) {
			x = minx;
			y++;
		}
		continue;
	}

	/* There are multiple points with the same color. If we are
	 * not at the start of a row of the rectangle, then draw this
	 * first row specially.
	 */
	if (x != minx) {
		cc = count;
		if (x + cc - 1 > maxx)
			cc = maxx - x + 1;
		if (dodraw)
			drawrow(psd, x, x + cc - 1, y);
		count -= cc;
		x += cc;
		if (x > maxx) {
			x = minx;
			y++;

⌨️ 快捷键说明

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