📄 rgn.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:矩形区域管理器
版本号:3.0.0
开发时期:1999
作者:李林
修改记录:
******************************************************/
#include <eframe.h>
#include <gwmeobj.h>
#include <eassert.h>
#include <bheap.h>
#define __USE_MEM
// private proc define start
#define INSERT_NODE_BEFORE( lpdst, lpsrc ) { (lpsrc)->lpNext = (lpdst); (lpdst) = (lpsrc); }
#define SET_LPRECTNODE_VALUE( lpRect, l, t, r, b ) { (lpRect)->rect.left = l; (lpRect)->rect.top = t; (lpRect)->rect.right = r; (lpRect)->rect.bottom = b; }
#define SET_RECT_VALUE( rect, l, t, r, b ) { rect.left = l; rect.top = t; rect.right = r; rect.bottom = b; }
static int _AndRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag );
static int _CopyRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc);
static int _DiffRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpRemove, BOOL sFlag );
static int _OrRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag );
static int _XorRgn(_LPRGNDATA lpDest, _LPRGNDATA lpSrc1, _LPRGNDATA lpSrc2, BOOL sFlag );
static void *__AllocMem( void );
static void __FreeMem( void* );
static BOOL _DeleteObject( _LPRGNDATA lpData );
static int __AppendNodes( _LPRGNDATA lpData, _LPRGNDATA lpSrc );
static int __CalcRgnBox( _LPRECTNODE lpNodeFirst, LPRECT lpRect );
static int __SortAndUnite( _LPRGNDATA lpData );
#define FIX_NO_MEM -1
#define FIX_NO_INTERSECT 0
#define FIX_REMOVE_RECT 1
#define FIX_SPLIT_RECT 2
static int __FixRects( _LPRECTNODE *lpData, LPRECT lpDest, LPRECT lpRemove );
static int __FreeNodes( _LPRECTNODE lpNodes );
static _LPRECTNODE __LinkNodesAfter( _LPRECTNODE lpDest, _LPRECTNODE lpSrc );
// private proc define end
#define __AllocRectNode (_LPRECTNODE)__AllocMem
#define _SET_LPRECT_ZERO( lprc ) ((lprc)->left = (lprc)->top = (lprc)->right = (lprc)->bottom = 0)
#define _SET_RECT_ZERO( rect ) ((rect).left = (rect).top = (rect).right = (rect).bottom = 0)
#define IS_RECT_EQUAL( rc1, rc2 ) ( (rc1).left == (rc2).left &&\
(rc1).top == (rc2).top &&\
(rc1).right == (rc2).right &&\
(rc1).bottom == (rc2).bottom)
#define OFFSET_RECT( rect, xOffset, yOffset ) { (rect).left += (xOffset);\
(rect).right += (xOffset);\
(rect).top += (yOffset);\
(rect).bottom += (yOffset); }
#define UNION_RECT( rect0, rect1 ) { rect0.left = MIN( rect0.left, rect1.left );\
rect0.top = MIN( rect0.top, rect1.top );\
rect0.right = MAX( rect0.right, rect1.right );\
rect0.bottom = MAX( rect0.bottom, rect1.bottom ); }
#define FORMAT_XY( l, t, r, b ) \
do{ \
int temp; \
if( (l) > (r) ) { temp = (l), (l) = (r), (r) = temp; } \
if( (t) > (b) ) { temp = (t), (t) = (b), (b) = temp; } \
}while(0);
//#define USE_USERHEAP
//#ifdef USE_USERHEAP
//#define malloc malloc
//#define free free
//#define _krealloc realloc
//#endif
extern BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner );
////////////////////////////////////////////////////////////
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static _LPRGNDATA __AllocRgnObjectHandle( void )
{
return BlockHeap_Alloc( hgwmeBlockHeap, 0, sizeof( _RGNDATA ) );
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static void __FreeRgnObjectHandle( _LPRGNDATA lpRgn )
{
BlockHeap_Free( hgwmeBlockHeap, 0, lpRgn, sizeof(_RGNDATA) );
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static HRGN DoCreateRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, UINT uiObjFlag )
{
_LPRGNDATA lpRgn = __AllocRgnObjectHandle();
FORMAT_XY( nLeftRect, nTopRect, nRightRect, nBottomRect );
if( lpRgn )
{
lpRgn->obj.objType = OBJ_REGION;
lpRgn->count = 0;
if( nLeftRect < nRightRect && nTopRect < nBottomRect )
{
lpRgn->lpNodeFirst = __AllocRectNode();
if( lpRgn->lpNodeFirst )
{
SET_LPRECTNODE_VALUE( lpRgn->lpNodeFirst, nLeftRect, nTopRect, nRightRect, nBottomRect );
lpRgn->lpNodeFirst->lpNext = 0;
lpRgn->count = 1;
lpRgn->rect = lpRgn->lpNodeFirst->rect;
}
else
{
_DeleteObject( lpRgn );
lpRgn = NULL;
}
}
else
{
lpRgn->lpNodeFirst = 0;
_SET_RECT_ZERO( lpRgn->rect );
}
}
ASSERT_NOTIFY( lpRgn, "CreateRectRgn: No enough rgn resource\r\n" );
if( lpRgn )
{
extern BOOL Gdi_AddToObjMgr( LPOBJLIST lpObj, DWORD objType, HANDLE hOwner );
AddToObjMgr( &lpRgn->obj, OBJ_REGION | uiObjFlag, (ULONG)GetCallerProcess() );
}
if( lpRgn )
return (HRGN)PTR_TO_HANDLE( lpRgn );
return NULL;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
HRGN WINAPI WinRgn_CreateRect( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect )
{
return DoCreateRectRgn( nLeftRect, nTopRect, nRightRect, nBottomRect, 0 );
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
HRGN _CreateSysRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect )
{
return DoCreateRectRgn( nLeftRect, nTopRect, nRightRect, nBottomRect, OBJ_FREE_DISABLE );
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
HRGN WINAPI WinRgn_CreateRectIndirect(LPCRECT lpRect)
{
return WinRgn_CreateRect( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int WINAPI WinRgn_Combine( HRGN hrgnDest, HRGN hrgnSrc1, HRGN hrgnSrc2, int fnCombineMode )
{
int retv = ERROR;
_LPRGNDATA lpRgnDest, lpRgnSrc1, lpRgnSrc2;
lpRgnDest = _GetHRGNPtr( hrgnDest );
if( lpRgnDest == NULL )
goto L_RET;
switch( fnCombineMode )
{
case RGN_AND:
//ASSERT( hrgnSrc1 && hrgnSrc2 );
lpRgnSrc1 = _GetHRGNPtr( hrgnSrc1 );
lpRgnSrc2 = _GetHRGNPtr( hrgnSrc2 );
if( lpRgnSrc1 && lpRgnSrc2 )
retv = _AndRgn( lpRgnDest, lpRgnSrc1, lpRgnSrc2, TRUE );
break;
case RGN_COPY:
///ASSERT( hrgnSrc1 );
lpRgnSrc1 = _GetHRGNPtr( hrgnSrc1 );
if( lpRgnSrc1 )
retv = _CopyRgn( lpRgnDest, lpRgnSrc1 );
break;
case RGN_DIFF:
//ASSERT( hrgnSrc1 && hrgnSrc2 );
lpRgnSrc1 = _GetHRGNPtr( hrgnSrc1 );
lpRgnSrc2 = _GetHRGNPtr( hrgnSrc2 );
if( lpRgnSrc1 && lpRgnSrc2 )
retv = _DiffRgn( lpRgnDest, lpRgnSrc1, lpRgnSrc2, TRUE );
break;
case RGN_OR:
//ASSERT( hrgnSrc1 && hrgnSrc2 );
lpRgnSrc1 = _GetHRGNPtr( hrgnSrc1 );
lpRgnSrc2 = _GetHRGNPtr( hrgnSrc2 );
if( lpRgnSrc1 && lpRgnSrc2 )
retv = _OrRgn( lpRgnDest, lpRgnSrc1, lpRgnSrc2, TRUE );
break;
case RGN_XOR:
//ASSERT( hrgnSrc1 && hrgnSrc2 );
lpRgnSrc1 = _GetHRGNPtr( hrgnSrc1 );
lpRgnSrc2 = _GetHRGNPtr( hrgnSrc2 );
if( lpRgnSrc1 && lpRgnSrc2 )
retv = _XorRgn( lpRgnDest, lpRgnSrc1, lpRgnSrc2, TRUE );
break;
default:
ASSERT( 0 );
}
// only for test
//_CheckObjList();
L_RET:
//LeaveCriticalSection( &csRgn );
if( retv != ERROR )
{
if( (retv = lpRgnDest->count) == 0 )
return NULLREGION;
else if( retv == 1 )
return SIMPLEREGION;
else
return COMPLEXREGION;
}
return retv;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
static BOOL _DeleteObject( _LPRGNDATA lpRgn )
{
lpRgn->obj.objType = OBJ_NULL;
__FreeNodes( lpRgn->lpNodeFirst );
__FreeRgnObjectHandle( lpRgn );
return TRUE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL _DeleteRgnObject(HRGN hrgn)
{
if( hrgn )
{
_LPRGNDATA lpRgn = _GetHRGNPtr( hrgn );
if( lpRgn && !(lpRgn->obj.objType & OBJ_FREE_DISABLE) )
{
return _DeleteObject( lpRgn );
}
}
return FALSE;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
BOOL WINAPI WinRgn_Equal(HRGN hSrcRgn1, HRGN hSrcRgn2)
{
int retv = ERROR;
_LPRECTNODE lpNode1, lpNode2;
_LPRGNDATA lpSrc1, lpSrc2;
//EnterCriticalSection( &csRgn );
lpSrc1 = _GetHRGNPtr( hSrcRgn1 );
lpSrc2 = _GetHRGNPtr( hSrcRgn2 );
//ASSERT( lpSrc1 && lpSrc2 );
if( lpSrc1 && lpSrc2 )
{
//lpSrc1 = _GET_HRGN_PTR( hSrcRgn1 );
//lpSrc2 = _GET_HRGN_PTR( hSrcRgn2 );
ASSERT( lpSrc1->count >= 0 && lpSrc2->count >= 0 );
lpNode1 = lpSrc1->lpNodeFirst;
lpNode2 = lpSrc2->lpNodeFirst;
if( lpSrc1->count == lpSrc2->count &&
IS_RECT_EQUAL(lpSrc1->rect, lpSrc2->rect) )
{
lpNode1 = lpSrc1->lpNodeFirst;
lpNode2 = lpSrc2->lpNodeFirst;
while( lpNode1 && lpNode2 )
{
if( !IS_RECT_EQUAL( lpNode1->rect, lpNode2->rect ) )
{
retv = FALSE;//return FALSE;
goto L_RET;
}
lpNode1 = lpNode1->lpNext;
lpNode2 = lpNode2->lpNext;
}
if( lpNode1 == 0 && lpNode2 == 0 )
retv = TRUE;//return TRUE;
}
else
retv = FALSE;
//return FALSE;
}
L_RET:
//LeaveCriticalSection( &csRgn );
return retv;//ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
int WINAPI WinRgn_GetBox(HRGN hrgn, LPRECT lprc)
{
_LPRGNDATA lpRgn;
int retv = ERROR;
lpRgn = _GetHRGNPtr( hrgn );
//ASSERT( lpRgn );
if( lpRgn )
{
int i;
*lprc = lpRgn->rect;
if( (i = lpRgn->count) == 0 )
{
retv = NULLREGION;//return NULLREGION;
ASSERT( lpRgn->lpNodeFirst == NULL );
}
else if( i == 1 )
retv = SIMPLEREGION;//return SIMPLEREGION;
else
retv = COMPLEXREGION;//return COMPLEXREGION;
}
return retv;//ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
//
// ************************************************
// the option export for win.c
int _GetRgnInfo(HRGN hrgn)
{
_LPRGNDATA lprgn = _GetHRGNPtr( hrgn );
ASSERT( lprgn );
if( lprgn )
{
int i;
if( (i = lprgn->count) == 0 )
{
ASSERT( lprgn->lpNodeFirst == NULL );
return NULLREGION;
}
else if( i == 1 )
return SIMPLEREGION;
else
return COMPLEXREGION;
}
return ERROR;
}
// **************************************************
// 声明:
// 参数:
// 无
// 返回值:
// 假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//
// 引用:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -