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.
diff --git a/dlls/gdi/mfdrv/graphics.c b/dlls/gdi/mfdrv/graphics.c
index c44dbc5..aa27b6b 100644
--- a/dlls/gdi/mfdrv/graphics.c
+++ b/dlls/gdi/mfdrv/graphics.c
@@ -22,7 +22,6 @@
#include <string.h>
#include "gdi.h"
-#include "region.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index 949f751..ac65fe7 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -22,7 +22,6 @@
#include "gdi.h"
#include "ttydrv.h"
-#include "region.h"
#include "win.h"
#include "winpos.h"
#include "wine/debug.h"
@@ -203,6 +202,7 @@
WND *pWnd;
int i;
HWND *list = WIN_ListChildren( parent );
+ HRGN hrgn = 0;
if (!list) return;
for (i = 0; list[i]; i++)
@@ -217,15 +217,14 @@
rect.bottom = pWnd->rectWindow.bottom + y;
if( IntersectRect( &rect, &rect, lpRect ))
{
- if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
- {
- WIN_ReleaseWndPtr( pWnd );
- break;
- }
+ if (!hrgn) hrgn = CreateRectRgnIndirect( &rect );
+ else SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
+ CombineRgn( hrgnClip, hrgnClip, hrgn, RGN_OR );
}
}
WIN_ReleaseWndPtr( pWnd );
}
+ if (hrgn) DeleteObject( hrgn );
HeapFree( GetProcessHeap(), 0, list );
}
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index dbde92b..06109bc 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -34,7 +34,6 @@
#include "hook.h"
#include "win.h"
#include "winpos.h"
-#include "region.h"
#include "dce.h"
#include "cursoricon.h"
#include "nonclient.h"
diff --git a/dlls/x11drv/xrender.c b/dlls/x11drv/xrender.c
index fe4c877..39b478f 100644
--- a/dlls/x11drv/xrender.c
+++ b/dlls/x11drv/xrender.c
@@ -27,7 +27,6 @@
#include "winnt.h"
#include "x11drv.h"
#include "bitmap.h"
-#include "region.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@@ -563,8 +562,7 @@
XRenderColor col;
int idx;
TEXTMETRICW tm;
- RGNOBJ *obj;
- XRectangle *pXrect;
+ RGNDATA *data;
SIZE sz;
RECT rc;
BOOL done_extents = FALSE;
@@ -713,12 +711,9 @@
if (flags & ETO_CLIPPED)
{
SaveVisRgn16( hdc );
- CLIPPING_IntersectVisRect( dc, rc.left, rc.top, rc.right,
- rc.bottom, FALSE );
+ IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
}
-
-
if(!physDev->xrender->pict) {
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors;
@@ -736,52 +731,14 @@
TRACE("using existing pict = %lx dc = %p\n", physDev->xrender->pict, dc);
}
- obj = (RGNOBJ *) GDI_GetObjPtr(dc->hGCClipRgn, REGION_MAGIC);
- if (!obj)
+ if ((data = X11DRV_GetRegionData( dc->hGCClipRgn, 0 )))
{
- ERR("Rgn is 0. Please report this.\n");
- return FALSE;
+ wine_tsx11_lock();
+ pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
+ 0, 0, (XRectangle *)data->Buffer, data->rdh.nCount );
+ wine_tsx11_unlock();
+ HeapFree( GetProcessHeap(), 0, data );
}
-
- if (obj->rgn->numRects > 0)
- {
- XRectangle *pXr;
- RECT *pRect = obj->rgn->rects;
- 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( 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(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) {
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index edd0987..cd74b84 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -26,62 +26,100 @@
#include "gdi.h"
#include "x11drv.h"
-#include "region.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
/***********************************************************************
- * X11DRV_SetDeviceClipping
- * Copy RECT32s to a temporary buffer of XRectangles and call
- * TSXSetClipRectangles().
+ * X11DRV_GetRegionData
*
- * 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;
- RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(hrgn, REGION_MAGIC);
- if (!obj)
+ if (!(size = GetRegionData( hrgn, 0, NULL ))) return NULL;
+ if (sizeof(XRectangle) > sizeof(RECT))
{
- ERR("Rgn is 0. Please report this.\n");
- return;
+ /* add extra size for XRectangle array */
+ int count = (size - sizeof(RGNDATAHEADER)) / sizeof(RECT);
+ size += count * (sizeof(XRectangle) - sizeof(RECT));
}
-
- if (obj->rgn->numRects > 0)
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
+ if (!GetRegionData( hrgn, size, data ))
{
- XRectangle *pXr;
- RECT *pRect = obj->rgn->rects;
- RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects;
+ HeapFree( GetProcessHeap(), 0, data );
+ return NULL;
+ }
- 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++)
+ rect = (RECT *)data->Buffer;
+ xrect = (XRectangle *)data->Buffer;
+ if (hdc_lptodp) /* map to device coordinates */
+ {
+ LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
+ for (i = 0; i < data->rdh.nCount; i++)
{
- pXr->x = pRect->left;
- pXr->y = pRect->top;
- pXr->width = pRect->right - pRect->left;
- pXr->height = pRect->bottom - pRect->top;
+ 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 (sizeof(XRectangle) > sizeof(RECT))
+ {
+ /* need to start from the end */
+ for (i = data->rdh.nCount-1; i >=0; 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;
}
}
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;
+}
+
+/***********************************************************************
+ * X11DRV_SetDeviceClipping
+ */
+void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn )
+{
+ RGNDATA *data;
+
+ if (!(data = X11DRV_GetRegionData( hrgn, 0 ))) return;
TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
- pXrect, obj->rgn->numRects, YXBanded );
-
- if(pXrect)
- HeapFree( GetProcessHeap(), 0, pXrect );
-
- GDI_ReleaseObj( hrgn );
+ (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
+ HeapFree( GetProcessHeap(), 0, data );
}
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 7e34689..7ea2e13 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -45,7 +45,6 @@
#include "bitmap.h"
#include "gdi.h"
#include "palette.h"
-#include "region.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(graphics);
@@ -940,48 +939,29 @@
BOOL
X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn )
{
- RECT box;
- HRGN tmpVisRgn, prevVisRgn;
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 ))
{
- /* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ int i;
+ XRectangle *rect;
+ RGNDATA *data = X11DRV_GetRegionData( hrgn, physDev->hdc );
- TSXFillRectangle( gdi_display, physDev->drawable, physDev->gc,
- box.left, box.top,
- box.right-box.left, box.bottom-box.top );
-
- /* Update the DIBSection from the pixmap */
- X11DRV_UnlockDIBSection(physDev, TRUE);
+ if (!data) return FALSE;
+ rect = (XRectangle *)data->Buffer;
+ for (i = 0; i < data->rdh.nCount; i++)
+ {
+ rect[i].x += dc->DCOrgX;
+ rect[i].y += dc->DCOrgY;
+ }
+
+ 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 );
}
-
- /* Restore the visible region */
-
- RestoreVisRgn16( hdc );
return TRUE;
}
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index fbf5d96..01de6ad 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -151,7 +151,10 @@
{
SIZE sz;
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
- return FALSE;
+ {
+ result = FALSE;
+ goto END;
+ }
width = INTERNAL_XWSTODS(dc, sz.cx);
}
ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
@@ -206,8 +209,7 @@
if (flags & ETO_CLIPPED)
{
SaveVisRgn16( dc->hSelf );
- CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
- rect.bottom, FALSE );
+ IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
}
/* Draw the text background if necessary */
@@ -395,9 +397,7 @@
dc->DCOrgX + x + width, dc->DCOrgY + y - lineAscent );
}
- if (flags & ETO_CLIPPED)
- RestoreVisRgn16( dc->hSelf );
-
+ if (flags & ETO_CLIPPED) RestoreVisRgn16( dc->hSelf );
goto END;
FAIL:
diff --git a/include/gdi.h b/include/gdi.h
index 973c780..d7ffe88 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -580,16 +580,7 @@
extern void DC_InitDC( DC * dc );
extern void DC_UpdateXforms( DC * dc );
-
-#define CLIP_INTERSECT 0x0001
-#define CLIP_EXCLUDE 0x0002
-#define CLIP_KEEPRGN 0x0004
-
/* 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 );
/* objects/enhmetafile.c */
diff --git a/include/region.h b/include/region.h
index e66f9a6..682cb2c 100644
--- a/include/region.h
+++ b/include/region.h
@@ -25,26 +25,11 @@
#include "windef.h"
#include "wingdi.h"
-typedef struct {
- INT size;
- INT numRects;
- INT type; /* NULL, SIMPLE or COMPLEX */
- RECT *rects;
- RECT extents;
-} WINEREGION;
+struct _RGNOBJ;
- /* GDI logical region object */
-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 BOOL REGION_DeleteObject( HRGN hrgn, struct _RGNOBJ * obj );
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_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc );
#endif /* __WINE_REGION_H */
diff --git a/include/x11drv.h b/include/x11drv.h
index 4effb5f..b5bd9f4 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -198,6 +198,7 @@
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, 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_StartGraphicsExposures( HDC hdc );
extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
diff --git a/objects/clipping.c b/objects/clipping.c
index 2519bca..0051119 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -23,7 +23,6 @@
#include "wingdi.h"
#include "wine/winuser16.h"
#include "gdi.h"
-#include "region.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
@@ -205,54 +204,6 @@
/***********************************************************************
- * 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)
*/
INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
@@ -268,6 +219,7 @@
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
INT right, INT bottom )
{
+ HRGN newRgn;
INT ret;
DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR;
@@ -276,13 +228,25 @@
if(dc->funcs->pExcludeClipRect)
ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
- else {
- left = XLPTODP( dc, left );
- right = XLPTODP( dc, right );
- top = YLPTODP( dc, top );
- bottom = YLPTODP( dc, bottom );
+ else
+ {
+ left = dc->DCOrgX + XLPTODP( dc, left );
+ right = dc->DCOrgX + XLPTODP( dc, right );
+ 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 );
return ret;
@@ -313,13 +277,30 @@
if(dc->funcs->pIntersectClipRect)
ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
- else {
- left = XLPTODP( dc, left );
- right = XLPTODP( dc, right );
- top = YLPTODP( dc, top );
- bottom = YLPTODP( dc, bottom );
+ else
+ {
+ left = dc->DCOrgX + XLPTODP( dc, left );
+ right = dc->DCOrgX + XLPTODP( dc, right );
+ top = dc->DCOrgY + YLPTODP( dc, top );
+ bottom = dc->DCOrgY + YLPTODP( dc, bottom );
- ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_INTERSECT );
+ if (!dc->hClipRgn)
+ {
+ dc->hClipRgn = CreateRectRgn( left, top, right, bottom );
+ ret = SIMPLEREGION;
+ }
+ else
+ {
+ HRGN newRgn;
+
+ if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
+ else
+ {
+ ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND );
+ DeleteObject( newRgn );
+ }
+ }
+ if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
}
GDI_ReleaseObj( hdc );
return ret;
@@ -327,74 +308,30 @@
/***********************************************************************
- * 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 );
- return ERROR;
- }
- ret = CombineRgn( newRgn, dc->hVisRgn, tempRgn,
- exclude ? RGN_DIFF : RGN_AND );
- DeleteObject( tempRgn );
-
- if (ret != ERROR)
- {
- RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
- if (newObj)
- {
- RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC);
- if (prevObj)
- {
- newObj->header.hNext = prevObj->header.hNext;
- GDI_ReleaseObj( dc->hVisRgn );
- }
- GDI_ReleaseObj( newRgn );
- }
- DeleteObject( dc->hVisRgn );
- dc->hVisRgn = newRgn;
- CLIPPING_UpdateGCRegion( dc );
- }
- else DeleteObject( newRgn );
- return ret;
-}
-
-
-/***********************************************************************
* ExcludeVisRect (GDI.73)
*/
INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
INT16 right, INT16 bottom )
{
+ HRGN tempRgn;
INT16 ret;
DC * dc = DC_GetDCUpdate( hdc );
- if (!dc) return ERROR;
+ if (!dc) return ERROR;
- left = XLPTODP( dc, left );
- right = XLPTODP( dc, right );
- top = YLPTODP( dc, top );
- bottom = YLPTODP( dc, bottom );
+ left = dc->DCOrgX + XLPTODP( dc, left );
+ right = dc->DCOrgX + XLPTODP( dc, right );
+ top = dc->DCOrgY + YLPTODP( dc, top );
+ bottom = dc->DCOrgY + YLPTODP( dc, 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 );
return ret;
}
@@ -406,18 +343,25 @@
INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top,
INT16 right, INT16 bottom )
{
+ HRGN tempRgn;
INT16 ret;
DC * dc = DC_GetDCUpdate( hdc );
- if (!dc) return ERROR;
+ if (!dc) return ERROR;
- left = XLPTODP( dc, left );
- right = XLPTODP( dc, right );
- top = YLPTODP( dc, top );
- bottom = YLPTODP( dc, bottom );
+ left = dc->DCOrgX + XLPTODP( dc, left );
+ right = dc->DCOrgX + XLPTODP( dc, right );
+ top = dc->DCOrgY + YLPTODP( dc, top );
+ bottom = dc->DCOrgY + YLPTODP( dc, 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 );
return ret;
}
@@ -562,13 +506,13 @@
HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
{
HRGN copy;
- RGNOBJ *obj, *copyObj;
+ GDIOBJHDR *obj, *copyObj;
DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return 0;
TRACE("%04x\n", hdc );
- if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
+ if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
{
GDI_ReleaseObj( hdc );
return 0;
@@ -580,15 +524,15 @@
return 0;
}
CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY );
- if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
+ if (!(copyObj = GDI_GetObjPtr( copy, REGION_MAGIC )))
{
DeleteObject( copy );
GDI_ReleaseObj( dc->hVisRgn );
GDI_ReleaseObj( hdc );
return 0;
}
- copyObj->header.hNext = obj->header.hNext;
- obj->header.hNext = copy;
+ copyObj->hNext = obj->hNext;
+ obj->hNext = copy;
GDI_ReleaseObj( copy );
GDI_ReleaseObj( dc->hVisRgn );
GDI_ReleaseObj( hdc );
@@ -602,25 +546,27 @@
INT16 WINAPI RestoreVisRgn16( HDC16 hdc )
{
HRGN saved;
- RGNOBJ *obj, *savedObj;
+ GDIOBJHDR *obj, *savedObj;
DC *dc = DC_GetDCPtr( hdc );
INT16 ret = ERROR;
- if (!dc) return ERROR;
- if (!dc->hVisRgn) goto done;
+ if (!dc) return ERROR;
+
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;
+ saved = obj->hNext;
+
+ if ((savedObj = GDI_GetObjPtr( saved, REGION_MAGIC )))
+ {
+ ret = CombineRgn( dc->hVisRgn, saved, 0, RGN_COPY );
+ obj->hNext = savedObj->hNext;
+ GDI_ReleaseObj( saved );
+ DeleteObject( saved );
+ dc->flags &= ~DC_DIRTY;
+ CLIPPING_UpdateGCRegion( dc );
+ }
GDI_ReleaseObj( dc->hVisRgn );
- if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;
-
- DeleteObject( dc->hVisRgn );
- dc->hVisRgn = saved;
- dc->flags &= ~DC_DIRTY;
- CLIPPING_UpdateGCRegion( dc );
- ret = savedObj->rgn->type; /* FIXME */
- GDI_ReleaseObj( saved );
done:
GDI_ReleaseObj( hdc );
return ret;
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 9d464dd..dbdb945 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -897,7 +897,7 @@
case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header );
case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)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:
GDI_ReleaseObj( obj );
return DeleteDC(obj);
diff --git a/objects/region.c b/objects/region.c
index 60b3f6e..102ddd8 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -104,6 +104,21 @@
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.
* 0 if two RECTs do not overlap.
*/
@@ -134,7 +149,6 @@
(pReg)->numRects = 0; \
(pReg)->extents.left = (pReg)->extents.top = 0; \
(pReg)->extents.right = (pReg)->extents.bottom = 0; \
- (pReg)->type = NULLREGION; \
}
#define REGION_NOT_EMPTY(pReg) pReg->numRects
@@ -423,6 +437,21 @@
#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
* Outputs the contents of a WINEREGION
@@ -542,7 +571,7 @@
obj->rgn->extents.bottom += y;
}
}
- ret = obj->rgn->type;
+ ret = get_region_type( obj );
GDI_ReleaseObj( hrgn );
return ret;
}
@@ -573,7 +602,7 @@
rect->top = obj->rgn->extents.top;
rect->right = obj->rgn->extents.right;
rect->bottom = obj->rgn->extents.bottom;
- ret = obj->rgn->type;
+ ret = get_region_type( obj );
GDI_ReleaseObj(hrgn);
return ret;
}
@@ -671,8 +700,7 @@
obj->rgn->rects->top = obj->rgn->extents.top = top;
obj->rgn->rects->right = obj->rgn->extents.right = right;
obj->rgn->rects->bottom = obj->rgn->extents.bottom = bottom;
- obj->rgn->numRects = 1;
- obj->rgn->type = SIMPLEREGION;
+ obj->rgn->numRects = 1;
}
else
EMPTY_REGION(obj->rgn);
@@ -804,7 +832,6 @@
rect.bottom = bottom;
REGION_UnionRectWithRegion( &rect, obj->rgn );
}
- obj->rgn->type = SIMPLEREGION; /* FIXME? */
GDI_ReleaseObj( hrgn );
return hrgn;
}
@@ -1091,10 +1118,10 @@
}
return ret;
}
+
/***********************************************************************
* REGION_UnionRectWithRegion
* Adds a rectangle to a WINEREGION
- * See below for REGION_UnionRectWithRgn
*/
static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
{
@@ -1103,26 +1130,10 @@
region.rects = ®ion.extents;
region.numRects = 1;
region.size = 1;
- region.type = SIMPLEREGION;
region.extents = *rect;
REGION_UnionRegion(rgn, rgn, ®ion);
- 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
@@ -1163,66 +1174,7 @@
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)
*/
@@ -1256,7 +1208,7 @@
if (mode == RGN_COPY)
{
REGION_CopyRegion( destObj->rgn, src1Obj->rgn );
- result = destObj->rgn->type;
+ result = get_region_type( destObj );
}
else
{
@@ -1282,7 +1234,7 @@
REGION_SubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
break;
}
- result = destObj->rgn->type;
+ result = get_region_type( destObj );
GDI_ReleaseObj( hSrc2 );
}
}
@@ -1361,8 +1313,6 @@
dst->extents.top = src->extents.top;
dst->extents.right = src->extents.right;
dst->extents.bottom = src->extents.bottom;
- dst->type = src->type;
-
memcpy((char *) dst->rects, (char *) src->rects,
(int) (src->numRects * sizeof(RECT)));
}
@@ -1892,10 +1842,6 @@
* due to coalescing, so we have to examine fewer rectangles.
*/
REGION_SetExtents(newReg);
- newReg->type = (newReg->numRects) ?
- ((newReg->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
- : NULLREGION ;
- return;
}
/***********************************************************************
@@ -2071,10 +2017,6 @@
newReg->extents.top = min(reg1->extents.top, reg2->extents.top);
newReg->extents.right = max(reg1->extents.right, reg2->extents.right);
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 @@
* due to coalescing, so we have to examine fewer rectangles.
*/
REGION_SetExtents (regD);
- regD->type = (regD->numRects) ?
- ((regD->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
- : NULLREGION ;
- return;
}
/***********************************************************************
@@ -2876,9 +2814,6 @@
}
REGION_FreeStorage(SLLBlock.next);
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
- region->type = (region->numRects) ?
- ((region->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
- : NULLREGION;
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
tmpPtBlock = curPtBlock->next;
@@ -3120,8 +3055,6 @@
rgnDst->extents.top = rgnDst->rects[0].top;
rgnDst->extents.bottom = rgnDst->rects[j].bottom;
- rgnDst->type = (j >= 1) ? COMPLEXREGION : SIMPLEREGION;
-
if( TRACE_ON(region) )
{
TRACE("result:\n");
diff --git a/windows/dce.c b/windows/dce.c
index b55c12b..4d0d41c 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -35,7 +35,6 @@
#include "dce.h"
#include "win.h"
#include "gdi.h"
-#include "region.h"
#include "user.h"
#include "wine/debug.h"
#include "windef.h"
diff --git a/windows/winpos.c b/windows/winpos.c
index e40840d..f17959a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -28,7 +28,6 @@
#include "wine/server.h"
#include "controls.h"
#include "user.h"
-#include "region.h"
#include "win.h"
#include "hook.h"
#include "message.h"