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

📄 gdi.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
                        if( rcSrc.top  < blt.lprcDest->top )
                            blt.yPositive = 0;	//从右到左
                        if( rcSrc.left  < blt.lprcDest->left )
                            blt.xPositive = 0;	//从下到上
                    }
                    lpDispDrv->lpBlkBitBlt( &blt );	//绘制到显示面
                }
                lprnNode = lprnNode->lpNext;//下一个裁剪区
            }
        }
        else
        {	//非同一个显示面
			if( ( blt.lpDestImage->bmBitsPixel == blt.lpSrcImage->bmBitsPixel ||
				  blt.lpSrcImage->bmBitsPixel == 1 ) )
			{	//数据格式相同或者源格式是黑白位图格式
				
				//设置绘制方向为从左到右,从上到下
				blt.yPositive = 1;
				blt.xPositive = 1;				
				//遍历每一个裁剪域,如果可显示则绘制
				while( lprnNode )
				{	//得到内交区域
					if( IntersectRect( &rcDest, &rcClip, &lprnNode->rect ) )
					{
						rcSrc = rcDest;
						OffsetRect( &rcSrc, xoff, yoff );
						lpDispDrv->lpBlkBitBlt( &blt );	//绘制到显示面
					}
					lprnNode = lprnNode->lpNext;	//下一个裁剪区
				}
			}
			else if( lpdcSrc->lpDispDrv )
			{   // 不同的位图格式, 需要对每一个点进行处理 ,点对点拷贝 pixel -> pixel
				// 这个将会大量的处理时间!
				_LPCDISPLAYDRV lpSrcDispDrv = lpdcSrc->lpDispDrv;
				_PIXELDATA pxSrc, pxDest;
				
	            pxSrc.lpDestImage = blt.lpSrcImage;
	            pxSrc.pattern = 0xff;
	            pxSrc.rop = R2_NOP;// read only

				pxDest.lpDestImage = blt.lpDestImage;
	            pxDest.pattern = 0xff;

				switch( dwRop )
				{
				case SRCCOPY:  // dest = src
					pxDest.rop = R2_COPYPEN;
					break;
				case SRCAND:   // dest = src & dst
					pxDest.rop = R2_MASKPEN;
					break;
				case SRCINVERT:  // dest = src ^ dst
					pxDest.rop = R2_MASKPEN;
					break;
				case SRCPAINT:  // dest = src | dst
					pxDest.rop = R2_MERGEPEN;
					break;
				case NOTSRCCOPY:  // dest = ~src
					pxDest.rop = R2_NOTCOPYPEN;
					break;
				case MERGEPAINT:  // dest = (~src) | dest
					pxDest.rop = R2_MERGENOTPEN;
					break;
				default:
					SetLastError( ERROR_INVALID_PARAMETER );
					goto _ERROR;
				}
				//遍历每一个裁剪域,如果可显示则绘制
				while( lprnNode )
				{	//得到内交区域
					if( IntersectRect( &rcDest, &rcClip, &lprnNode->rect ) )
					{
						rcSrc = rcDest;
						OffsetRect( &rcSrc, xoff, yoff );
						//对每个点进行转换
						//PixelTransfer( lpDispDrv, &pxDest, &rcDest, lpSrcDispDrv, &pxSrc, &rcSrc, NULL, 0, 0, -1 );
						PixelTransfer( lpdcDest, &pxDest, &rcDest, lpdcSrc, &pxSrc, &rcSrc, NULL, 0, 0, -1 );
					}
					lprnNode = lprnNode->lpNext;//下一个裁剪区
				}
			}
        }
        return TRUE;
    }
_ERROR:
    return FALSE;
}



// **************************************************
// 声明:BOOL WINAPI WinGdi_TransparentBlt(
//							HDC hdcDest - 目标DC
//							int xDest - 目标x坐标
//							int yDest - 目标x坐标
//							int width, 
//							int height,
//							HDC hdcSrc, 
//							int xSrc, 
//							int ySrc, 
//							int widthSrc,
//							int heightSrc,
//							DWORD clTransparent )
// 参数:
//	IN hdcDest - 目标DC
//	IN xDest - 目标矩形左上角X坐标
//	IN yDest - 目标矩形左上角Y坐标
//	IN width - 目标矩形宽度
//	IN height - 目标矩形高度
//	IN hdcSrc - 源DC
//	IN xSrc - 源矩形左上角X坐标
//	IN ySrc - 源矩形左上角Y坐标
//	IN width - 源矩形宽度
//	IN height - 源矩形高度
//	IN clTransparent - 透明色,假如 (clTransparent & 0x80000000) != 0, 
//				则说明 clTransparent 是表示一个在源位图的设备相关的颜色值,否则,是一个RGB值
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	从源DC向目标DC进行透明位图传送
// 引用: 
//	系统API
// ************************************************
						   
BOOL WINAPI WinGdi_TransparentBlt(HDC hdcDest, 
								  int xDest, 
								  int yDest, 
								  int width, 
								  int height,
								  HDC hdcSrc,
								  int xSrc, 
								  int ySrc, 
								  int widthSrc,
								  int heightSrc,
								  DWORD clTransparent )
{
    _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 = NULL;//&lpdcSrc->brushAttrib;

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

        blt.lprcSrc = &rcSrc;
        blt.lprcDest = &rcDest;
        blt.dwRop = SRCCOPY;
        // in bitblt, mono bitmap , 1 mean backcolor, 0 mean textcolor
        blt.solidColor = lpdcSrc->lpDispDrv->lpRealizeColor( clTransparent, lpdcSrc->lpdwPal, lpdcSrc->wPalNumber, lpdcSrc->wPalFormat );//lpdcDest->backColor;
        blt.solidBkColor = lpdcDest->textColor;
        blt.backMode = TRANSPARENT;//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;
		/* supprt later
        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 ) )
                    {	//因为是相同的显示面,所以必须确定正确的拷贝顺序
						//这里表示目标矩形与源矩形有重叠并且必须反向拷贝
                        if( rcSrc.top  < blt.lprcDest->top )
                            blt.yPositive = 0;	//从右到左
                        if( rcSrc.left  < blt.lprcDest->left )
                            blt.xPositive = 0;	//从下到上
                    }
                    lpDispDrv->lpBlkBitTransparentBlt( &blt );	//绘制到显示面
                }
                lprnNode = lprnNode->lpNext;//下一个裁剪区
            }
        }
        else
		*/
        {	//非同一个显示面
			/*	//support later
			if( ( blt.lpDestImage->bmBitsPixel == blt.lpSrcImage->bmBitsPixel ||
				  blt.lpSrcImage->bmBitsPixel == 1 ) )
			{	//数据格式相同或者源格式是黑白位图格式
				
				//设置绘制方向为从左到右,从上到下
				blt.yPositive = 1;
				blt.xPositive = 1;				
				//遍历每一个裁剪域,如果可显示则绘制
				while( lprnNode )
				{	//得到内交区域
					if( IntersectRect( &rcDest, &rcClip, &lprnNode->rect ) )
					{
						rcSrc = rcDest;
						OffsetRect( &rcSrc, xoff, yoff );
						lpDispDrv->lpBlkBitTransparentBlt( &blt );	//绘制到显示面
					}
					lprnNode = lprnNode->lpNext;	//下一个裁剪区
				}
			}
			else if( lpdcSrc->lpDispDrv )
			*/
			{   // 不同的位图格式, 需要对每一个点进行处理 ,点对点拷贝 pixel -> pixel
				// 这个将会大量的处理时间!
				_LPCDISPLAYDRV lpSrcDispDrv = lpdcSrc->lpDispDrv;
				_PIXELDATA pxSrc, pxDest;
				
	            pxSrc.lpDestImage = blt.lpSrcImage;
	            pxSrc.pattern = 0xff;
	            pxSrc.rop = R2_NOP;// read only

				pxDest.lpDestImage = blt.lpDestImage;
	            pxDest.pattern = 0xff;
				pxDest.rop = R2_COPYPEN;

				//遍历每一个裁剪域,如果可显示则绘制
				while( lprnNode )
				{	//得到内交区域
					if( IntersectRect( &rcDest, &rcClip, &lprnNode->rect ) )
					{
						rcSrc = rcDest;
						OffsetRect( &rcSrc, xoff, yoff );
						//对每个点进行转换
						PixelTransfer( lpdcDest, &pxDest, &rcDest, lpdcSrc, &pxSrc, &rcSrc, NULL, 0, 0, clTransparent );
					}
					lprnNode = lprnNode->lpNext;//下一个裁剪区
				}
			}
        }
        return TRUE;
    }
_ERROR:
    return FALSE;
}


// **************************************************
// 声明:
// 参数:
// 	IN 
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	
// 引用: 
//	
// ************************************************

extern int _WinGdi_ConvertImageColorValue( 
									_LPCDISPLAYDRV lpDrv,
								    _LPBITMAP_DIB lpDestImage,  // dest image data
									LPCRECT lprcDestClip,
									CONST BITMAPINFO * lpbi,// src image info
									LPCRECT lprcSrcClip,
								    DWORD dwStartScanLine,  // src start scan line
                                    DWORD dwScanLineNum, 
                                    DWORD dwScanLineWidth,
                                    LPCBYTE lpbData,// src bitmap bits data
								    int fuColorUse   // use src's RGB or PAL
									);

// **************************************************
// 声明:int WINAPI WinGdi_SetDIBitsToDevice(
//						 HDC hdc,                 // handle to DC
//						 int xDest,               // x-coord of destination upper-left corner
//						 int yDest,               // y-coord of destination upper-left corner 
//						 DWORD dwWidth,           // source rectangle width
//						 DWORD dwHeight,          // source rectangle height
//						 int xSrc,                // x-coord of source lower-left corner
//						 int ySrc,                // y-coord of source lower-left corner
//						 UINT uStartScan,         // first scan line in array
//						 UINT cScanLines,         // number of scan lines
//						 CONST VOID *lpvBits,     // array of DIB bits
//						 CONST BITMAPINFO *lpbmi, // bitmap information
//						 UINT fuColorUse          // RGB or palette indexes
//						 )
// 参数:
//	IN hdc – 目标DC
//	IN xDest – 输出到目标矩形的x坐标
//	IN yDest – 输出到目标矩形的y坐标
//	IN dwWidth – 输出到目标矩形的宽度
//	IN dwHeight – 输出到目标矩形的高度
//	IN xSrc – 源DIB点数据的开始x位置
//	IN ySrc – 源DIB点数据的开始y位置
//	IN uStartScan – DIB数据的开始扫描行
//	IN cScanLines – DIB数据的扫描行行数
//	IN lpvBits – 包含DIB数据的指针
//	IN lpbmi - BITMAPINFO结构指针,用于描述lpvBits的数据信息
//	IN fuColorUse - 说明BITMAPINFO结构成员bmiColors的类型:
//					DIB_PAL_COLORS – bmiColors为16索引数组,每一个索引值指向当前hdc的调色板的对应项 
//					DIB_RGB_COLORS – bmiColors为红、绿、蓝颜色数组
// 返回值:
//	假如成功,返回实际拷贝的扫描行数;否则,返回0
// 功能描述:
//	设置DIB数据到目标设备对应的矩形里
// 引用: 
//	系统API
// ************************************************
									
int WINAPI WinGdi_SetDIBitsToDevice(
						 HDC hdc,                 // handle to DC

						 int xDest,               // x-coord of destination upper-left corner
						 int yDest,               // y-coord of destination upper-left corner 
						 DWORD dwWidth,           // source rectangle width
						 DWORD dwHeight,          // source rectangle height
						 int xSrc,                // x-coord of source lower-left corner
						 int ySrc,                // y-coord of source lower-left corner

						 UINT uStartScan,         // first scan line in array
						 UINT cScanLines,         // number of scan lines
						 CONST VOID *lpvBits,     // array of DIB bits
						 CONST BITMAPINFO *lpbmi, // bitmap information
						 UINT fuColorUse          // RGB or palette indexes
						 )

{	// 得到DC对象指针
    _LPGDCDATA lpdc = _GetSafeDrawPtr( hdc );

	if( lpdc && lpbmi )
	{
        _LPBITMAPDATA lpImage = NULL;//
		_LPCDISPLAYDRV lpDrv;
		UINT uiHeight = ABS(lpbmi->bmiHeader.biHeight);
		//得到DC显示面
		lpImage = _GetHBITMAPPtr( lpdc->hBitmap );		

	    lpDrv = lpdc->lpDispDrv;
	    if( lpDrv == NULL )
		    return 0;	//非法

		if( lpImage )
		{
			int iDir;
			// 源扫描行字节数
			int iScanLineBytes = (lpbmi->bmiHeader.biBitCount * lpbmi->bmiHeader.biWidth + 31) / 32 * 4;  // align to dword
			int iMinWidth, iMinHeight;
			RECT rcSrc, rcDst, rcTemp;
			int xoff = XOFFSET( lpdc );
			int yoff = YOFFSET( lpdc );
			_LPRGNDATA lprgn;
			_LPRECTNODE lprnNode;
            //颜色数据是从底到顶排列的吗 ? 			
			if( lpbmi->bmiHeader.biHeight > 0 )
				iDir = -1;	//是从底到顶排列的
			else

⌨️ 快捷键说明

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