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

📄 gdi.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
				iDir = 1;
			//得到目标和源的相交区域		
			rcDst.left = xDest;
			rcDst.top = yDest;
			rcDst.right = xDest + dwWidth;
			rcDst.bottom = yDest + dwHeight;
			OffsetRect( &rcDst, xoff, yoff );
			rcTemp.left = 0;
			rcTemp.top = 0;
			rcTemp.right = lpImage->bmWidth;
			rcTemp.bottom = lpImage->bmHeight;
			//目标区域与目标显示面相交
			if( IntersectRect( &rcDst, &rcDst, &rcTemp ) )
			{	//有相交区域
				dwWidth = rcDst.right - rcDst.left;
				dwHeight = rcDst.bottom - rcDst.top;
				
				rcSrc.left = xSrc;
				rcSrc.top = ySrc;
				rcSrc.right = xSrc + dwWidth;
				rcSrc.bottom = ySrc + dwHeight;
				rcTemp.left = 0;
				rcTemp.top = 0;
				rcTemp.right = lpbmi->bmiHeader.biWidth;
				rcTemp.bottom = uiHeight;
				//源区域与源显示面矩形相交
				if( IntersectRect( &rcSrc, &rcSrc, &rcTemp ) )
				{	//有相交区域
					iMinWidth = rcSrc.right - rcSrc.left;
					iMinHeight = rcSrc.bottom - rcSrc.top;
					
					rcDst.right = rcDst.left + iMinWidth;
					rcDst.bottom = rcDst.top + iMinHeight;
				}
				else
					goto _return;	//没有相交区域,退出
			}
			else
				goto _return;	//没有相交区域,退出
			xoff = xSrc - xDest - xoff;
			yoff = ySrc - yDest - yoff;
			//得到目标的裁剪区域
			lprgn = _GetHRGNPtr( lpdc->hrgn );
			ASSERT( lprgn );
			//遍历目标的所有裁剪区域,如果有可绘制区域,则输出
			lprnNode = lprgn->lpNodeFirst;
			while( lprnNode )
			{
				RECT rcDest;
				if( IntersectRect( &rcDest, &rcDst, &lprnNode->rect ) )
				{	//相交
					rcSrc = rcDest;
					OffsetRect( &rcSrc, xoff, yoff );
					//转换位图数据到目标显示面
					_WinGdi_ConvertImageColorValue( 
						lpDrv,
						(_LPBITMAP_DIB)lpImage,
						&rcDest,
						lpbmi,
						&rcSrc,
						uStartScan,
						cScanLines,
						iScanLineBytes,
						lpvBits,
						fuColorUse );
				}
				lprnNode = lprnNode->lpNext;	//下一个裁剪区
			}
		}
	}
_return:
	return 0;
}

// **************************************************
// 声明:BOOL WINAPI WinGdi_Line( HDC hdc, int x0, int y0, int x1, int y1 )
// 参数:
//	IN hdc - DC句柄
//	IN x0 - 起点坐标X
//	IN y0 - 起点坐标Y
//	IN x1 - 结束坐标X
//	IN y1 - 结束坐标Y
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	画线段
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI WinGdi_Line( HDC hdc, int x0, int y0, int x1, int y1 )
{
    POINT pt;
	BOOL retv;

    WinGdi_MoveTo( hdc, x0, y0, &pt );
    retv = WinGdi_LineTo( hdc, x1, y1 );
    WinGdi_MoveTo( hdc, pt.x, pt.y, 0 );
    return retv;
}

// **************************************************
// 声明:COLORREF WINAPI WinGdi_GetPixel( HDC hdc, int x, int y )
// 参数:
//	IN hdc - DC句柄
//	IN x - 点坐标X
//	IN y - 点坐标Y
// 返回值:
//	成功:返回RGB值
//	否则:返回CLR_INVALID
// 功能描述:
//	得到点颜色值
// 引用: 
//	系统API
// ************************************************

COLORREF WINAPI WinGdi_GetPixel( HDC hdc, int x, int y )
{
    _LPGDCDATA lpdc = _GetSafeDrawPtr( hdc );

    if( lpdc && lpdc->lpDispDrv )
    {
        _PIXELDATA pixelData;
        pixelData.lpDestImage = _GetHBITMAPPtr( lpdc->hBitmap );
		//转化到目标DC设备坐标
        pixelData.x = x + XOFFSET( lpdc );
        pixelData.y = y + YOFFSET( lpdc );
		//需要的点是否在显示面上 ?
        if( WinRgn_PtInRegion( lpdc->hrgn, pixelData.x, pixelData.y ) )
            return lpdc->lpDispDrv->lpUnrealizeColor( lpdc->lpDispDrv->lpGetPixel( &pixelData ), lpdc->lpdwPal, lpdc->wPalNumber, lpdc->wPalFormat );
        else
            return CLR_INVALID;
    }
    return CLR_INVALID;

}

// **************************************************
// 声明:COLORREF WINAPI WinGdi_SetPixel( HDC hdc, int x, int y, COLORREF color )
// 参数:
//	IN hdc - 目标DC句柄
//	IN x - x坐标
//	IN y - y坐标
//	IN color - RGB颜色值
// 返回值:
//	返回实际写的RGB值, 失败,返回 -1
// 功能描述:
//	用给定的颜色写一个点
// 引用: 
//	系统API
// ************************************************

COLORREF WINAPI WinGdi_SetPixel( HDC hdc, int x, int y, COLORREF color )
{
    _LPGDCDATA lpdc = _GetSafeDrawPtr( hdc );//_GetHDCPtr( hdc );

    if( lpdc )
    {
        _PIXELDATA pixelData;

        pixelData.lpDestImage = _GetHBITMAPPtr( lpdc->hBitmap );
        pixelData.x = x + XOFFSET( lpdc );
        pixelData.y = y + YOFFSET( lpdc );
        pixelData.color = lpdc->lpDispDrv->lpRealizeColor(color, lpdc->lpdwPal, lpdc->wPalNumber, lpdc->wPalFormat);
        pixelData.pattern = 0;
        pixelData.rop = lpdc->rop;

        if( WinRgn_PtInRegion( lpdc->hrgn, pixelData.x, pixelData.y ) )
            lpdc->lpDispDrv->lpPutPixel( &pixelData );
        else
            return -1;
        return color;
    }
    return -1;
}

// **************************************************
// 声明:static int Sqrt32( int x )
// 参数:
// 	IN x
// 返回值:
//	平方根
// 功能描述:
//	对 整数 x 求其平方根
// 引用: 
//	
// ************************************************

static int Sqrt32( int x )
{
    ULONG val, root, newroot, mask;

    root = 0;
    mask = 0x40000000L;
    val  = (ULONG)x;

    do
    {
		newroot = root + mask;
		if ( newroot <= val )
		{
			val -= newroot;
			root = newroot + mask;
		}
		
		root >>= 1;
		mask >>= 2;
		
    } while ( mask != 0 );

    return root;
}

#define EF_OUTLINE  0x0001
#define EF_FILL     0x0002
#define EF_ROUNDRECT     0x0004
// 每一个扫描行的最大最小结构
typedef struct _MINMAX
{
	int maxl;
	int minr;
}MINMAX;
//弧数据结构
typedef struct _ARC_DATA
{
    int nXStartArc; // 第一条射线的x结束点 x-coord of first radial ending point
    int nYStartArc; // 第一条射线的y结束点 y-coord of first radial ending point
	int nXEndArc;   // 第二条射线的x结束点 x-coord of second radial ending point
	int nYEndArc;    // 第二条射线的y结束点 y-coord of second radial ending point

    int cxStart;    // = (nXStartArc - x0)
    int cyStart;    // = (nYStartArc - y0)
    int cxEnd;      // = (nXEndArc - x0)
    int cyEnd;      // = (nYEndArc - y0)

    int iStartQuadrant; //开始象限(基于0)
    int iEndQuadrant;//结束象限(基于0)
    int iArcDirect;//  // 顺时针方向 = -1, 否则 = 1
	BOOL bInvert;   //  当 开始点与结束点的方向与 iArcDirect方向相反,则iInvert = TRUE
}ARC_DATA, * PARC_DATA;

#define DRAW_1_Q   0x01  //     1 象限  //quadrant
#define DRAW_2_Q   0x02  //     2 象限  //quadrant
#define DRAW_3_Q   0x04  //     3 象限  //quadrant
#define DRAW_4_Q   0x08  //     4 象限  //quadrant
#define DRAW_ALL_Q ( DRAW_1_Q | DRAW_2_Q | DRAW_3_Q | DRAW_4_Q )

// **************************************************
// 声明:static DWORD JudgeArcMiddlePoint( PARC_DATA pArc )
// 参数:
// 	IN pArc - ARC_DATA 结构指针
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	判断 弧的两个端点之间的象限(始终有效)
// 引用: 
//	
// ************************************************

//判断 弧的两个端点之间的象限(始终有效)
static DWORD JudgeArcMiddlePoint( PARC_DATA pArc )
{
	DWORD dwDrawMode = 0;
	int dir = pArc->iArcDirect;
	if( pArc->iEndQuadrant != pArc->iStartQuadrant )
	{
		int i;
		i = (pArc->iStartQuadrant + dir + 4) & 3;
		while( i != pArc->iEndQuadrant )
		{
			dwDrawMode |= (0x01 << i);
			i = (i + dir + 4) & 3;
		};
	}
	else
	{  
		// pArc->cyStart / pArc->cxStart >= pArc->cyEnd / pArc->cxEnd
		int iStart = pArc->cyStart * pArc->cxEnd;
		int iEnd = pArc->cyEnd * pArc->cxStart;
		if( iStart == iEnd )
			dwDrawMode = DRAW_ALL_Q;
		if(  (dir > 0 && iStart > iEnd) ||        // 顺时针方向
			 (dir < 0 && iStart < iEnd)  )        // 反时针方向
		{   //
			dwDrawMode = DRAW_ALL_Q & ( ~(0x1 << pArc->iStartQuadrant) );
		}
	}
	return dwDrawMode;
}

// **************************************************
// 声明:static DWORD JudgeArcEndPoint( 
//					PARC_DATA pArc, 
//				    int x0, //     中心点
//					int y0,
//					POINT points[4]
//					)
// 参数:
// 	IN pArc - ARC_DATA结构指针
//	IN x0 - 弧的中心点 x
//	IN y0 - 弧的中心点 y
//	IN points - 弧所在的矩形的四个点
// 返回值:
//	返回弧的两个端点所在象限
// 功能描述:
//  判断同弧的两个端点所在象限 相同的点是否有效
//	
// 引用: 
//	
// ************************************************


static DWORD JudgeArcEndPoint( PARC_DATA pArc, 
				    int x0, //     中心点
					int y0,
					POINT points[4]
					)
{
	int cxS = points[pArc->iStartQuadrant].x - x0;  //开始象限的点
	int cyS = points[pArc->iStartQuadrant].y - y0;
	int cxE = points[pArc->iEndQuadrant].x - x0;  //结束象限的点
	int cyE = points[pArc->iEndQuadrant].y - y0;
	DWORD dwDrawMode  = 0;
	int dir = pArc->iArcDirect;
	int bValidStart, bValidEnd;

	if( dir > 0 )
	{   // 顺时针方向
		//cyS / cxS >= pArc->cyStart / pArc->cxStart 
		bValidStart = ( cyS * pArc->cxStart >= pArc->cyStart * cxS );

		//cyE / cxE < pArc->cyEnd / pArc->cxEnd 
		bValidEnd = ( cyE * pArc->cxEnd < pArc->cyEnd * cxE );
	}
	else
	{   //反时针方向
		//cyS / cxS <= pArc->cyStart / pArc->cxStart 
		bValidStart = (cyS * pArc->cxStart <= pArc->cyStart * cxS);

		//cyE / cxE > pArc->cyEnd / pArc->cxEnd 
		bValidEnd = ( cyE * pArc->cxEnd > pArc->cyEnd * cxE );
	}
	
	if( pArc->iEndQuadrant == pArc->iStartQuadrant )
	{	//开始象限 = 结束象限
		if( !pArc->bInvert )
		{   //在同样的象限 并且 与 ArcDirect 是顺方向
			if( bValidStart && bValidEnd ) // 必须同时成立
				dwDrawMode |= 0x01 << pArc->iStartQuadrant;
			goto _return;
		}
	}
	if( bValidStart )
		dwDrawMode |= 0x01 << pArc->iStartQuadrant;
	if( bValidEnd )
		dwDrawMode |= 0x01 << pArc->iEndQuadrant;

_return:
	return dwDrawMode;
}

// **************************************************
// 声明:static BOOL DrawEllipseRect( 
//						_LPCDISPLAYDRV lpDispDrv, 
//		                _LPLINEDATA lpLineData,
//						_LPRECTNODE lprNodes,
//                      _LPBLKBITBLT lpBlkData,
//                      _FILLRGN * lpFillRgn,
//						int x0,   // ellips's origin x point 
//						int y0,   // ellips's origin y point 
//						int r1,   // ellips's origin a len 
//						int r2,   // ellips's origin b len
//						int lw,   // pen's left width
//						int rw,   // pen's right width
//						UINT uiFlag,
//						int nRectWidth,
//						int nRectHeight,
//						MINMAX * lpMinMax,
//						PARC_DATA pArc
//						)
// 参数:
//	IN lpDispDrv - 显示驱动程序
//	IN lpLineData - 画线数据结构
//	IN lprNodes - 裁剪域
//  IN lpBlkData - 块填充结构
//  IN lpFillRgn - 填充区域结构
//	IN x0 - 椭圆的x远点    // ellips's origin x point 
//	IN y0 - 椭圆的y远点    // ellips's origin y point 
//	IN r1 - 椭圆的 a 半径长度    // ellips's origin a len 
//	IN r2 - 椭圆的 b 半径长度   // ellips's origin b len
//	IN lw - 笔的左部分宽度,   // pen's left width
//	IN rw - 笔的右部分宽度,   // pen's right width
//	IN uiFlag - 画标志:
//				EF_FILL - 填充椭圆
//				EF_ROUNDRECT - 画矩形的圆弧轮廓
//				EF_OUTLINE - 画椭圆外轮廓
//	IN nRectWidth - 矩形宽度
//	IN nRectHeight - 矩形高度
//	IN lpMinMax - 最大最小结构,当画有一定宽度的轮廓线时,该结构保存轮廓线在扫描线上的最大/最小宽度值。

⌨️ 快捷键说明

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