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 @@
#include <string.h>
#include "gdi.h"
#include "region.h"
#include "mfdrv/metafiledrv.h"
#include "wine/debug.h"
......
......@@ -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 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
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 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
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 );
}
......
......@@ -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"
......
......@@ -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 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
XRenderColor col;
int idx;
TEXTMETRICW tm;
RGNOBJ *obj;
XRectangle *pXrect;
RGNDATA *data;
SIZE sz;
RECT rc;
BOOL done_extents = FALSE;
......@@ -713,12 +711,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
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,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);
}
obj = (RGNOBJ *) GDI_GetObjPtr(dc->hGCClipRgn, REGION_MAGIC);
if (!obj)
{
ERR("Rgn is 0. Please report this.\n");
return FALSE;
}
if (obj->rgn->numRects > 0)
if ((data = X11DRV_GetRegionData( dc->hGCClipRgn, 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, (XRectangle *)data->Buffer, data->rdh.nCount );
wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, data );
}
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))) {
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
......
......@@ -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;
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);
if (!obj)
rect = (RECT *)data->Buffer;
xrect = (XRectangle *)data->Buffer;
if (hdc_lptodp) /* map to device coordinates */
{
ERR("Rgn is 0. Please report this.\n");
return;
LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
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;
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( hrgn );
return;
}
for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
/* need to start from the end */
for (i = data->rdh.nCount-1; i >=0; i--)
{
pXr->x = pRect->left;
pXr->y = pRect->top;
pXr->width = pRect->right - pRect->left;
pXr->height = pRect->bottom - pRect->top;
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;
}
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 @@
#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 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y )
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);
}
/* Restore the visible region */
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;
}
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;
}
......
......@@ -151,7 +151,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
{
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 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
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 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
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:
......
......@@ -580,16 +580,7 @@ extern DC * DC_GetDCUpdate( HDC hdc );
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 */
......
......@@ -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 */
......
......@@ -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_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 );
......
......@@ -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 @@ 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)
*/
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 right, INT bottom )
{
HRGN newRgn;
INT ret;
DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR;
......@@ -276,13 +228,25 @@ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
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,66 +277,32 @@ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top,
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 );
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 )))
else
{
DeleteObject( newRgn );
return ERROR;
}
ret = CombineRgn( newRgn, dc->hVisRgn, tempRgn,
exclude ? RGN_DIFF : RGN_AND );
DeleteObject( tempRgn );
left = dc->DCOrgX + XLPTODP( dc, left );
right = dc->DCOrgX + XLPTODP( dc, right );
top = dc->DCOrgY + YLPTODP( dc, top );
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
if (ret != ERROR)
{
RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
if (newObj)
if (!dc->hClipRgn)
{
RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC);
if (prevObj)
dc->hClipRgn = CreateRectRgn( left, top, right, bottom );
ret = SIMPLEREGION;
}
else
{
HRGN newRgn;
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
else
{
newObj->header.hNext = prevObj->header.hNext;
GDI_ReleaseObj( dc->hVisRgn );
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND );
DeleteObject( newRgn );
}
GDI_ReleaseObj( newRgn );
}
DeleteObject( dc->hVisRgn );
dc->hVisRgn = newRgn;
CLIPPING_UpdateGCRegion( dc );
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
}
else DeleteObject( newRgn );
GDI_ReleaseObj( hdc );
return ret;
}
......@@ -383,18 +313,25 @@ INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
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 ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
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 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
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 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
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 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
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;
GDI_ReleaseObj( dc->hVisRgn );
if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;
if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
saved = obj->hNext;
DeleteObject( dc->hVisRgn );
dc->hVisRgn = saved;
dc->flags &= ~DC_DIRTY;
CLIPPING_UpdateGCRegion( dc );
ret = savedObj->rgn->type; /* FIXME */
GDI_ReleaseObj( saved );
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 );
done:
GDI_ReleaseObj( hdc );
return ret;
......
......@@ -897,7 +897,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
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);
......
......@@ -104,6 +104,21 @@ SOFTWARE.
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 @@ static inline int xmemcheck(WINEREGION *reg, LPRECT *rect, LPRECT *firstrect ) {
(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 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);
#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 @@ INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y )
obj->rgn->extents.bottom += y;
}
}
ret = obj->rgn->type;
ret = get_region_type( obj );
GDI_ReleaseObj( hrgn );
return ret;
}
......@@ -573,7 +602,7 @@ INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect )
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 @@ BOOL WINAPI SetRectRgn( HRGN hrgn, INT left, INT top,
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 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
rect.bottom = bottom;
REGION_UnionRectWithRegion( &rect, obj->rgn );
}
obj->rgn->type = SIMPLEREGION; /* FIXME? */
GDI_ReleaseObj( hrgn );
return hrgn;
}
......@@ -1091,10 +1118,10 @@ BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 )
}
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 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
region.rects = &region.extents;
region.numRects = 1;
region.size = 1;
region.type = SIMPLEREGION;
region.extents = *rect;
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
......@@ -1163,66 +1174,7 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
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 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
if (mode == RGN_COPY)
{
REGION_CopyRegion( destObj->rgn, src1Obj->rgn );
result = destObj->rgn->type;
result = get_region_type( destObj );
}
else
{
......@@ -1282,7 +1234,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
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 @@ static void REGION_CopyRegion(WINEREGION *dst, WINEREGION *src)
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 @@ static void REGION_IntersectRegion(WINEREGION *newReg, WINEREGION *reg1,
* 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 @@ static void REGION_UnionRegion(WINEREGION *newReg, WINEREGION *reg1,
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 @@ static void REGION_SubtractRegion(WINEREGION *regD, WINEREGION *regM,
* 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 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
}
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 @@ empty:
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");
......
......@@ -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"
......
......@@ -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"
......
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