📄 rgn.c
字号:
//
// ************************************************
int WINAPI WinRgn_Offset(HRGN hrgn, int xOffset, int yOffset)
{
_LPRGNDATA lprgn;
int retv = ERROR;
lprgn = _GetHRGNPtr( hrgn );
if( lprgn )
{
_LPRECTNODE lpNode;
int i;
ASSERT( lprgn->count >=0 );
OFFSET_RECT( lprgn->rect, xOffset, yOffset );
lpNode = lprgn->lpNodeFirst;
while( lpNode )
{
OFFSET_RECT( lpNode->rect, xOffset, yOffset );
lpNode = lpNode->lpNext;
}
if( (i = lprgn->count) == 0 )
retv = NULLREGION;
else if( i == 1 )
retv = SIMPLEREGION;
else
retv = COMPLEXREGION;
}
return retv;//ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL WINAPI WinRgn_PtInRegion(HRGN hrgn, int x, int y)
{
_LPRGNDATA lprgn = _GetHRGNPtr( hrgn );
int retv = FALSE;
if( lprgn )
{
_LPRECTNODE lpNode;
lpNode = lprgn->lpNodeFirst;
ASSERT( lprgn->count >= 0 );
while( lpNode )
{
if( x >= lpNode->rect.left && x < lpNode->rect.right &&
y >= lpNode->rect.top && y < lpNode->rect.bottom )
{
retv = TRUE; // in rect
break;
}
lpNode = lpNode->lpNext;
}
}
else
retv = ERROR;
return retv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL WINAPI WinRgn_RectInRegion(HRGN hrgn, const RECT * lprc )
{
_LPRGNDATA lprgn = _GetHRGNPtr( hrgn );
int retv = FALSE;
ASSERT( lprgn );
if( lprgn )
{
_LPRECTNODE lpNode;
lpNode = lprgn->lpNodeFirst;
ASSERT( lprgn->count >= 0 );
while( lpNode )
{
if( ( MAX(lpNode->rect.left, lprc->left) < MIN(lpNode->rect.right, lprc->right) ) &&
( MAX(lpNode->rect.top, lprc->top) < MIN(lpNode->rect.bottom, lprc->bottom) ) )
{
retv = TRUE; // has intersect;
break;
}
lpNode = lpNode->lpNext;
}
}
else
retv = ERROR;
return retv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL WINAPI WinRgn_SetRect(HRGN hrgn, int left, int top, int right, int bottom)
{
_LPRGNDATA lprgn = _GetHRGNPtr( hrgn );
int retv = FALSE;
ASSERT( lprgn );
FORMAT_XY( left, top, right, bottom );
if( lprgn )
{
__FreeNodes( lprgn->lpNodeFirst );
lprgn->lpNodeFirst = NULL;
if( left < right && top < bottom )
{
lprgn->lpNodeFirst = __AllocRectNode();
if( lprgn->lpNodeFirst == NULL )
retv = FALSE;
}
if( lprgn->lpNodeFirst )
{
lprgn->rect.left = left;
lprgn->rect.top = top;
lprgn->rect.right = right;
lprgn->rect.bottom = bottom;
lprgn->count = 1;
lprgn->lpNodeFirst->rect = lprgn->rect;
lprgn->lpNodeFirst->lpNext = 0;
retv = TRUE;//return TRUE;
}
else
{
lprgn->count = 0;
_SET_RECT_ZERO( lprgn->rect );
}
}
return retv;//FALSE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
//======================== private proc ============================
int _AndRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag )
{
_LPRECTNODE lpNode, lpFirst0, lpFirst1, lpSaveDest = 0;
RECT rect;
int count;
if( lpSrc1->count == 0 ||
lpSrc2->count == 0 )
{ // free lpDest
__FreeNodes( lpDest->lpNodeFirst );
lpDest->count = 0;
lpDest->lpNodeFirst = NULL;
_SET_RECT_ZERO( lpDest->rect );
return !ERROR;
}
lpNode = __AllocRectNode();
if( lpNode )
{
count = 0;
for( lpFirst0 = lpSrc1->lpNodeFirst; lpFirst0 != 0; lpFirst0 = lpFirst0->lpNext )
{
rect = lpFirst0->rect;
for( lpFirst1 = lpSrc2->lpNodeFirst; lpFirst1 != 0; lpFirst1 = lpFirst1->lpNext )
{
// if up speed, I may use inline option to replace IntersectRect
if( IntersectRect( &(lpNode->rect), &rect, &(lpFirst1->rect) ) )
{
// add to link table
INSERT_NODE_BEFORE( lpSaveDest, lpNode );
count++;
// alloc a new node for next use
lpNode = __AllocRectNode();
if( lpNode == 0 )
{ // failure to alloc mem
__FreeNodes( lpSaveDest );
return ERROR;
}
}
}
}
}
else
return ERROR;
__FreeNodes( lpDest->lpNodeFirst );
__FreeMem( lpNode );
lpDest->lpNodeFirst = lpSaveDest;
if( sFlag )
__SortAndUnite( lpDest );
return !ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int _CopyRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc)
{
_LPRECTNODE lpNode, lpNewNode, lpSaveNode = 0;
ASSERT( lpDest );
if( lpDest == lpSrc ||
lpSrc->count == 0 )
return !ERROR;
__FreeNodes( lpDest->lpNodeFirst );
lpDest->lpNodeFirst = 0;
if( lpSrc == 0 )
return NULLREGION;
lpNode = lpSrc->lpNodeFirst;
while( lpNode )
{
if( ( lpNewNode = __AllocRectNode() ) != 0 )
{
lpNewNode->rect = lpNode->rect;
INSERT_NODE_BEFORE( lpSaveNode, lpNewNode );
}
else
{
__FreeNodes( lpSaveNode );
return ERROR;
}
lpNode = lpNode->lpNext;
}
lpDest->lpNodeFirst = lpSaveNode;
lpDest->rect = lpSrc->rect;
lpDest->count = lpSrc->count;
return !ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int _DiffRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc, _LPRGNDATA lpRemove, BOOL sFlag)
{
_LPRECTNODE lpFixNode, lpDestCurrent, lpRemoveFirst, lpDestPrev, lpTemp;
_RGNDATA rgnDest;
int retv = ERROR;
ASSERT( lpDest && lpSrc && lpRemove );
rgnDest.lpNodeFirst = 0;
if( (retv = _CopyRgn( &rgnDest, lpSrc )) == ERROR )
return ERROR;
for( lpRemoveFirst = lpRemove->lpNodeFirst; lpRemoveFirst != 0 ; lpRemoveFirst = lpRemoveFirst->lpNext )
{
for( lpDestPrev = lpDestCurrent = rgnDest.lpNodeFirst; lpDestCurrent != 0; )
{
// make four rect to hrgnDest
retv = __FixRects( &lpFixNode, &(lpDestCurrent->rect), &(lpRemoveFirst->rect) );
if( retv == FIX_SPLIT_RECT || retv == FIX_REMOVE_RECT )
{// lpDestCurrent->rect has split to some rect, so I delete lpDestCurrent
// the lpNodeFirst of hrgnDest has changed after call _FixRects
if( lpDestPrev == lpDestCurrent )
{ // first
ASSERT( lpDestPrev == rgnDest.lpNodeFirst );
if( retv == FIX_SPLIT_RECT )
{
// search end of lpFixNode
lpTemp = lpFixNode;
while( lpTemp->lpNext )
lpTemp = lpTemp->lpNext;
// remove lpDestPrev
lpTemp->lpNext = lpDestPrev->lpNext;
// link rgnDest and lpFixNode
rgnDest.lpNodeFirst = lpFixNode;
// free lpDest
__FreeMem( lpDestCurrent );
// set for next loop
lpDestCurrent = lpTemp;
}
else
{ // retv is FIX_REMOVE_RECT
// only remove lpDestCurrent from rgnDest
rgnDest.lpNodeFirst = lpDestCurrent->lpNext;
__FreeMem( lpDestCurrent );
lpDestPrev = lpDestCurrent = rgnDest.lpNodeFirst;
continue;
}
}
else
{ // lpDestPrev != lpDestCurrent
// remove lpDestCurrent and free it
lpDestPrev->lpNext = lpDestCurrent->lpNext;
__FreeMem( lpDestCurrent );
// set for next loop
lpDestCurrent = lpDestPrev;
if( retv == FIX_SPLIT_RECT )
{ // search end of lpFixNode
lpTemp = lpFixNode;
while( lpTemp->lpNext )
lpTemp = lpTemp->lpNext;
// link lpFixNode and rgnDest
lpTemp->lpNext = rgnDest.lpNodeFirst;
rgnDest.lpNodeFirst = lpFixNode;
}
}
}
else if( retv == FIX_NO_MEM )
{
__FreeNodes( rgnDest.lpNodeFirst );
return ERROR;
}
lpDestPrev = lpDestCurrent;
lpDestCurrent = lpDestCurrent->lpNext;
}
}
__FreeNodes( lpDest->lpNodeFirst );
lpDest->lpNodeFirst = rgnDest.lpNodeFirst;
if( sFlag )
__SortAndUnite( lpDest );
return !ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
//int _OrRgn(HRGN hrgnDest, HRGN hrgnSrc1, HRGN hrgnSrc2)
int _OrRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag)
{
int retv;
if( (retv = _DiffRgn( lpDest, lpSrc1, lpSrc2, FALSE )) != ERROR )
retv = __AppendNodes( lpDest, lpSrc2 );
if( retv != ERROR && sFlag )
__SortAndUnite( lpDest );
return retv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int _XorRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag)
{
_RGNDATA rgnOver, rgnDest1, rgnDest2;
int retv;
rgnDest1.lpNodeFirst = rgnDest2.lpNodeFirst = rgnOver.lpNodeFirst = 0;
if( (retv = _AndRgn( &rgnOver, lpSrc1, lpSrc2, FALSE )) != ERROR )
{
if( rgnOver.lpNodeFirst == 0 )
{ // null region
if( (retv = __AppendNodes( &rgnOver, lpSrc1 )) != ERROR )
{
if( (retv = __AppendNodes( &rgnOver, lpSrc2 )) != ERROR )
{
__FreeNodes( lpDest->lpNodeFirst );
lpDest->lpNodeFirst = rgnOver.lpNodeFirst;
}
else
__FreeNodes( rgnOver.lpNodeFirst );
}
}
else
{ // retv == COMPLEXREGION or retv == SIMPLEREGION
if( (retv = _DiffRgn( &rgnDest1, lpSrc1, &rgnOver, FALSE )) != ERROR )
{
if( (retv = _DiffRgn( &rgnDest2, lpSrc2, &rgnOver, FALSE )) != ERROR )
{
__FreeNodes( lpDest->lpNodeFirst );
// link rgnDest1 and rgnDest2
lpDest->lpNodeFirst = __LinkNodesAfter( rgnDest1.lpNodeFirst, rgnDest2.lpNodeFirst );
}
else
__FreeNodes( rgnDest1.lpNodeFirst );
}
__FreeNodes( rgnOver.lpNodeFirst );
}
}
if( retv != ERROR && sFlag )
__SortAndUnite( lpDest );
return retv;
}
//#ifdef __USE_MEM
typedef struct __MEM_BLOCK
{
// struct __MEM_BLOCK *lpNext;
short int NextIndex;
short int PrevIndex;
union{
_RECTNODE node;
//_RGNDATA rgn;
}data;
}_MEM_BLOCK;
static int __FreeIndex = 0;
static int __AllocIndex = -1;
static int __Count = 0;
//int rgnCount;
#define BLOCK_SIZE 400
//static _MEM_BLOCK * __lpMemoryBlock[BLOCK_SIZE];
static _MEM_BLOCK * __lpMemoryBlock;
static CRITICAL_SECTION csRgn;
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL _InitialRgn( void )
{
int i;
// LPBYTE lpmem;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -