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"