📄 gdi.c
字号:
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 + -