2004-08-15 18:40:07 +00:00
|
|
|
#include "precomp.h"
|
2002-07-22 17:42:52 +00:00
|
|
|
|
2009-12-24 07:42:38 +00:00
|
|
|
#define INRECT(r, x, y) \
|
|
|
|
( ( ((r).right > x)) && \
|
|
|
|
( ((r).left <= x)) && \
|
|
|
|
( ((r).bottom > y)) && \
|
|
|
|
( ((r).top <= y)) )
|
|
|
|
|
|
|
|
static
|
|
|
|
INT
|
|
|
|
FASTCALL
|
|
|
|
ComplexityFromRects( PRECT prc1, PRECT prc2)
|
|
|
|
{
|
|
|
|
if ( prc2->left >= prc1->left )
|
|
|
|
{
|
|
|
|
if ( ( prc1->right >= prc2->right) &&
|
|
|
|
( prc1->top <= prc2->top ) &&
|
|
|
|
( prc1->bottom <= prc2->bottom ) )
|
|
|
|
return SIMPLEREGION;
|
|
|
|
|
|
|
|
if ( prc2->left > prc1->left )
|
|
|
|
{
|
|
|
|
if ( ( prc1->left >= prc2->right ) ||
|
|
|
|
( prc1->right <= prc2->left ) ||
|
|
|
|
( prc1->top >= prc2->bottom ) ||
|
|
|
|
( prc1->bottom <= prc2->top ) )
|
|
|
|
return COMPLEXREGION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( prc2->right < prc1->right ) ||
|
|
|
|
( prc2->top > prc1->top ) ||
|
|
|
|
( prc2->bottom < prc1->bottom ) )
|
|
|
|
{
|
|
|
|
if ( ( prc1->left >= prc2->right ) ||
|
|
|
|
( prc1->right <= prc2->left ) ||
|
|
|
|
( prc1->top >= prc2->bottom ) ||
|
|
|
|
( prc1->bottom <= prc2->top ) )
|
|
|
|
return COMPLEXREGION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NULLREGION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
SortRects(PRECT pRect, INT nCount)
|
|
|
|
{
|
2008-01-05 05:58:40 +00:00
|
|
|
INT i = 0, a = 0, b = 0, c, s;
|
2007-12-31 17:26:57 +00:00
|
|
|
RECT sRect;
|
|
|
|
|
|
|
|
if (nCount > 0)
|
|
|
|
{
|
2008-01-05 05:58:40 +00:00
|
|
|
i = 1; // set index point
|
|
|
|
c = nCount; // set inverse count
|
|
|
|
do
|
|
|
|
{
|
|
|
|
s = i; // set sort count
|
|
|
|
if ( i < nCount )
|
|
|
|
{
|
|
|
|
a = i - 1;
|
|
|
|
b = i;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if(pRect[b].top != pRect[i].bottom) break;
|
|
|
|
if(pRect[b].left < pRect[a].left)
|
|
|
|
{
|
|
|
|
sRect = pRect[a];
|
|
|
|
pRect[a] = pRect[b];
|
|
|
|
pRect[b] = sRect;
|
|
|
|
}
|
|
|
|
++s;
|
|
|
|
++b;
|
|
|
|
} while ( s < nCount );
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
} while ( c-- != 1 );
|
2007-12-31 17:26:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-07 00:56:12 +00:00
|
|
|
/*
|
2007-12-31 17:26:57 +00:00
|
|
|
* I thought it was okay to have this in DeleteObject but~ Speed. (jt)
|
2007-08-07 00:56:12 +00:00
|
|
|
*/
|
2007-12-31 17:26:57 +00:00
|
|
|
BOOL
|
|
|
|
FASTCALL
|
|
|
|
DeleteRegion( HRGN hRgn )
|
2007-08-07 00:56:12 +00:00
|
|
|
{
|
2007-12-31 17:26:57 +00:00
|
|
|
#if 0
|
|
|
|
PRGN_ATTR Rgn_Attr;
|
|
|
|
|
|
|
|
if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) &&
|
|
|
|
( Rgn_Attr != NULL ))
|
|
|
|
{
|
|
|
|
PTEB pTeb = NtCurrentTeb();
|
|
|
|
if (pTeb->Win32ThreadInfo != NULL)
|
|
|
|
{
|
|
|
|
if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
|
|
|
|
{
|
|
|
|
PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
|
|
|
|
pTeb->GdiTebBatch.Offset);
|
|
|
|
pgO->gbHdr.Cmd = GdiBCDelRgn;
|
|
|
|
pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
|
|
|
|
pgO->hgdiobj = (HGDIOBJ)hRgn;
|
|
|
|
|
|
|
|
pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
|
|
|
|
pTeb->GdiBatchCount++;
|
|
|
|
if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
|
2007-08-07 00:56:12 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
INT
|
|
|
|
FASTCALL
|
|
|
|
MirrorRgnByWidth(HRGN hRgn, INT Width, HRGN *phRgn)
|
|
|
|
{
|
|
|
|
INT cRgnDSize, Ret = 0;
|
|
|
|
PRGNDATA pRgnData;
|
|
|
|
|
|
|
|
cRgnDSize = NtGdiGetRegionData(hRgn, 0, NULL);
|
2007-08-07 00:56:12 +00:00
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
if (cRgnDSize)
|
|
|
|
{
|
|
|
|
pRgnData = LocalAlloc(LMEM_FIXED, cRgnDSize * sizeof(LONG));
|
|
|
|
if (pRgnData)
|
|
|
|
{
|
|
|
|
if ( GetRegionData(hRgn, cRgnDSize, pRgnData) )
|
|
|
|
{
|
|
|
|
HRGN hRgnex;
|
2008-12-07 21:52:22 +00:00
|
|
|
UINT i;
|
|
|
|
INT SaveL = pRgnData->rdh.rcBound.left;
|
2007-12-31 17:26:57 +00:00
|
|
|
pRgnData->rdh.rcBound.left = Width - pRgnData->rdh.rcBound.right;
|
|
|
|
pRgnData->rdh.rcBound.right = Width - SaveL;
|
|
|
|
if (pRgnData->rdh.nCount > 0)
|
|
|
|
{
|
|
|
|
PRECT pRect = (PRECT)&pRgnData->Buffer;
|
|
|
|
for (i = 0; i < pRgnData->rdh.nCount; i++)
|
|
|
|
{
|
|
|
|
SaveL = pRect[i].left;
|
|
|
|
pRect[i].left = Width - pRect[i].right;
|
|
|
|
pRect[i].right = Width - SaveL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SortRects((PRECT)&pRgnData->Buffer, pRgnData->rdh.nCount);
|
|
|
|
hRgnex = ExtCreateRegion(NULL, cRgnDSize , pRgnData);
|
|
|
|
if (hRgnex)
|
|
|
|
{
|
|
|
|
if (phRgn) phRgn = (HRGN *)hRgnex;
|
|
|
|
else
|
|
|
|
{
|
2009-08-23 22:47:32 +00:00
|
|
|
CombineRgn(hRgn, hRgnex, 0, RGN_COPY);
|
2007-12-31 17:26:57 +00:00
|
|
|
DeleteObject(hRgnex);
|
|
|
|
}
|
|
|
|
Ret = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LocalFree(pRgnData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-12-31 17:26:57 +00:00
|
|
|
MirrorRgnDC(HDC hdc, HRGN hRgn, HRGN *phRgn)
|
2003-07-20 00:13:36 +00:00
|
|
|
{
|
2007-12-31 17:26:57 +00:00
|
|
|
if (!GdiIsHandleValid((HGDIOBJ) hdc) ||
|
|
|
|
(GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)) return 0;
|
|
|
|
|
|
|
|
return MirrorRgnByWidth(hRgn, NtGdiGetDeviceWidth(hdc), phRgn);
|
2003-07-20 00:13:36 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2007-04-20 23:50:44 +00:00
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
CombineRgn(HRGN hDest,
|
|
|
|
HRGN hSrc1,
|
|
|
|
HRGN hSrc2,
|
|
|
|
INT CombineMode)
|
|
|
|
{
|
|
|
|
/* FIXME some part should be done in user mode */
|
|
|
|
return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
|
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-04-20 23:50:44 +00:00
|
|
|
HRGN
|
2007-10-19 23:21:45 +00:00
|
|
|
WINAPI
|
2007-08-24 17:37:53 +00:00
|
|
|
CreatePolygonRgn( const POINT * lppt, int cPoints, int fnPolyFillMode)
|
2007-04-20 23:50:44 +00:00
|
|
|
{
|
2007-08-24 17:37:53 +00:00
|
|
|
return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) &cPoints, 1, GdiPolyPolyRgn);
|
2007-04-20 23:50:44 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-04-20 23:50:44 +00:00
|
|
|
HRGN
|
|
|
|
WINAPI
|
remove redirect of CreatePolyPolygonRgn@16 and implement own stub for it, it is hacked, it should doing, return (HRGN) NtGdiPolyPolyDraw(fnPolyFillMode, lppt, lpPolyCounts, nCount, 6 );
remove redirect of CreatePolygonRgn@12 and implement own stub for it, it is hacked, it should doing return NtGdiPolyPolyDraw(fnPolyFillMode,lppt,cPoints,1,6);
remove redirect of CreateRectRgn@16 and implement own stub for it, some part need be done in user mode
Fix CreateRectRgnIndirect it call now on CreateRectRgn for some part need be done in user mode, and it crash if NULL comes in as param, like windows does.
Fix CreatePenIndirect ir call now on CreatePen for some stuff need be done in user mode.
Add comment to CreatePen it need be fix.
svn path=/trunk/; revision=28484
2007-08-23 19:21:16 +00:00
|
|
|
CreatePolyPolygonRgn( const POINT* lppt,
|
|
|
|
const INT* lpPolyCounts,
|
|
|
|
int nCount,
|
|
|
|
int fnPolyFillMode)
|
2007-04-20 23:50:44 +00:00
|
|
|
{
|
2007-08-24 17:37:53 +00:00
|
|
|
return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) lpPolyCounts, (ULONG) nCount, GdiPolyPolyRgn );
|
2007-04-20 23:50:44 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-07-26 16:27:47 +00:00
|
|
|
HRGN
|
|
|
|
WINAPI
|
|
|
|
CreateEllipticRgnIndirect(
|
|
|
|
const RECT *prc
|
|
|
|
)
|
|
|
|
{
|
2007-08-23 15:03:13 +00:00
|
|
|
/* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
|
|
|
|
return NtGdiCreateEllipticRgn(prc->left, prc->top, prc->right, prc->bottom);
|
|
|
|
|
2007-07-26 16:27:47 +00:00
|
|
|
}
|
2007-07-26 19:52:51 +00:00
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
HRGN
|
|
|
|
WINAPI
|
2009-12-23 23:30:26 +00:00
|
|
|
CreateRectRgn(int x1, int y1, int x2, int y2)
|
remove redirect of CreatePolyPolygonRgn@16 and implement own stub for it, it is hacked, it should doing, return (HRGN) NtGdiPolyPolyDraw(fnPolyFillMode, lppt, lpPolyCounts, nCount, 6 );
remove redirect of CreatePolygonRgn@12 and implement own stub for it, it is hacked, it should doing return NtGdiPolyPolyDraw(fnPolyFillMode,lppt,cPoints,1,6);
remove redirect of CreateRectRgn@16 and implement own stub for it, some part need be done in user mode
Fix CreateRectRgnIndirect it call now on CreateRectRgn for some part need be done in user mode, and it crash if NULL comes in as param, like windows does.
Fix CreatePenIndirect ir call now on CreatePen for some stuff need be done in user mode.
Add comment to CreatePen it need be fix.
svn path=/trunk/; revision=28484
2007-08-23 19:21:16 +00:00
|
|
|
{
|
2009-12-24 07:42:38 +00:00
|
|
|
PRGN_ATTR pRgn_Attr;
|
|
|
|
HRGN hrgn;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
/* Normalize points */
|
|
|
|
x = x1;
|
|
|
|
if ( x1 > x2 )
|
|
|
|
{
|
|
|
|
x1 = x2;
|
|
|
|
x2 = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
y = y1;
|
|
|
|
if ( y1 > y2 )
|
|
|
|
{
|
|
|
|
y1 = y2;
|
|
|
|
y2 = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (UINT)x1 < 0x80000000 ||
|
|
|
|
(UINT)y1 < 0x80000000 ||
|
|
|
|
(UINT)x2 > 0x7FFFFFFF ||
|
|
|
|
(UINT)y2 > 0x7FFFFFFF )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-12-24 09:01:43 +00:00
|
|
|
//// Remove when Brush/Pen/Rgn Attr is ready!
|
2009-12-24 07:42:38 +00:00
|
|
|
return NtGdiCreateRectRgn(x1,y1,x2,y2);
|
|
|
|
////
|
|
|
|
hrgn = hGetPEBHandle(hctRegionHandle, 0);
|
|
|
|
|
|
|
|
if (!hrgn)
|
|
|
|
hrgn = NtGdiCreateRectRgn(0, 0, 1, 1);
|
|
|
|
|
|
|
|
if (!hrgn)
|
|
|
|
return hrgn;
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
|
|
|
|
{
|
|
|
|
DeleteRegion(hrgn);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (( x1 == x2) || (y1 == y2))
|
|
|
|
{
|
|
|
|
pRgn_Attr->Flags = NULLREGION;
|
|
|
|
pRgn_Attr->Rect.left = pRgn_Attr->Rect.top =
|
|
|
|
pRgn_Attr->Rect.right = pRgn_Attr->Rect.bottom = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pRgn_Attr->Flags = SIMPLEREGION;
|
|
|
|
pRgn_Attr->Rect.left = x1;
|
|
|
|
pRgn_Attr->Rect.top = y1;
|
|
|
|
pRgn_Attr->Rect.right = x2;
|
|
|
|
pRgn_Attr->Rect.bottom = y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
pRgn_Attr->AttrFlags = (ATTR_RGN_DIRTY|ATTR_RGN_VALID);
|
|
|
|
|
|
|
|
return hrgn;
|
remove redirect of CreatePolyPolygonRgn@16 and implement own stub for it, it is hacked, it should doing, return (HRGN) NtGdiPolyPolyDraw(fnPolyFillMode, lppt, lpPolyCounts, nCount, 6 );
remove redirect of CreatePolygonRgn@12 and implement own stub for it, it is hacked, it should doing return NtGdiPolyPolyDraw(fnPolyFillMode,lppt,cPoints,1,6);
remove redirect of CreateRectRgn@16 and implement own stub for it, some part need be done in user mode
Fix CreateRectRgnIndirect it call now on CreateRectRgn for some part need be done in user mode, and it crash if NULL comes in as param, like windows does.
Fix CreatePenIndirect ir call now on CreatePen for some stuff need be done in user mode.
Add comment to CreatePen it need be fix.
svn path=/trunk/; revision=28484
2007-08-23 19:21:16 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-07-26 19:52:51 +00:00
|
|
|
HRGN
|
|
|
|
WINAPI
|
|
|
|
CreateRectRgnIndirect(
|
|
|
|
const RECT *prc
|
|
|
|
)
|
|
|
|
{
|
remove redirect of CreatePolyPolygonRgn@16 and implement own stub for it, it is hacked, it should doing, return (HRGN) NtGdiPolyPolyDraw(fnPolyFillMode, lppt, lpPolyCounts, nCount, 6 );
remove redirect of CreatePolygonRgn@12 and implement own stub for it, it is hacked, it should doing return NtGdiPolyPolyDraw(fnPolyFillMode,lppt,cPoints,1,6);
remove redirect of CreateRectRgn@16 and implement own stub for it, some part need be done in user mode
Fix CreateRectRgnIndirect it call now on CreateRectRgn for some part need be done in user mode, and it crash if NULL comes in as param, like windows does.
Fix CreatePenIndirect ir call now on CreatePen for some stuff need be done in user mode.
Add comment to CreatePen it need be fix.
svn path=/trunk/; revision=28484
2007-08-23 19:21:16 +00:00
|
|
|
/* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */
|
|
|
|
return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom);
|
|
|
|
|
2007-07-26 19:52:51 +00:00
|
|
|
}
|
2007-11-05 01:50:59 +00:00
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
ExcludeClipRect(IN HDC hdc, IN INT xLeft, IN INT yTop, IN INT xRight, IN INT yBottom)
|
|
|
|
{
|
2009-12-24 07:42:38 +00:00
|
|
|
#if 0
|
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_ExcludeClipRect( hdc, xLeft, yTop, xRight, yBottom);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( pLDC )
|
|
|
|
{
|
|
|
|
if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExcludeClipRect( hdc, xLeft, yTop, xRight, yBottom))
|
|
|
|
return NtGdiExcludeClipRect(hdc, xLeft, yTop, xRight, yBottom);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-23 23:10:32 +00:00
|
|
|
return NtGdiExcludeClipRect(hdc, xLeft, yTop, xRight, yBottom);
|
|
|
|
}
|
|
|
|
|
2007-11-27 01:01:39 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HRGN
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
ExtCreateRegion(
|
|
|
|
CONST XFORM * lpXform,
|
|
|
|
DWORD nCount,
|
|
|
|
CONST RGNDATA * lpRgnData
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (lpRgnData)
|
|
|
|
{
|
|
|
|
if ((!lpXform) && (lpRgnData->rdh.nCount == 1))
|
|
|
|
{
|
|
|
|
PRECT pRect = (PRECT)&lpRgnData->Buffer[0];
|
|
|
|
return CreateRectRgn(pRect->left, pRect->top, pRect->right, pRect->bottom);
|
|
|
|
}
|
|
|
|
return NtGdiExtCreateRegion((LPXFORM) lpXform, nCount,(LPRGNDATA) lpRgnData);
|
|
|
|
}
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode)
|
|
|
|
{
|
|
|
|
/* FIXME some part need be done on user mode size */
|
|
|
|
return NtGdiExtSelectClipRgn(hdc,hrgn, iMode);
|
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-12-31 17:26:57 +00:00
|
|
|
GetClipRgn(
|
|
|
|
HDC hdc,
|
|
|
|
HRGN hrgn
|
|
|
|
)
|
|
|
|
{
|
2008-05-23 00:29:08 +00:00
|
|
|
INT Ret = NtGdiGetRandomRgn(hdc, hrgn, CLIPRGN);
|
2007-12-31 17:26:57 +00:00
|
|
|
// if (Ret)
|
2008-01-05 05:58:40 +00:00
|
|
|
// {
|
|
|
|
// if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL);
|
|
|
|
// }
|
2007-12-31 17:26:57 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2008-01-09 04:15:42 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-01-09 04:15:42 +00:00
|
|
|
GetMetaRgn(HDC hdc,
|
|
|
|
HRGN hrgn)
|
|
|
|
{
|
2008-05-23 00:29:08 +00:00
|
|
|
return NtGdiGetRandomRgn(hdc, hrgn, METARGN);
|
2008-01-09 04:15:42 +00:00
|
|
|
}
|
|
|
|
|
2009-12-23 23:30:26 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
DWORD
|
|
|
|
WINAPI
|
|
|
|
GetRegionData(HRGN hrgn,
|
|
|
|
DWORD nCount,
|
|
|
|
LPRGNDATA lpRgnData)
|
|
|
|
{
|
|
|
|
if (!lpRgnData)
|
|
|
|
{
|
|
|
|
nCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NtGdiGetRegionData(hrgn,nCount,lpRgnData);
|
|
|
|
}
|
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
GetRgnBox(HRGN hrgn,
|
|
|
|
LPRECT prcOut)
|
|
|
|
{
|
|
|
|
PRGN_ATTR Rgn_Attr;
|
2009-12-23 23:30:26 +00:00
|
|
|
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
|
2009-12-23 23:10:32 +00:00
|
|
|
return NtGdiGetRgnBox(hrgn, prcOut);
|
2009-12-23 23:30:26 +00:00
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
if (Rgn_Attr->Flags == NULLREGION)
|
|
|
|
{
|
|
|
|
prcOut->left = 0;
|
|
|
|
prcOut->top = 0;
|
|
|
|
prcOut->right = 0;
|
|
|
|
prcOut->bottom = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-12-23 23:30:26 +00:00
|
|
|
if (Rgn_Attr->Flags != SIMPLEREGION)
|
|
|
|
return NtGdiGetRgnBox(hrgn, prcOut);
|
|
|
|
/* WARNING! prcOut is never checked newbies! */
|
|
|
|
RtlCopyMemory( prcOut, &Rgn_Attr->Rect, sizeof(RECT));
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
return Rgn_Attr->Flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
IntersectClipRect(HDC hdc,
|
|
|
|
int nLeftRect,
|
|
|
|
int nTopRect,
|
|
|
|
int nRightRect,
|
|
|
|
int nBottomRect)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_IntersectClipRect( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( pLDC )
|
|
|
|
{
|
|
|
|
if (pLDC->iType != LDC_EMFLDC || EMFDRV_IntersectClipRect( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect))
|
|
|
|
return NtGdiIntersectClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2009-12-24 07:42:38 +00:00
|
|
|
return ERROR;
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return NtGdiIntersectClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-12-31 17:26:57 +00:00
|
|
|
MirrorRgn(HWND hwnd, HRGN hrgn)
|
|
|
|
{
|
|
|
|
RECT Rect;
|
|
|
|
GetWindowRect(hwnd, &Rect);
|
|
|
|
return MirrorRgnByWidth(hrgn, Rect.right - Rect.left, NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
OffsetClipRgn(HDC hdc,
|
|
|
|
int nXOffset,
|
|
|
|
int nYOffset)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_OffsetClipRgn( hdc, nXOffset, nYOffset );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2009-12-24 07:42:38 +00:00
|
|
|
return ERROR;
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC && !EMFDRV_OffsetClipRgn( hdc, nXOffset, nYOffset ))
|
2009-12-24 07:42:38 +00:00
|
|
|
return ERROR;
|
2009-12-23 23:10:32 +00:00
|
|
|
return NtGdiOffsetClipRgn( hdc, nXOffset, nYOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return NtGdiOffsetClipRgn( hdc, nXOffset, nYOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
INT
|
|
|
|
WINAPI
|
|
|
|
OffsetRgn( HRGN hrgn,
|
|
|
|
int nXOffset,
|
|
|
|
int nYOffset)
|
|
|
|
{
|
2009-12-24 07:42:38 +00:00
|
|
|
PRGN_ATTR pRgn_Attr;
|
|
|
|
int nLeftRect, nTopRect, nRightRect, nBottomRect;
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
|
|
|
|
return NtGdiOffsetRgn(hrgn,nXOffset,nYOffset);
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags == NULLREGION)
|
|
|
|
return pRgn_Attr->Flags;
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags != SIMPLEREGION)
|
|
|
|
return NtGdiOffsetRgn(hrgn,nXOffset,nYOffset);
|
|
|
|
|
|
|
|
nLeftRect = pRgn_Attr->Rect.left;
|
|
|
|
nTopRect = pRgn_Attr->Rect.top;
|
|
|
|
nRightRect = pRgn_Attr->Rect.right;
|
|
|
|
nBottomRect = pRgn_Attr->Rect.bottom;
|
|
|
|
|
|
|
|
if (nLeftRect < nRightRect)
|
|
|
|
{
|
|
|
|
if (nTopRect < nBottomRect)
|
|
|
|
{
|
|
|
|
nLeftRect = nXOffset + nLeftRect;
|
|
|
|
nTopRect = nYOffset + nTopRect;
|
|
|
|
nRightRect = nXOffset + nRightRect;
|
|
|
|
nBottomRect = nYOffset + nBottomRect;
|
|
|
|
|
|
|
|
/* Mask and bit test. */
|
|
|
|
if ( ( nLeftRect & 0xF8000000 &&
|
|
|
|
(nLeftRect & 0xF8000000) != 0x80000000 ) ||
|
|
|
|
( nTopRect & 0xF8000000 &&
|
|
|
|
(nTopRect & 0xF8000000) != 0x80000000 ) ||
|
|
|
|
( nRightRect & 0xF8000000 &&
|
|
|
|
(nRightRect & 0xF8000000) != 0x80000000 ) ||
|
|
|
|
( nBottomRect & 0xF8000000 &&
|
|
|
|
(nBottomRect & 0xF8000000) != 0x80000000 ) )
|
|
|
|
{
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pRgn_Attr->Rect.top = nTopRect;
|
|
|
|
pRgn_Attr->Rect.left = nLeftRect;
|
|
|
|
pRgn_Attr->Rect.right = nRightRect;
|
|
|
|
pRgn_Attr->Rect.bottom = nBottomRect;
|
|
|
|
pRgn_Attr->AttrFlags |= ATTR_RGN_DIRTY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pRgn_Attr->Flags;
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-12-24 07:42:38 +00:00
|
|
|
* @implemented
|
2009-12-23 23:10:32 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
PtInRegion(IN HRGN hrgn,
|
|
|
|
int x,
|
|
|
|
int y)
|
|
|
|
{
|
2009-12-24 07:42:38 +00:00
|
|
|
PRGN_ATTR pRgn_Attr;
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
|
|
|
|
return NtGdiPtInRegion(hrgn,x,y);
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags == NULLREGION)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags != SIMPLEREGION)
|
|
|
|
return NtGdiPtInRegion(hrgn,x,y);
|
|
|
|
|
|
|
|
return INRECT( pRgn_Attr->Rect, x, y);
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-12-24 07:42:38 +00:00
|
|
|
* @implemented
|
2009-12-23 23:10:32 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
RectInRegion(HRGN hrgn,
|
|
|
|
LPCRECT prcl)
|
|
|
|
{
|
2009-12-24 07:42:38 +00:00
|
|
|
PRGN_ATTR pRgn_Attr;
|
|
|
|
RECT rc;
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
|
|
|
|
return NtGdiRectInRegion(hrgn, (LPRECT) prcl);
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags == NULLREGION)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if ( pRgn_Attr->Flags != SIMPLEREGION)
|
|
|
|
return NtGdiRectInRegion(hrgn, (LPRECT) prcl);
|
|
|
|
|
|
|
|
/* swap the coordinates to make right >= left and bottom >= top */
|
|
|
|
/* (region building rectangles are normalized the same way) */
|
|
|
|
if ( prcl->top > prcl->bottom)
|
|
|
|
{
|
|
|
|
rc.top = prcl->bottom;
|
|
|
|
rc.bottom = prcl->top;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rc.top = prcl->top;
|
|
|
|
rc.bottom = prcl->bottom;
|
|
|
|
}
|
|
|
|
if ( prcl->right < prcl->left)
|
|
|
|
{
|
|
|
|
rc.right = prcl->left;
|
|
|
|
rc.left = prcl->right;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rc.right = prcl->right;
|
|
|
|
rc.left = prcl->left;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ComplexityFromRects( (PRECT)&pRgn_Attr->Rect, &rc) != COMPLEXREGION )
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
2009-12-23 23:10:32 +00:00
|
|
|
}
|
|
|
|
|
2007-12-31 17:26:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
int WINAPI
|
2007-12-31 17:26:57 +00:00
|
|
|
SelectClipRgn(
|
|
|
|
HDC hdc,
|
|
|
|
HRGN hrgn
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
|
|
|
|
}
|
2007-11-27 05:40:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 05:40:50 +00:00
|
|
|
SetRectRgn(HRGN hrgn,
|
|
|
|
int nLeftRect,
|
|
|
|
int nTopRect,
|
|
|
|
int nRightRect,
|
|
|
|
int nBottomRect)
|
|
|
|
{
|
2007-12-31 17:26:57 +00:00
|
|
|
PRGN_ATTR Rgn_Attr;
|
2007-11-27 05:40:50 +00:00
|
|
|
|
2009-12-24 07:42:38 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
|
2007-11-27 05:40:50 +00:00
|
|
|
return NtGdiSetRectRgn(hrgn, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
2009-12-23 23:10:32 +00:00
|
|
|
|
2007-11-27 05:40:50 +00:00
|
|
|
if ((nLeftRect == nRightRect) || (nTopRect == nBottomRect))
|
|
|
|
{
|
2009-12-23 23:10:32 +00:00
|
|
|
Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY;
|
|
|
|
Rgn_Attr->Flags = NULLREGION;
|
|
|
|
Rgn_Attr->Rect.left = Rgn_Attr->Rect.top =
|
|
|
|
Rgn_Attr->Rect.right = Rgn_Attr->Rect.bottom = 0;
|
2007-11-27 05:40:50 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
Rgn_Attr->Rect.left = nLeftRect;
|
|
|
|
Rgn_Attr->Rect.top = nTopRect;
|
|
|
|
Rgn_Attr->Rect.right = nRightRect;
|
|
|
|
Rgn_Attr->Rect.bottom = nBottomRect;
|
2007-11-27 05:40:50 +00:00
|
|
|
|
|
|
|
if(nLeftRect > nRightRect)
|
|
|
|
{
|
2009-12-23 23:10:32 +00:00
|
|
|
Rgn_Attr->Rect.left = nRightRect;
|
|
|
|
Rgn_Attr->Rect.right = nLeftRect;
|
2007-11-27 05:40:50 +00:00
|
|
|
}
|
|
|
|
if(nTopRect > nBottomRect)
|
|
|
|
{
|
2009-12-23 23:10:32 +00:00
|
|
|
Rgn_Attr->Rect.top = nBottomRect;
|
|
|
|
Rgn_Attr->Rect.bottom = nTopRect;
|
2007-11-27 05:40:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-23 23:10:32 +00:00
|
|
|
Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY ;
|
|
|
|
Rgn_Attr->Flags = SIMPLEREGION;
|
2007-11-27 05:40:50 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2008-01-09 04:15:42 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-01-09 04:15:42 +00:00
|
|
|
SetMetaRgn( HDC hDC )
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_DC)
|
|
|
|
return NtGdiSetMetaRgn(hDC);
|
|
|
|
#if 0
|
|
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
|
|
if ( pLDC && GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_METADC )
|
|
|
|
{
|
|
|
|
if (pLDC->iType == LDC_EMFLDC || EMFDRV_SetMetaRgn(hDC))
|
|
|
|
{
|
|
|
|
return NtGdiSetMetaRgn(hDC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-24 07:42:38 +00:00
|
|
|
return ERROR;
|
2008-01-09 04:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|