Commit 07439cd2 authored by Alexandre Julliard's avatar Alexandre Julliard

Removed dependencies on the internals of the region object.

Do not store the region type in the object, it's trivial to determine from the rectangle count. Rewrote a few routines to not depend on internal clipping or region functions.
parent 6a967492
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <string.h> #include <string.h>
#include "gdi.h" #include "gdi.h"
#include "region.h"
#include "mfdrv/metafiledrv.h" #include "mfdrv/metafiledrv.h"
#include "wine/debug.h" #include "wine/debug.h"
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "gdi.h" #include "gdi.h"
#include "ttydrv.h" #include "ttydrv.h"
#include "region.h"
#include "win.h" #include "win.h"
#include "winpos.h" #include "winpos.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -203,6 +202,7 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec ...@@ -203,6 +202,7 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
WND *pWnd; WND *pWnd;
int i; int i;
HWND *list = WIN_ListChildren( parent ); HWND *list = WIN_ListChildren( parent );
HRGN hrgn = 0;
if (!list) return; if (!list) return;
for (i = 0; list[i]; i++) for (i = 0; list[i]; i++)
...@@ -217,15 +217,14 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec ...@@ -217,15 +217,14 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
rect.bottom = pWnd->rectWindow.bottom + y; rect.bottom = pWnd->rectWindow.bottom + y;
if( IntersectRect( &rect, &rect, lpRect )) if( IntersectRect( &rect, &rect, lpRect ))
{ {
if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) if (!hrgn) hrgn = CreateRectRgnIndirect( &rect );
{ else SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
WIN_ReleaseWndPtr( pWnd ); CombineRgn( hrgnClip, hrgnClip, hrgn, RGN_OR );
break;
}
} }
} }
WIN_ReleaseWndPtr( pWnd ); WIN_ReleaseWndPtr( pWnd );
} }
if (hrgn) DeleteObject( hrgn );
HeapFree( GetProcessHeap(), 0, list ); HeapFree( GetProcessHeap(), 0, list );
} }
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "hook.h" #include "hook.h"
#include "win.h" #include "win.h"
#include "winpos.h" #include "winpos.h"
#include "region.h"
#include "dce.h" #include "dce.h"
#include "cursoricon.h" #include "cursoricon.h"
#include "nonclient.h" #include "nonclient.h"
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "winnt.h" #include "winnt.h"
#include "x11drv.h" #include "x11drv.h"
#include "bitmap.h" #include "bitmap.h"
#include "region.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -563,8 +562,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -563,8 +562,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
XRenderColor col; XRenderColor col;
int idx; int idx;
TEXTMETRICW tm; TEXTMETRICW tm;
RGNOBJ *obj; RGNDATA *data;
XRectangle *pXrect;
SIZE sz; SIZE sz;
RECT rc; RECT rc;
BOOL done_extents = FALSE; BOOL done_extents = FALSE;
...@@ -713,12 +711,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -713,12 +711,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
SaveVisRgn16( hdc ); SaveVisRgn16( hdc );
CLIPPING_IntersectVisRect( dc, rc.left, rc.top, rc.right, IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
rc.bottom, FALSE );
} }
if(!physDev->xrender->pict) { if(!physDev->xrender->pict) {
XRenderPictureAttributes pa; XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors; pa.subwindow_mode = IncludeInferiors;
...@@ -736,53 +731,15 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag ...@@ -736,53 +731,15 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
TRACE("using existing pict = %lx dc = %p\n", physDev->xrender->pict, dc); TRACE("using existing pict = %lx dc = %p\n", physDev->xrender->pict, dc);
} }
obj = (RGNOBJ *) GDI_GetObjPtr(dc->hGCClipRgn, REGION_MAGIC); if ((data = X11DRV_GetRegionData( dc->hGCClipRgn, 0 )))
if (!obj)
{
ERR("Rgn is 0. Please report this.\n");
return FALSE;
}
if (obj->rgn->numRects > 0)
{ {
XRectangle *pXr; wine_tsx11_lock();
RECT *pRect = obj->rgn->rects; pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects; 0, 0, (XRectangle *)data->Buffer, data->rdh.nCount );
wine_tsx11_unlock();
pXrect = HeapAlloc( GetProcessHeap(), 0, HeapFree( GetProcessHeap(), 0, data );
sizeof(*pXrect) * obj->rgn->numRects );
if(!pXrect)
{
WARN("Can't alloc buffer\n");
GDI_ReleaseObj( dc->hGCClipRgn );
return FALSE;
}
for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
{
pXr->x = pRect->left;
pXr->y = pRect->top;
pXr->width = pRect->right - pRect->left;
pXr->height = pRect->bottom - pRect->top;
TRACE("Adding clip rect %d,%d - %d,%d\n", pRect->left, pRect->top,
pRect->right, pRect->bottom);
}
}
else {
TRACE("no clip rgn\n");
pXrect = NULL;
} }
wine_tsx11_lock();
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
0, 0, pXrect, obj->rgn->numRects );
wine_tsx11_unlock();
if(pXrect)
HeapFree( GetProcessHeap(), 0, pXrect );
GDI_ReleaseObj( dc->hGCClipRgn );
if(GetBkMode(hdc) != TRANSPARENT) { if(GetBkMode(hdc) != TRANSPARENT) {
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) { if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) {
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right || if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
......
...@@ -26,62 +26,100 @@ ...@@ -26,62 +26,100 @@
#include "gdi.h" #include "gdi.h"
#include "x11drv.h" #include "x11drv.h"
#include "region.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv); WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
/*********************************************************************** /***********************************************************************
* X11DRV_SetDeviceClipping * X11DRV_GetRegionData
* Copy RECT32s to a temporary buffer of XRectangles and call
* TSXSetClipRectangles().
* *
* Could write using GetRegionData but this would be slower. * Calls GetRegionData on the given region and converts the rectangle
* array to XRectangle format. The returned buffer must be freed by
* caller using HeapFree(GetProcessHeap(),...).
* If hdc_lptodp is not 0, the rectangles are converted through LPtoDP.
*/ */
void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn ) RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
{ {
XRectangle *pXrect; RGNDATA *data;
DWORD size;
int i;
RECT *rect, tmp;
XRectangle *xrect;
if (!(size = GetRegionData( hrgn, 0, NULL ))) return NULL;
if (sizeof(XRectangle) > sizeof(RECT))
{
/* add extra size for XRectangle array */
int count = (size - sizeof(RGNDATAHEADER)) / sizeof(RECT);
size += count * (sizeof(XRectangle) - sizeof(RECT));
}
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
if (!GetRegionData( hrgn, size, data ))
{
HeapFree( GetProcessHeap(), 0, data );
return NULL;
}
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(hrgn, REGION_MAGIC); rect = (RECT *)data->Buffer;
if (!obj) xrect = (XRectangle *)data->Buffer;
if (hdc_lptodp) /* map to device coordinates */
{ {
ERR("Rgn is 0. Please report this.\n"); LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
return; for (i = 0; i < data->rdh.nCount; i++)
{
if (rect[i].right < rect[i].left)
{
INT tmp = rect[i].right;
rect[i].right = rect[i].left;
rect[i].left = tmp;
}
if (rect[i].bottom < rect[i].top)
{
INT tmp = rect[i].bottom;
rect[i].bottom = rect[i].top;
rect[i].top = tmp;
}
}
} }
if (obj->rgn->numRects > 0) if (sizeof(XRectangle) > sizeof(RECT))
{ {
XRectangle *pXr; /* need to start from the end */
RECT *pRect = obj->rgn->rects; for (i = data->rdh.nCount-1; i >=0; i--)
RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects;
pXrect = HeapAlloc( GetProcessHeap(), 0,
sizeof(*pXrect) * obj->rgn->numRects );
if(!pXrect)
{
WARN("Can't alloc buffer\n");
GDI_ReleaseObj( hrgn );
return;
}
for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
{ {
pXr->x = pRect->left; tmp = rect[i];
pXr->y = pRect->top; xrect[i].x = tmp.left;
pXr->width = pRect->right - pRect->left; xrect[i].y = tmp.top;
pXr->height = pRect->bottom - pRect->top; xrect[i].width = tmp.right - tmp.left;
xrect[i].height = tmp.bottom - tmp.top;
} }
} }
else else
pXrect = NULL; {
for (i = 0; i < data->rdh.nCount; i++)
{
tmp = rect[i];
xrect[i].x = tmp.left;
xrect[i].y = tmp.top;
xrect[i].width = tmp.right - tmp.left;
xrect[i].height = tmp.bottom - tmp.top;
}
}
return data;
}
TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
pXrect, obj->rgn->numRects, YXBanded );
if(pXrect) /***********************************************************************
HeapFree( GetProcessHeap(), 0, pXrect ); * X11DRV_SetDeviceClipping
*/
void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn )
{
RGNDATA *data;
GDI_ReleaseObj( hrgn ); if (!(data = X11DRV_GetRegionData( hrgn, 0 ))) return;
TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
HeapFree( GetProcessHeap(), 0, data );
} }
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include "bitmap.h" #include "bitmap.h"
#include "gdi.h" #include "gdi.h"
#include "palette.h" #include "palette.h"
#include "region.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(graphics); WINE_DEFAULT_DEBUG_CHANNEL(graphics);
...@@ -940,48 +939,29 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y ) ...@@ -940,48 +939,29 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y )
BOOL BOOL
X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn ) X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn )
{ {
RECT box;
HRGN tmpVisRgn, prevVisRgn;
DC *dc = physDev->dc; DC *dc = physDev->dc;
HDC hdc = physDev->hdc; /* FIXME: should not mix dc/hdc this way */
if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
/* Transform region into device co-ords */
if ( !REGION_LPTODP( hdc, tmpVisRgn, hrgn )
|| OffsetRgn( tmpVisRgn, dc->DCOrgX, dc->DCOrgY ) == ERROR) {
DeleteObject( tmpVisRgn );
return FALSE;
}
/* Modify visible region */
if (!(prevVisRgn = SaveVisRgn16( hdc ))) {
DeleteObject( tmpVisRgn );
return FALSE;
}
CombineRgn( tmpVisRgn, prevVisRgn, tmpVisRgn, RGN_AND );
SelectVisRgn16( hdc, tmpVisRgn );
DeleteObject( tmpVisRgn );
/* Fill the region */
GetRgnBox( dc->hGCClipRgn, &box );
if (X11DRV_SetupGCForBrush( physDev )) if (X11DRV_SetupGCForBrush( physDev ))
{ {
/* Update the pixmap from the DIB section */ int i;
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE); XRectangle *rect;
RGNDATA *data = X11DRV_GetRegionData( hrgn, physDev->hdc );
TSXFillRectangle( gdi_display, physDev->drawable, physDev->gc, if (!data) return FALSE;
box.left, box.top, rect = (XRectangle *)data->Buffer;
box.right-box.left, box.bottom-box.top ); for (i = 0; i < data->rdh.nCount; i++)
{
/* Update the DIBSection from the pixmap */ rect[i].x += dc->DCOrgX;
X11DRV_UnlockDIBSection(physDev, TRUE); rect[i].y += dc->DCOrgY;
} }
/* Restore the visible region */
RestoreVisRgn16( hdc ); X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
wine_tsx11_lock();
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
wine_tsx11_unlock();
X11DRV_UnlockDIBSection(physDev, TRUE);
HeapFree( GetProcessHeap(), 0, data );
}
return TRUE; return TRUE;
} }
......
...@@ -151,7 +151,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, ...@@ -151,7 +151,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
{ {
SIZE sz; SIZE sz;
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz )) if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
return FALSE; {
result = FALSE;
goto END;
}
width = INTERNAL_XWSTODS(dc, sz.cx); width = INTERNAL_XWSTODS(dc, sz.cx);
} }
ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent; ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
...@@ -206,8 +209,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, ...@@ -206,8 +209,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
SaveVisRgn16( dc->hSelf ); SaveVisRgn16( dc->hSelf );
CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right, IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
rect.bottom, FALSE );
} }
/* Draw the text background if necessary */ /* Draw the text background if necessary */
...@@ -395,9 +397,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, ...@@ -395,9 +397,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
dc->DCOrgX + x + width, dc->DCOrgY + y - lineAscent ); dc->DCOrgX + x + width, dc->DCOrgY + y - lineAscent );
} }
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED) RestoreVisRgn16( dc->hSelf );
RestoreVisRgn16( dc->hSelf );
goto END; goto END;
FAIL: FAIL:
......
...@@ -580,16 +580,7 @@ extern DC * DC_GetDCUpdate( HDC hdc ); ...@@ -580,16 +580,7 @@ extern DC * DC_GetDCUpdate( HDC hdc );
extern void DC_InitDC( DC * dc ); extern void DC_InitDC( DC * dc );
extern void DC_UpdateXforms( DC * dc ); extern void DC_UpdateXforms( DC * dc );
#define CLIP_INTERSECT 0x0001
#define CLIP_EXCLUDE 0x0002
#define CLIP_KEEPRGN 0x0004
/* objects/clipping.c */ /* objects/clipping.c */
INT CLIPPING_IntersectClipRect( DC * dc, INT left, INT top,
INT right, INT bottom, UINT flags );
INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
INT right, INT bottom, BOOL exclude );
extern void CLIPPING_UpdateGCRegion( DC * dc ); extern void CLIPPING_UpdateGCRegion( DC * dc );
/* objects/enhmetafile.c */ /* objects/enhmetafile.c */
......
...@@ -25,26 +25,11 @@ ...@@ -25,26 +25,11 @@
#include "windef.h" #include "windef.h"
#include "wingdi.h" #include "wingdi.h"
typedef struct { struct _RGNOBJ;
INT size;
INT numRects;
INT type; /* NULL, SIMPLE or COMPLEX */
RECT *rects;
RECT extents;
} WINEREGION;
/* GDI logical region object */ extern BOOL REGION_DeleteObject( HRGN hrgn, struct _RGNOBJ * obj );
typedef struct
{
GDIOBJHDR header;
WINEREGION *rgn;
} RGNOBJ;
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
extern BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );
extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt ); extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ); extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
extern BOOL REGION_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc );
#endif /* __WINE_REGION_H */ #endif /* __WINE_REGION_H */
......
...@@ -198,6 +198,7 @@ extern HBITMAP X11DRV_BITMAP_CreateBitmapFromPixmap(Pixmap pixmap, BOOL bDeleteP ...@@ -198,6 +198,7 @@ extern HBITMAP X11DRV_BITMAP_CreateBitmapFromPixmap(Pixmap pixmap, BOOL bDeleteP
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc ); extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc ); extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp );
extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y ); extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y );
extern void X11DRV_StartGraphicsExposures( HDC hdc ); extern void X11DRV_StartGraphicsExposures( HDC hdc );
extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn ); extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "wingdi.h" #include "wingdi.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "gdi.h" #include "gdi.h"
#include "region.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(clipping); WINE_DEFAULT_DEBUG_CHANNEL(clipping);
...@@ -205,54 +204,6 @@ INT16 WINAPI OffsetVisRgn16( HDC16 hdc, INT16 x, INT16 y ) ...@@ -205,54 +204,6 @@ INT16 WINAPI OffsetVisRgn16( HDC16 hdc, INT16 x, INT16 y )
/*********************************************************************** /***********************************************************************
* CLIPPING_IntersectClipRect
*
* Helper function for {Intersect,Exclude}ClipRect, can be called from
* elsewhere (like ExtTextOut()) to skip redundant metafile update and
* coordinate conversion.
*/
INT CLIPPING_IntersectClipRect( DC * dc, INT left, INT top,
INT right, INT bottom, UINT flags )
{
HRGN newRgn;
INT ret;
left += dc->DCOrgX;
right += dc->DCOrgX;
top += dc->DCOrgY;
bottom += dc->DCOrgY;
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) return ERROR;
if (!dc->hClipRgn)
{
if( flags & CLIP_INTERSECT )
{
dc->hClipRgn = newRgn;
CLIPPING_UpdateGCRegion( dc );
return SIMPLEREGION;
}
else if( flags & CLIP_EXCLUDE )
{
dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( dc->hClipRgn, dc->hVisRgn, 0, RGN_COPY );
}
else WARN("No hClipRgn and flags are %x\n",flags);
}
ret = CombineRgn( newRgn, dc->hClipRgn, newRgn,
(flags & CLIP_EXCLUDE) ? RGN_DIFF : RGN_AND );
if (ret != ERROR)
{
if (!(flags & CLIP_KEEPRGN)) DeleteObject( dc->hClipRgn );
dc->hClipRgn = newRgn;
CLIPPING_UpdateGCRegion( dc );
}
else DeleteObject( newRgn );
return ret;
}
/***********************************************************************
* ExcludeClipRect (GDI.21) * ExcludeClipRect (GDI.21)
*/ */
INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top, INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
...@@ -268,6 +219,7 @@ INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top, ...@@ -268,6 +219,7 @@ INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top, INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
INT right, INT bottom ) INT right, INT bottom )
{ {
HRGN newRgn;
INT ret; INT ret;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR; if (!dc) return ERROR;
...@@ -276,13 +228,25 @@ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top, ...@@ -276,13 +228,25 @@ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
if(dc->funcs->pExcludeClipRect) if(dc->funcs->pExcludeClipRect)
ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom ); ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
else { else
left = XLPTODP( dc, left ); {
right = XLPTODP( dc, right ); left = dc->DCOrgX + XLPTODP( dc, left );
top = YLPTODP( dc, top ); right = dc->DCOrgX + XLPTODP( dc, right );
bottom = YLPTODP( dc, bottom ); top = dc->DCOrgY + YLPTODP( dc, top );
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_EXCLUDE ); if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
else
{
if (!dc->hClipRgn)
{
dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( dc->hClipRgn, dc->hVisRgn, 0, RGN_COPY );
}
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_DIFF );
DeleteObject( newRgn );
}
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
} }
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
...@@ -313,66 +277,32 @@ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top, ...@@ -313,66 +277,32 @@ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top,
if(dc->funcs->pIntersectClipRect) if(dc->funcs->pIntersectClipRect)
ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom ); ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
else { else
left = XLPTODP( dc, left );
right = XLPTODP( dc, right );
top = YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom );
ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_INTERSECT );
}
GDI_ReleaseObj( hdc );
return ret;
}
/***********************************************************************
* CLIPPING_IntersectVisRect
*
* Helper function for {Intersect,Exclude}VisRect, can be called from
* elsewhere (like ExtTextOut()) to skip redundant metafile update and
* coordinate conversion.
*/
INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
INT right, INT bottom,
BOOL exclude )
{
HRGN tempRgn, newRgn;
INT ret;
left += dc->DCOrgX;
right += dc->DCOrgX;
top += dc->DCOrgY;
bottom += dc->DCOrgY;
if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
{ {
DeleteObject( newRgn ); left = dc->DCOrgX + XLPTODP( dc, left );
return ERROR; right = dc->DCOrgX + XLPTODP( dc, right );
} top = dc->DCOrgY + YLPTODP( dc, top );
ret = CombineRgn( newRgn, dc->hVisRgn, tempRgn, bottom = dc->DCOrgY + YLPTODP( dc, bottom );
exclude ? RGN_DIFF : RGN_AND );
DeleteObject( tempRgn );
if (ret != ERROR) if (!dc->hClipRgn)
{
RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
if (newObj)
{ {
RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC); dc->hClipRgn = CreateRectRgn( left, top, right, bottom );
if (prevObj) ret = SIMPLEREGION;
}
else
{
HRGN newRgn;
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
else
{ {
newObj->header.hNext = prevObj->header.hNext; ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND );
GDI_ReleaseObj( dc->hVisRgn ); DeleteObject( newRgn );
} }
GDI_ReleaseObj( newRgn );
} }
DeleteObject( dc->hVisRgn ); if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
dc->hVisRgn = newRgn;
CLIPPING_UpdateGCRegion( dc );
} }
else DeleteObject( newRgn ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
...@@ -383,18 +313,25 @@ INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top, ...@@ -383,18 +313,25 @@ INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top, INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
INT16 right, INT16 bottom ) INT16 right, INT16 bottom )
{ {
HRGN tempRgn;
INT16 ret; INT16 ret;
DC * dc = DC_GetDCUpdate( hdc ); DC * dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR; if (!dc) return ERROR;
left = XLPTODP( dc, left ); left = dc->DCOrgX + XLPTODP( dc, left );
right = XLPTODP( dc, right ); right = dc->DCOrgX + XLPTODP( dc, right );
top = YLPTODP( dc, top ); top = dc->DCOrgY + YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom ); bottom = dc->DCOrgY + YLPTODP( dc, bottom );
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE ); if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
else
{
ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_DIFF );
DeleteObject( tempRgn );
}
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
...@@ -406,18 +343,25 @@ INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top, ...@@ -406,18 +343,25 @@ INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top, INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top,
INT16 right, INT16 bottom ) INT16 right, INT16 bottom )
{ {
HRGN tempRgn;
INT16 ret; INT16 ret;
DC * dc = DC_GetDCUpdate( hdc ); DC * dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR; if (!dc) return ERROR;
left = XLPTODP( dc, left ); left = dc->DCOrgX + XLPTODP( dc, left );
right = XLPTODP( dc, right ); right = dc->DCOrgX + XLPTODP( dc, right );
top = YLPTODP( dc, top ); top = dc->DCOrgY + YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom ); bottom = dc->DCOrgY + YLPTODP( dc, bottom );
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom ); TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE ); if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
else
{
ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_AND );
DeleteObject( tempRgn );
}
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
...@@ -562,13 +506,13 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn ) ...@@ -562,13 +506,13 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
HRGN16 WINAPI SaveVisRgn16( HDC16 hdc ) HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
{ {
HRGN copy; HRGN copy;
RGNOBJ *obj, *copyObj; GDIOBJHDR *obj, *copyObj;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return 0; if (!dc) return 0;
TRACE("%04x\n", hdc ); TRACE("%04x\n", hdc );
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
{ {
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return 0; return 0;
...@@ -580,15 +524,15 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc ) ...@@ -580,15 +524,15 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
return 0; return 0;
} }
CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY ); CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY );
if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC ))) if (!(copyObj = GDI_GetObjPtr( copy, REGION_MAGIC )))
{ {
DeleteObject( copy ); DeleteObject( copy );
GDI_ReleaseObj( dc->hVisRgn ); GDI_ReleaseObj( dc->hVisRgn );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return 0; return 0;
} }
copyObj->header.hNext = obj->header.hNext; copyObj->hNext = obj->hNext;
obj->header.hNext = copy; obj->hNext = copy;
GDI_ReleaseObj( copy ); GDI_ReleaseObj( copy );
GDI_ReleaseObj( dc->hVisRgn ); GDI_ReleaseObj( dc->hVisRgn );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
...@@ -602,25 +546,27 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc ) ...@@ -602,25 +546,27 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
INT16 WINAPI RestoreVisRgn16( HDC16 hdc ) INT16 WINAPI RestoreVisRgn16( HDC16 hdc )
{ {
HRGN saved; HRGN saved;
RGNOBJ *obj, *savedObj; GDIOBJHDR *obj, *savedObj;
DC *dc = DC_GetDCPtr( hdc ); DC *dc = DC_GetDCPtr( hdc );
INT16 ret = ERROR; INT16 ret = ERROR;
if (!dc) return ERROR; if (!dc) return ERROR;
if (!dc->hVisRgn) goto done;
TRACE("%04x\n", hdc ); TRACE("%04x\n", hdc );
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
saved = obj->header.hNext; if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
GDI_ReleaseObj( dc->hVisRgn ); saved = obj->hNext;
if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;
DeleteObject( dc->hVisRgn ); if ((savedObj = GDI_GetObjPtr( saved, REGION_MAGIC )))
dc->hVisRgn = saved; {
dc->flags &= ~DC_DIRTY; ret = CombineRgn( dc->hVisRgn, saved, 0, RGN_COPY );
CLIPPING_UpdateGCRegion( dc ); obj->hNext = savedObj->hNext;
ret = savedObj->rgn->type; /* FIXME */ GDI_ReleaseObj( saved );
GDI_ReleaseObj( saved ); DeleteObject( saved );
dc->flags &= ~DC_DIRTY;
CLIPPING_UpdateGCRegion( dc );
}
GDI_ReleaseObj( dc->hVisRgn );
done: done:
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
......
...@@ -897,7 +897,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) ...@@ -897,7 +897,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header ); case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header );
case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header); case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header); case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header ); case REGION_MAGIC: return REGION_DeleteObject( obj, (struct _RGNOBJ*)header );
case DC_MAGIC: case DC_MAGIC:
GDI_ReleaseObj( obj ); GDI_ReleaseObj( obj );
return DeleteDC(obj); return DeleteDC(obj);
......
...@@ -104,6 +104,21 @@ SOFTWARE. ...@@ -104,6 +104,21 @@ SOFTWARE.
WINE_DEFAULT_DEBUG_CHANNEL(region); WINE_DEFAULT_DEBUG_CHANNEL(region);
typedef struct {
INT size;
INT numRects;
RECT *rects;
RECT extents;
} WINEREGION;
/* GDI logical region object */
typedef struct _RGNOBJ
{
GDIOBJHDR header;
WINEREGION *rgn;
} RGNOBJ;
/* 1 if two RECTs overlap. /* 1 if two RECTs overlap.
* 0 if two RECTs do not overlap. * 0 if two RECTs do not overlap.
*/ */
...@@ -134,7 +149,6 @@ static inline int xmemcheck(WINEREGION *reg, LPRECT *rect, LPRECT *firstrect ) { ...@@ -134,7 +149,6 @@ static inline int xmemcheck(WINEREGION *reg, LPRECT *rect, LPRECT *firstrect ) {
(pReg)->numRects = 0; \ (pReg)->numRects = 0; \
(pReg)->extents.left = (pReg)->extents.top = 0; \ (pReg)->extents.left = (pReg)->extents.top = 0; \
(pReg)->extents.right = (pReg)->extents.bottom = 0; \ (pReg)->extents.right = (pReg)->extents.bottom = 0; \
(pReg)->type = NULLREGION; \
} }
#define REGION_NOT_EMPTY(pReg) pReg->numRects #define REGION_NOT_EMPTY(pReg) pReg->numRects
...@@ -423,6 +437,21 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn); ...@@ -423,6 +437,21 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);
#define RGN_DEFAULT_RECTS 2 #define RGN_DEFAULT_RECTS 2
/***********************************************************************
* get_region_type
*/
inline static INT get_region_type( const RGNOBJ *obj )
{
switch(obj->rgn->numRects)
{
case 0: return NULLREGION;
case 1: return SIMPLEREGION;
default: return COMPLEXREGION;
}
}
/*********************************************************************** /***********************************************************************
* REGION_DumpRegion * REGION_DumpRegion
* Outputs the contents of a WINEREGION * Outputs the contents of a WINEREGION
...@@ -542,7 +571,7 @@ INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y ) ...@@ -542,7 +571,7 @@ INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y )
obj->rgn->extents.bottom += y; obj->rgn->extents.bottom += y;
} }
} }
ret = obj->rgn->type; ret = get_region_type( obj );
GDI_ReleaseObj( hrgn ); GDI_ReleaseObj( hrgn );
return ret; return ret;
} }
...@@ -573,7 +602,7 @@ INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect ) ...@@ -573,7 +602,7 @@ INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect )
rect->top = obj->rgn->extents.top; rect->top = obj->rgn->extents.top;
rect->right = obj->rgn->extents.right; rect->right = obj->rgn->extents.right;
rect->bottom = obj->rgn->extents.bottom; rect->bottom = obj->rgn->extents.bottom;
ret = obj->rgn->type; ret = get_region_type( obj );
GDI_ReleaseObj(hrgn); GDI_ReleaseObj(hrgn);
return ret; return ret;
} }
...@@ -671,8 +700,7 @@ BOOL WINAPI SetRectRgn( HRGN hrgn, INT left, INT top, ...@@ -671,8 +700,7 @@ BOOL WINAPI SetRectRgn( HRGN hrgn, INT left, INT top,
obj->rgn->rects->top = obj->rgn->extents.top = top; obj->rgn->rects->top = obj->rgn->extents.top = top;
obj->rgn->rects->right = obj->rgn->extents.right = right; obj->rgn->rects->right = obj->rgn->extents.right = right;
obj->rgn->rects->bottom = obj->rgn->extents.bottom = bottom; obj->rgn->rects->bottom = obj->rgn->extents.bottom = bottom;
obj->rgn->numRects = 1; obj->rgn->numRects = 1;
obj->rgn->type = SIMPLEREGION;
} }
else else
EMPTY_REGION(obj->rgn); EMPTY_REGION(obj->rgn);
...@@ -804,7 +832,6 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top, ...@@ -804,7 +832,6 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
rect.bottom = bottom; rect.bottom = bottom;
REGION_UnionRectWithRegion( &rect, obj->rgn ); REGION_UnionRectWithRegion( &rect, obj->rgn );
} }
obj->rgn->type = SIMPLEREGION; /* FIXME? */
GDI_ReleaseObj( hrgn ); GDI_ReleaseObj( hrgn );
return hrgn; return hrgn;
} }
...@@ -1091,10 +1118,10 @@ BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 ) ...@@ -1091,10 +1118,10 @@ BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 )
} }
return ret; return ret;
} }
/*********************************************************************** /***********************************************************************
* REGION_UnionRectWithRegion * REGION_UnionRectWithRegion
* Adds a rectangle to a WINEREGION * Adds a rectangle to a WINEREGION
* See below for REGION_UnionRectWithRgn
*/ */
static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn) static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
{ {
...@@ -1103,26 +1130,10 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn) ...@@ -1103,26 +1130,10 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
region.rects = &region.extents; region.rects = &region.extents;
region.numRects = 1; region.numRects = 1;
region.size = 1; region.size = 1;
region.type = SIMPLEREGION;
region.extents = *rect; region.extents = *rect;
REGION_UnionRegion(rgn, rgn, &region); REGION_UnionRegion(rgn, rgn, &region);
return;
} }
/***********************************************************************
* REGION_UnionRectWithRgn
* Adds a rectangle to a HRGN
* A helper used by scroll.c
*/
BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
{
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
if(!obj) return FALSE;
REGION_UnionRectWithRegion( lpRect, obj->rgn );
GDI_ReleaseObj(hrgn);
return TRUE;
}
/*********************************************************************** /***********************************************************************
* REGION_CreateFrameRgn * REGION_CreateFrameRgn
...@@ -1163,66 +1174,7 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y ) ...@@ -1163,66 +1174,7 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
return bRet; return bRet;
} }
/***********************************************************************
* REGION_LPTODP
*
* Convert region to device co-ords for the supplied dc.
*/
BOOL REGION_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc )
{
RECT *pCurRect, *pEndRect;
RGNOBJ *srcObj, *destObj;
DC * dc = DC_GetDCPtr( hdc );
RECT tmpRect;
BOOL ret = FALSE;
TRACE(" hdc=%04x dest=%04x src=%04x\n",
hdc, hDest, hSrc) ;
if (!dc) return ret;
if (dc->MapMode == MM_TEXT) /* Requires only a translation */
{
if( CombineRgn( hDest, hSrc, 0, RGN_COPY ) == ERROR ) goto done;
OffsetRgn( hDest, dc->vportOrgX - dc->wndOrgX,
dc->vportOrgY - dc->wndOrgY );
ret = TRUE;
goto done;
}
if(!( srcObj = (RGNOBJ *) GDI_GetObjPtr( hSrc, REGION_MAGIC) ))
goto done;
if(!( destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC) ))
{
GDI_ReleaseObj( hSrc );
goto done;
}
EMPTY_REGION( destObj->rgn );
pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
for(pCurRect = srcObj->rgn->rects; pCurRect < pEndRect; pCurRect++)
{
tmpRect = *pCurRect;
tmpRect.left = XLPTODP( dc, tmpRect.left );
tmpRect.top = YLPTODP( dc, tmpRect.top );
tmpRect.right = XLPTODP( dc, tmpRect.right );
tmpRect.bottom = YLPTODP( dc, tmpRect.bottom );
if (tmpRect.left > tmpRect.right)
{ INT tmp = tmpRect.left; tmpRect.left = tmpRect.right; tmpRect.right = tmp; }
if (tmpRect.top > tmpRect.bottom)
{ INT tmp = tmpRect.top; tmpRect.top = tmpRect.bottom; tmpRect.bottom = tmp; }
REGION_UnionRectWithRegion( &tmpRect, destObj->rgn );
}
ret = TRUE;
GDI_ReleaseObj( hDest );
GDI_ReleaseObj( hSrc );
done:
GDI_ReleaseObj( hdc );
return ret;
}
/*********************************************************************** /***********************************************************************
* CombineRgn (GDI.47) * CombineRgn (GDI.47)
*/ */
...@@ -1256,7 +1208,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode) ...@@ -1256,7 +1208,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
if (mode == RGN_COPY) if (mode == RGN_COPY)
{ {
REGION_CopyRegion( destObj->rgn, src1Obj->rgn ); REGION_CopyRegion( destObj->rgn, src1Obj->rgn );
result = destObj->rgn->type; result = get_region_type( destObj );
} }
else else
{ {
...@@ -1282,7 +1234,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode) ...@@ -1282,7 +1234,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
REGION_SubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn ); REGION_SubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
break; break;
} }
result = destObj->rgn->type; result = get_region_type( destObj );
GDI_ReleaseObj( hSrc2 ); GDI_ReleaseObj( hSrc2 );
} }
} }
...@@ -1361,8 +1313,6 @@ static void REGION_CopyRegion(WINEREGION *dst, WINEREGION *src) ...@@ -1361,8 +1313,6 @@ static void REGION_CopyRegion(WINEREGION *dst, WINEREGION *src)
dst->extents.top = src->extents.top; dst->extents.top = src->extents.top;
dst->extents.right = src->extents.right; dst->extents.right = src->extents.right;
dst->extents.bottom = src->extents.bottom; dst->extents.bottom = src->extents.bottom;
dst->type = src->type;
memcpy((char *) dst->rects, (char *) src->rects, memcpy((char *) dst->rects, (char *) src->rects,
(int) (src->numRects * sizeof(RECT))); (int) (src->numRects * sizeof(RECT)));
} }
...@@ -1892,10 +1842,6 @@ static void REGION_IntersectRegion(WINEREGION *newReg, WINEREGION *reg1, ...@@ -1892,10 +1842,6 @@ static void REGION_IntersectRegion(WINEREGION *newReg, WINEREGION *reg1,
* due to coalescing, so we have to examine fewer rectangles. * due to coalescing, so we have to examine fewer rectangles.
*/ */
REGION_SetExtents(newReg); REGION_SetExtents(newReg);
newReg->type = (newReg->numRects) ?
((newReg->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
: NULLREGION ;
return;
} }
/*********************************************************************** /***********************************************************************
...@@ -2071,10 +2017,6 @@ static void REGION_UnionRegion(WINEREGION *newReg, WINEREGION *reg1, ...@@ -2071,10 +2017,6 @@ static void REGION_UnionRegion(WINEREGION *newReg, WINEREGION *reg1,
newReg->extents.top = min(reg1->extents.top, reg2->extents.top); newReg->extents.top = min(reg1->extents.top, reg2->extents.top);
newReg->extents.right = max(reg1->extents.right, reg2->extents.right); newReg->extents.right = max(reg1->extents.right, reg2->extents.right);
newReg->extents.bottom = max(reg1->extents.bottom, reg2->extents.bottom); newReg->extents.bottom = max(reg1->extents.bottom, reg2->extents.bottom);
newReg->type = (newReg->numRects) ?
((newReg->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
: NULLREGION ;
return;
} }
/*********************************************************************** /***********************************************************************
...@@ -2279,10 +2221,6 @@ static void REGION_SubtractRegion(WINEREGION *regD, WINEREGION *regM, ...@@ -2279,10 +2221,6 @@ static void REGION_SubtractRegion(WINEREGION *regD, WINEREGION *regM,
* due to coalescing, so we have to examine fewer rectangles. * due to coalescing, so we have to examine fewer rectangles.
*/ */
REGION_SetExtents (regD); REGION_SetExtents (regD);
regD->type = (regD->numRects) ?
((regD->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
: NULLREGION ;
return;
} }
/*********************************************************************** /***********************************************************************
...@@ -2876,9 +2814,6 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count, ...@@ -2876,9 +2814,6 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
} }
REGION_FreeStorage(SLLBlock.next); REGION_FreeStorage(SLLBlock.next);
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
region->type = (region->numRects) ?
((region->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
: NULLREGION;
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
tmpPtBlock = curPtBlock->next; tmpPtBlock = curPtBlock->next;
...@@ -3120,8 +3055,6 @@ empty: ...@@ -3120,8 +3055,6 @@ empty:
rgnDst->extents.top = rgnDst->rects[0].top; rgnDst->extents.top = rgnDst->rects[0].top;
rgnDst->extents.bottom = rgnDst->rects[j].bottom; rgnDst->extents.bottom = rgnDst->rects[j].bottom;
rgnDst->type = (j >= 1) ? COMPLEXREGION : SIMPLEREGION;
if( TRACE_ON(region) ) if( TRACE_ON(region) )
{ {
TRACE("result:\n"); TRACE("result:\n");
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "dce.h" #include "dce.h"
#include "win.h" #include "win.h"
#include "gdi.h" #include "gdi.h"
#include "region.h"
#include "user.h" #include "user.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "windef.h" #include "windef.h"
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "wine/server.h" #include "wine/server.h"
#include "controls.h" #include "controls.h"
#include "user.h" #include "user.h"
#include "region.h"
#include "win.h" #include "win.h"
#include "hook.h" #include "hook.h"
#include "message.h" #include "message.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment