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

📄 gdi.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
// 功能描述:
//	将设备相关的颜色值转化为设备无关的颜色值
// 引用: 
//	
// ************************************************

DWORD _Gdi_UnrealizeColor( DWORD dwRealizeColor, LPCDWORD lpPal, UINT uiPalNum, UINT uiSrcColorType )
{
	DWORD dwRetv;

	if( uiSrcColorType == PAL_INDEX )
		dwRetv = lpPal[dwRealizeColor];	// 颜色类型为基于色板的索引值
	else if( uiSrcColorType == PAL_BITFIELD )
	{	//颜色类型bit位组合, lpPal里保存有三个 r g b 的 mask值
		int leftShift, rightShift;
		DWORD dwColorMask;

		dwRetv = 0;
		for( rightShift = 24; rightShift >= 0 && uiPalNum; rightShift -= 8, uiPalNum--, lpPal++ )
		{
			dwColorMask = *lpPal;
			//得到 需要移位的值
			for( leftShift = 32; dwColorMask; leftShift-- )
				dwColorMask >>= 1;

			dwRetv |= ( ( dwRealizeColor & *lpPal ) << leftShift ) >> rightShift;
		}
	}
	else
		dwRetv = 0;
	return dwRetv;
}


// **************************************************
// 声明:static DWORD _Gdi_RealizeColor( COLORREF clRgbColor, DWORD * lpPal, UINT uiPalNum, UINT uiDestColorType )
// 参数:
// 	IN clRgbColor - 设备无关的颜色值
//	IN uiDestColorType - 颜色类型
//	IN lpPal - 色板指针
//	IN uiPalNum - 色板项目数
// 返回值:
//	假如成功,返回设备相关的颜色值;否则,返回0
// 功能描述:
//	将设备无关的颜色值转化为设备相关的颜色值
// 引用: 
//	
// ************************************************

// return dest format

DWORD _Gdi_RealizeColor( COLORREF clRgbColor, LPCDWORD lpPal, UINT uiPalNum, UINT uiDestColorType )
{
	DWORD dwRetv;

	if( uiDestColorType == PAL_INDEX )
	{	// 颜色类型为基于色板的索引值
		long minDiff, curDiff;
		UINT uiPalCount = uiPalNum;
		

		minDiff = 0x7fffffffl;
		dwRetv = uiPalNum;
			
		for( ; uiPalCount; uiPalCount--, lpPal++ )
		{
			if( clRgbColor == *lpPal )
			{
				dwRetv = uiPalCount;
				break;
			}
			else
			{  //得到距离
				LPBYTE lpbSrc = (LPBYTE)&clRgbColor;
				LPBYTE lpbDest = (LPBYTE)lpPal;
				long lDiff;

				curDiff = *lpbSrc++ - *lpbDest++;
				curDiff *= curDiff;
				lDiff = *lpbSrc++ - *lpbDest++;
				curDiff += lDiff * lDiff;
				lDiff = *lpbSrc - *lpbDest;
				curDiff += lDiff * lDiff;				
			}
			if( curDiff < minDiff )
			{	//得到最短距离
			    minDiff = curDiff;
			    dwRetv = uiPalCount;
			}
		}
		dwRetv = uiPalNum - dwRetv;
	}
	else if( uiDestColorType == PAL_BITFIELD )
	{	//颜色类型bit位组合, lpPal里保存有三个 r g b 的 mask值
		int leftShift, rightShift;
		DWORD dwColorMask;

		dwRetv = 0;
		for( leftShift = 24; leftShift >= 0 && uiPalNum; leftShift -= 8, uiPalNum--, lpPal++ )
		{
			dwColorMask = *lpPal;
			//得到 需要移位的值
			for( rightShift = 32; dwColorMask; rightShift-- )
				dwColorMask >>= 1;

			dwRetv |= ( ( clRgbColor << leftShift ) >> rightShift ) & *lpPal;
		}
	}
	else
		dwRetv = 0;
	return dwRetv;
}

// **************************************************
// 声明:BOOL PixelTransfer( 
//							_LPGDCDATA lpdcDest,//_LPCDISPLAYDRV lpDestDispDrv,
//							_LPPIXELDATA lpPixDest,
//							LPRECT lprcDest,
//							_LPGDCDATA lpdcSrc,//_LPCDISPLAYDRV lpSrcDispDrv,
//							_LPPIXELDATA lpPixSrc,
//							LPRECT lprcSrc,
//							_LPPIXELDATA lpPixMask,   // if bltmask , it is valid
//							UINT uiMaskRopSrc,        // if bltmask , it is valid
//							UINT uiMaskRopDest        // if bltmask , it is valid
//							DWORD clrTransparent			// if == -1 , menau not transparent option invalid
//						 )

// 参数:
//	IN lpdcDest - 目标DC对象  //lpDestDispDrv - 目标驱动程序接口
//	IN lpPixDest - 目标点结构指针
//	IN lprcDest - 目标矩形
//	IN lpdcSrc - 源DC对象  //lpSrcDispDrv - 源驱动程序接口
//	IN lpPixSrc - 源点结构指针
//	IN lprcSrc - 源矩形
//	IN lpPixMask - 屏蔽点(假如有屏蔽位传送功能)   // if bltmask , it is valid
//	IN uiMaskRopSrc - 对源的屏蔽操作(假如有屏蔽位传送功能)       // if bltmask , it is valid
//	IN uiMaskRopDest - 对目标屏蔽操作 (假如有屏蔽位传送功能)      // if bltmask , it is valid
//	IN clrTransparent - 透明颜色,用于透明传输(如果为-1,非透明)	// if == -1 , not transparent option
//						假如 (clTransparent & 0x80000000) != 0, 
//						则说明 clTransparent 是表示一个在源位图的设备相关的颜色值,否则,是一个RGB值
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	在两个不同的位图格式之间传送位图
// 引用: 
//	
// ************************************************
#define DEBUG_PIXEL_TRANSFER 0
static BOOL PixelTransfer( _LPGDCDATA lpdcDest,//_LPCDISPLAYDRV lpDestDispDrv,
						   _LPPIXELDATA lpPixDest,
						   LPRECT lprcDest,

						   _LPGDCDATA lpdcSrc,//_LPCDISPLAYDRV lpSrcDispDrv,
						   _LPPIXELDATA lpPixSrc,
						   LPRECT lprcSrc,

						   _LPPIXELDATA lpPixMask,   // if bltmask , it is valid
						   UINT uiMaskRopSrc,        // if bltmask , it is valid
						   UINT uiMaskRopDest,        // if bltmask , it is valid
						   DWORD clrTransparent			// if not -1 , invalid
						 )
{
	_LPCDISPLAYDRV lpDestDispDrv = lpdcDest->lpDispDrv;
	_LPCDISPLAYDRV lpSrcDispDrv = lpdcSrc->lpDispDrv;
	int x, y;
	int width, height;
	int xSrcOffset, ySrcOffset, xDestOffset, yDestOffset;
	COLORREF clrPrev = -1;
	COLORREF clrCur, clrRgb = 0;
	_LPBITMAP_DIB lpSrcDIB = (_LPBITMAP_DIB)lpPixSrc->lpDestImage;
	WORD bmType = lpSrcDIB->bitmap.bmFlags & BF_DIB;
	DWORD * lpPal;
	UINT uiPalNum;
	int yDir = 1;
	UINT clrRealTransparent = -1;	//设备相关的颜色值
	
	if( bmType )
	{	//源位图为DIB格式
		lpPal = (DWORD*)&lpSrcDIB->palEntry[0];
		uiPalNum = lpSrcDIB->biClrUsed;
		yDir = lpSrcDIB->biDir;
		//颜色值为指向调色板的索引值
		if( lpSrcDIB->biCompression == BI_RGB )
		    bmType = PAL_INDEX;
		else if( lpSrcDIB->biCompression == BI_BITFIELDS )
			bmType = PAL_BITFIELD;  //颜色值为位图域
		else
			return FALSE;
	}
	//目标宽度和高度
	width = lprcDest->right - lprcDest->left;
	height = lprcDest->bottom - lprcDest->top;

	//RETAILMSG( 1, ( "PixelTransfer.\r\n" ) );
	//源起始位置在位图中的偏移
	xSrcOffset = lprcSrc->left;
	ySrcOffset = lprcSrc->top;
	//目标起始位置在位图中的偏移
	xDestOffset = lprcDest->left;
	yDestOffset = lprcDest->top;
	if( clrTransparent != -1 )
	{	//需要透明传输
		if( clrTransparent & TB_DEV_COLOR )
		{	//clrTransparent 是设备相关的值
			clrRealTransparent = clrTransparent & (~TB_DEV_COLOR);
		}
		else
		{	// clrTransparent是RGB值,将其转到设备相关的值
			if( bmType && uiPalNum )
			{
				clrRealTransparent = _Gdi_RealizeColor( clrTransparent, lpPal, uiPalNum, bmType );
			}
			else  //get default 
				clrRealTransparent = lpSrcDispDrv->lpRealizeColor( clrTransparent, NULL, 0, 0 );
		}
	}
		
	for( y = 0; y < height; y++ )
	{	// 每一行
		for( x = 0; x < width; x++ )
		{	// 每一列
			//2004.07-01 - remove, 多判断
			//if( bmType && yDir < 0 )
			if( yDir < 0 )	
			//
			{
			    lpPixSrc->y = lpSrcDIB->bitmap.bmHeight - (y + ySrcOffset) - 1;
			}
			else
			{
			    lpPixSrc->y = y + ySrcOffset;
			}
		    lpPixSrc->x = x + xSrcOffset;
			//得到源点设备相关颜色值
			clrCur = lpSrcDispDrv->lpGetPixel( lpPixSrc );
			if( clrCur != clrRealTransparent )
			{	//如果非透明色,则画之
				if( clrCur != clrPrev )
				{	//与之前的颜色值相同吗,如果不相同,则将其转化为
					//设备无关的值
					if( bmType && uiPalNum )
					{
						clrRgb = _Gdi_UnrealizeColor( clrCur, lpPal, uiPalNum, bmType );  
					}
					else
						clrRgb = lpSrcDispDrv->lpUnrealizeColor( clrCur, NULL, 0, 0 );
				}
				lpPixDest->x = x + xDestOffset;
				lpPixDest->y = y + yDestOffset;
				if( clrCur != clrPrev )
				{	//得到目标相关的值
					lpPixDest->color = lpDestDispDrv->lpRealizeColor( clrRgb, lpdcDest->lpdwPal, lpdcDest->wPalNumber, lpdcDest->wPalFormat );
				}
				//如果需要屏蔽操作,得到对应x,y坐标的屏蔽位
				if( lpPixMask )
				{
					lpPixMask->x = lpPixSrc->x;
					lpPixMask->y = lpPixSrc->y;
					if( _drvDisplay1BPP.lpGetPixel( lpPixMask ) )
						lpPixMask->rop = uiMaskRopSrc;
					else
						lpPixMask->rop = uiMaskRopDest;
				}
				//写点到目标位图
				lpDestDispDrv->lpPutPixel( lpPixDest );
				//缓存当前的颜色值
				clrPrev = clrCur;
			}
		}
	}
	return TRUE;
}


// **************************************************
// 声明:BOOL WINAPI WinGdi_BitBlt(
//							HDC hdcDest - 目标DC
//							int xDest - 目标x坐标
//							int yDest - 目标x坐标
//							int width, 
//							int height,
//							HDC hdcSrc, 
//							int xSrc, 
//							int ySrc, 
//							DWORD dwRop )
// 参数:
//	IN hdcDest - 目标DC
//	IN xDest - 目标矩形左上角X坐标
//	IN yDest - 目标矩形左上角Y坐标
//	IN width - 目标矩形宽度
//	IN height - 目标矩形高度
//	IN hdcSrc - 源DC
//	IN xSrc - 源矩形左上角X坐标
//	IN ySrc - 源矩形左上角Y坐标
//	IN dwRop - 光栅操作码,包括:
//			SRCCOPY-拷贝源矩形到目标矩形
//			SRCAND--源数据与目标数据做与运算(AND)
//			SRCINVERT-源数据与目标数据做异或运算(XOR)
//			SRCPAINT-源数据与目标数据做或运算(OR)
//			PATCOPY-拷贝模板到目标矩形
//			BLACKNESS-用黑色填充目标矩形
//			WHITENESS-用白色填充目标矩形
//			PATINVERT-模板颜色与目标颜色做异或运算(XOR)
//			DSTINVERT-反转目标颜色
//			NOTSRCCOPY-拷贝反转的源颜色到目标矩形 
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	从源DC向目标DC进行位图传送
// 引用: 
//	系统API
// ************************************************
						   
BOOL WINAPI WinGdi_BitBlt(HDC hdcDest, int xDest, int yDest, int width, int height,
				HDC hdcSrc, int xSrc, int ySrc, DWORD dwRop )
{
    _LPGDCDATA lpdcDest = _GetSafeDrawPtr( hdcDest );//得到目标DC对象指针
    _LPGDCDATA lpdcSrc = _GetSafeDrawPtr( hdcSrc );//得到源DC对象指针
    _LPRGNDATA lprgn;
    _LPRECTNODE lprnNode;
    _BLKBITBLT blt;
    RECT rcSrc, rcTemp, rcClip, rcDest;
    int xoff, yoff, xSrcOff, ySrcOff;

    if( lpdcDest && lpdcSrc && lpdcDest->lpDispDrv )
    {	
        _LPCDISPLAYDRV lpDispDrv = lpdcDest->lpDispDrv;  //目标DC驱动程序
		lprgn = _GetHRGNPtr( lpdcDest->hrgn );
		//源/目标位图数据结构
        blt.lpDestImage = _GetHBITMAPPtr( lpdcDest->hBitmap );
        blt.lpSrcImage = _GetHBITMAPPtr( lpdcSrc->hBitmap );
		//当前刷子
        blt.lpBrush = &lpdcSrc->brushAttrib;

		if( !(lprgn && blt.lpDestImage && blt.lpSrcImage && blt.lpBrush) )
			goto _ERROR;

        blt.lprcSrc = &rcSrc;
        blt.lprcDest = &rcDest;
        blt.dwRop = dwRop;
        // in bitblt, mono bitmap , 1 mean backcolor, 0 mean textcolor
        blt.solidColor = lpdcDest->backColor;
        blt.solidBkColor = lpdcDest->textColor;
        blt.backMode = lpdcDest->backMode;
		//当前源DC在显示设备上的偏移
        xSrcOff = XOFFSET( lpdcSrc );
        ySrcOff = YOFFSET( lpdcSrc );
		//转换源坐标到设备坐标
        rcTemp.left = xSrc;
        rcTemp.top = ySrc;
        rcTemp.right = rcTemp.left + width;
        rcTemp.bottom = rcTemp.top + height;
        OffsetRect( &rcTemp, xSrcOff, ySrcOff );
		//当前目标DC在显示设备上的偏移
        xoff = XOFFSET( lpdcDest );
        yoff = YOFFSET( lpdcDest );
		//转换目标坐标到设备坐标
        rcClip.left = xDest;
        rcClip.top = yDest;
        rcClip.right = rcClip.left + width;
        rcClip.bottom = rcClip.top + height;
        OffsetRect( &rcClip, xoff, yoff );
		//得到源和目标的共同区域
        if( rcTemp.left < 0 )
        {
            rcClip.left -= rcTemp.left;
        }
        if( rcTemp.top < 0 )
        {
            rcClip.top -= rcTemp.top;
        }
        if( rcTemp.right > blt.lpSrcImage->bmWidth )
        {
            rcClip.right -= rcTemp.right - blt.lpSrcImage->bmWidth;
        }
        if( rcTemp.bottom > blt.lpSrcImage->bmHeight )
        {
            rcClip.bottom -= rcTemp.bottom - blt.lpSrcImage->bmHeight;
        }
		//源坐标在目标上的投射点相对偏移
        xoff = xSrc + XOFFSET( lpdcSrc ) - xDest - xoff;
        yoff = ySrc + YOFFSET( lpdcSrc ) - yDest - yoff;
		//目标裁剪域
        lprnNode = lprgn->lpNodeFirst;

        if( blt.lpDestImage->bmBits == blt.lpSrcImage->bmBits )
        {	//相同的显示面
			//遍历每一个裁剪域,如果可显示则绘制
            while( lprnNode )
            {	//得到内交区域
                if( IntersectRect( &rcDest, &rcClip, &lprnNode->rect ) )
                {
                    rcSrc = rcDest;
                    OffsetRect( &rcSrc, xoff, yoff );
					//设置绘制方向为从左到右,从上到下
                    blt.yPositive = 1;
                    blt.xPositive = 1;
					//
                    if( IntersectRect( &rcTemp, &rcSrc, &rcDest ) )
                    {	//因为是相同的显示面,所以必须确定正确的拷贝顺序
						//这里表示目标矩形与源矩形有重叠并且必须反向拷贝

⌨️ 快捷键说明

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