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

📄 rgn.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************
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 + -