From e04fe7da4e683b47d82e45df1b3e0da0a970580b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 13 Feb 2004 20:26:27 +0000 Subject: [PATCH] Moved hGCClipRgn handling to the graphics driver. --- dlls/gdi/gdi_private.h | 2 +- dlls/wineps/clipping.c | 2 +- dlls/x11drv/bitblt.c | 3 +-- dlls/x11drv/clipping.c | 6 +++-- dlls/x11drv/graphics.c | 13 +++++---- dlls/x11drv/init.c | 13 +++------ dlls/x11drv/text.c | 16 ++++++++--- dlls/x11drv/x11drv.h | 2 ++ dlls/x11drv/xrender.c | 17 +++++++++--- include/gdi.h | 1 - objects/clipping.c | 60 ++++++++++++++++++++---------------------- objects/dc.c | 5 +--- 12 files changed, 74 insertions(+), 66 deletions(-) diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h index a4d2078f8ab..39281535855 100644 --- a/dlls/gdi/gdi_private.h +++ b/dlls/gdi/gdi_private.h @@ -140,7 +140,7 @@ typedef struct tagDC_FUNCS INT (*pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT); INT (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID, const BITMAPINFO*,UINT); - VOID (*pSetDeviceClipping)(PHYSDEV,HRGN); + VOID (*pSetDeviceClipping)(PHYSDEV,HRGN,HRGN); BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID); INT (*pSetMapMode)(PHYSDEV,INT); DWORD (*pSetMapperFlags)(PHYSDEV,DWORD); diff --git a/dlls/wineps/clipping.c b/dlls/wineps/clipping.c index 2dfa37c650a..5b07ee67ad5 100644 --- a/dlls/wineps/clipping.c +++ b/dlls/wineps/clipping.c @@ -27,7 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv); /*********************************************************************** * PSDRV_SetDeviceClipping */ -VOID PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN ignored ) +void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn ) { /* We could set a dirty flag here to speed up PSDRV_SetClip */ return; diff --git a/dlls/x11drv/bitblt.c b/dlls/x11drv/bitblt.c index 9579dffa32f..0f018328291 100644 --- a/dlls/x11drv/bitblt.c +++ b/dlls/x11drv/bitblt.c @@ -31,7 +31,6 @@ #include "wingdi.h" #include "winreg.h" #include "winuser.h" -#include "gdi.h" #include "x11drv.h" #include "wine/debug.h" @@ -1142,7 +1141,7 @@ static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT y rect.bottom = yDst + heightDst; if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right ); if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom ); - GetRgnBox( physDevDst->dc->hGCClipRgn, &clipRect ); + GetRgnBox( physDevDst->region, &clipRect ); if (!IntersectRect( visRectDst, &rect, &clipRect )) return FALSE; /* Get the source visible rectangle */ diff --git a/dlls/x11drv/clipping.c b/dlls/x11drv/clipping.c index 5f1515c8bb3..20721176593 100644 --- a/dlls/x11drv/clipping.c +++ b/dlls/x11drv/clipping.c @@ -109,11 +109,13 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) /*********************************************************************** * X11DRV_SetDeviceClipping */ -void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn ) +void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn ) { RGNDATA *data; - if (!(data = X11DRV_GetRegionData( hrgn, 0 ))) return; + CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY ); + if (!(data = X11DRV_GetRegionData( physDev->region, 0 ))) return; + wine_tsx11_lock(); XSetClipRectangles( gdi_display, physDev->gc, physDev->org.x, physDev->org.y, (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded ); diff --git a/dlls/x11drv/graphics.c b/dlls/x11drv/graphics.c index d1f2466591c..41f0d997ef5 100644 --- a/dlls/x11drv/graphics.c +++ b/dlls/x11drv/graphics.c @@ -1284,12 +1284,15 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color, { XImage *image; RECT rect; + POINT pt; TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n", x, y, color, fillType ); - if (!PtVisible( physDev->hdc, x, y )) return FALSE; - if (GetClipBox( physDev->hdc, &rect ) == ERROR) return FALSE; - LPtoDP( physDev->hdc, (LPPOINT)&rect, 2 ); + pt.x = x; + pt.y = y; + LPtoDP( physDev->hdc, &pt, 1 ); + if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE; + GetRgnBox( physDev->region, &rect ); wine_tsx11_lock(); image = XGetImage( gdi_display, physDev->drawable, @@ -1301,10 +1304,6 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color, if (X11DRV_SetupGCForBrush( physDev )) { - POINT pt; - pt.x = x; - pt.y = y; - LPtoDP(physDev->hdc, &pt, 1); /* Update the pixmap from the DIB section */ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE); diff --git a/dlls/x11drv/init.c b/dlls/x11drv/init.c index f2c8e4c4938..89843b84de1 100644 --- a/dlls/x11drv/init.c +++ b/dlls/x11drv/init.c @@ -95,10 +95,8 @@ BOOL X11DRV_CreateDC( DC *dc, X11DRV_PDEVICE **pdev, LPCWSTR driver, LPCWSTR dev if (!X11DRV_DC_Funcs) X11DRV_DC_Funcs = dc->funcs; /* hack */ physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) ); - if(!physDev) { - ERR("Can't allocate physDev\n"); - return FALSE; - } + if (!physDev) return FALSE; + *pdev = physDev; physDev->hdc = dc->hSelf; physDev->dc = dc; /* FIXME */ @@ -113,11 +111,7 @@ BOOL X11DRV_CreateDC( DC *dc, X11DRV_PDEVICE **pdev, LPCWSTR driver, LPCWSTR dev physDev->drawable = root_window; physDev->depth = screen_depth; } - physDev->org.x = physDev->org.y = 0; - physDev->drawable_org.x = physDev->drawable_org.y = 0; - - physDev->current_pf = 0; - physDev->used_visuals = 0; + physDev->region = CreateRectRgn( 0, 0, 0, 0 ); wine_tsx11_lock(); physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL ); @@ -136,6 +130,7 @@ BOOL X11DRV_DeleteDC( X11DRV_PDEVICE *physDev ) { if(physDev->xrender) X11DRV_XRender_DeleteDC( physDev ); + DeleteObject( physDev->region ); wine_tsx11_lock(); XFreeGC( gdi_display, physDev->gc ); while (physDev->used_visuals-- > 0) diff --git a/dlls/x11drv/text.c b/dlls/x11drv/text.c index 85dde735df6..5d88a520b30 100644 --- a/dlls/x11drv/text.c +++ b/dlls/x11drv/text.c @@ -56,6 +56,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, XChar2b *str2b = NULL; BOOL dibUpdateFlag = FALSE; BOOL result = TRUE; + HRGN saved_region = 0; POINT pt; DC *dc = physDev->dc; UINT align = GetTextAlign( physDev->hdc ); @@ -218,8 +219,12 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, if (flags & ETO_CLIPPED) { - SaveVisRgn16( HDC_16(physDev->hdc) ); - IntersectVisRect16( HDC_16(physDev->hdc), lprect->left, lprect->top, lprect->right, lprect->bottom ); + HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom ); + /* make a copy of the current device region */ + saved_region = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( saved_region, physDev->region, 0, RGN_COPY ); + X11DRV_SetDeviceClipping( physDev, saved_region, clip_region ); + DeleteObject( clip_region ); } /* Draw the text background if necessary */ @@ -411,7 +416,12 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, } wine_tsx11_unlock(); - if (flags & ETO_CLIPPED) RestoreVisRgn16( HDC_16(physDev->hdc) ); + if (flags & ETO_CLIPPED) + { + /* restore the device region */ + X11DRV_SetDeviceClipping( physDev, saved_region, 0 ); + DeleteObject( saved_region ); + } goto END; FAIL: diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h index 297564640f4..9f756dec6f0 100644 --- a/dlls/x11drv/x11drv.h +++ b/dlls/x11drv/x11drv.h @@ -91,6 +91,7 @@ typedef struct Drawable drawable; POINT org; /* DC origin relative to drawable */ POINT drawable_org; /* Origin of drawable relative to screen */ + HRGN region; /* Device region (visible region & clip region) */ X_PHYSFONT font; X_PHYSPEN pen; X_PHYSBRUSH brush; @@ -170,6 +171,7 @@ extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx ); extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count ); +extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn ); extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx, DWORD cy, INT xSrc, INT ySrc, diff --git a/dlls/x11drv/xrender.c b/dlls/x11drv/xrender.c index 4df7c764c35..e335d74f340 100644 --- a/dlls/x11drv/xrender.c +++ b/dlls/x11drv/xrender.c @@ -952,6 +952,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag int textPixel, backgroundPixel; INT *deltas = NULL; INT char_extra; + HRGN saved_region = 0; UINT align = GetTextAlign( hdc ); COLORREF textColor = GetTextColor( hdc ); @@ -1127,8 +1128,12 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag if (flags & ETO_CLIPPED) { - SaveVisRgn16( HDC_16(hdc) ); - IntersectVisRect16( HDC_16(hdc), lprect->left, lprect->top, lprect->right, lprect->bottom ); + HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom ); + /* make a copy of the current device region */ + saved_region = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( saved_region, physDev->region, 0, RGN_COPY ); + X11DRV_SetDeviceClipping( physDev, saved_region, clip_region ); + DeleteObject( clip_region ); } if(X11DRV_XRender_Installed) { @@ -1151,7 +1156,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag physDev->xrender->pict, hdc, physDev->drawable); } - if ((data = X11DRV_GetRegionData( physDev->dc->hGCClipRgn, 0 ))) + if ((data = X11DRV_GetRegionData( physDev->region, 0 ))) { wine_tsx11_lock(); pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict, @@ -1465,7 +1470,11 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag HeapFree(GetProcessHeap(), 0, deltas); if (flags & ETO_CLIPPED) - RestoreVisRgn16( HDC_16(hdc) ); + { + /* restore the device region */ + X11DRV_SetDeviceClipping( physDev, saved_region, 0 ); + DeleteObject( saved_region ); + } retv = TRUE; diff --git a/include/gdi.h b/include/gdi.h index afb6262fa18..3c4569590fb 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -115,7 +115,6 @@ typedef struct tagDC int flags; HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hVisRgn; /* Visible region (must never be 0) */ - HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */ HPEN hPen; HBRUSH hBrush; HFONT hFont; diff --git a/objects/clipping.c b/objects/clipping.c index de1584572c9..08382a4b6a7 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -39,8 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping); */ void CLIPPING_UpdateGCRegion( DC * dc ) { - if (!dc->hGCClipRgn) dc->hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 ); - if (!dc->hVisRgn) { ERR("hVisRgn is zero. Please report this.\n" ); @@ -49,12 +47,8 @@ void CLIPPING_UpdateGCRegion( DC * dc ) if (dc->flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" ); - if (!dc->hClipRgn) - CombineRgn( dc->hGCClipRgn, dc->hVisRgn, 0, RGN_COPY ); - else - CombineRgn(dc->hGCClipRgn, dc->hClipRgn, dc->hVisRgn, RGN_AND); if (dc->funcs->pSetDeviceClipping) - dc->funcs->pSetDeviceClipping( dc->physDev, dc->hGCClipRgn ); + dc->funcs->pSetDeviceClipping( dc->physDev, dc->hVisRgn, dc->hClipRgn ); } @@ -345,20 +339,18 @@ INT16 WINAPI IntersectVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right */ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) { - BOOL ret = FALSE; + POINT pt; + BOOL ret; DC *dc = DC_GetDCUpdate( hdc ); TRACE("%p %d,%d\n", hdc, x, y ); if (!dc) return FALSE; - if (dc->hGCClipRgn) - { - POINT pt; - pt.x = x; - pt.y = y; - LPtoDP( hdc, &pt, 1 ); - ret = PtInRegion( dc->hGCClipRgn, pt.x, pt.y ); - } + pt.x = x; + pt.y = y; + LPtoDP( hdc, &pt, 1 ); + ret = PtInRegion( dc->hVisRgn, pt.x, pt.y ); + if (ret && dc->hClipRgn) ret = PtInRegion( dc->hClipRgn, pt.x, pt.y ); GDI_ReleaseObj( hdc ); return ret; } @@ -369,26 +361,23 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) */ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) { - BOOL ret = FALSE; + RECT tmpRect; + BOOL ret; DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return FALSE; TRACE("%p %ld,%ldx%ld,%ld\n", hdc, rect->left, rect->top, rect->right, rect->bottom ); - if (dc->hGCClipRgn) - { - POINT pt[2]; - RECT tmpRect; - pt[0].x = rect->left; - pt[0].y = rect->top; - pt[1].x = rect->right; - pt[1].y = rect->bottom; - LPtoDP( hdc, pt, 2 ); - tmpRect.left = pt[0].x; - tmpRect.top = pt[0].y; - tmpRect.right = pt[1].x; - tmpRect.bottom = pt[1].y; - ret = RectInRegion( dc->hGCClipRgn, &tmpRect ); + tmpRect = *rect; + LPtoDP( hdc, (POINT *)&tmpRect, 2 ); + + if (dc->hClipRgn) + { + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND ); + ret = RectInRegion( hrgn, &tmpRect ); + DeleteObject( hrgn ); } + else ret = RectInRegion( dc->hVisRgn, &tmpRect ); GDI_ReleaseObj( hdc ); return ret; } @@ -402,7 +391,14 @@ INT WINAPI GetClipBox( HDC hdc, LPRECT rect ) INT ret; DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; - ret = GetRgnBox( dc->hGCClipRgn, rect ); + if (dc->hClipRgn) + { + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND ); + ret = GetRgnBox( hrgn, rect ); + DeleteObject( hrgn ); + } + else ret = GetRgnBox( dc->hVisRgn, rect ); DPtoLP( hdc, (LPPOINT)rect, 2 ); GDI_ReleaseObj( hdc ); return ret; diff --git a/objects/dc.c b/objects/dc.c index bd11b7a6fc2..6c5430a8ee8 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -78,7 +78,6 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) dc->flags = 0; dc->hClipRgn = 0; dc->hVisRgn = 0; - dc->hGCClipRgn = 0; dc->hPen = GetStockObject( BLACK_PEN ); dc->hBrush = GetStockObject( WHITE_BRUSH ); dc->hFont = GetStockObject( SYSTEM_FONT ); @@ -335,7 +334,7 @@ HDC WINAPI GetDCState( HDC hdc ) /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ - newdc->hGCClipRgn = newdc->hVisRgn = 0; + newdc->hVisRgn = 0; if (dc->hClipRgn) { newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 ); @@ -764,7 +763,6 @@ BOOL WINAPI DeleteDC( HDC hdc ) dc->saveLevel--; if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn ); if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn ); - if (dcs->hGCClipRgn) DeleteObject( dcs->hGCClipRgn ); PATH_DestroyGdiPath(&dcs->path); GDI_FreeObject( hdcs, dcs ); } @@ -782,7 +780,6 @@ BOOL WINAPI DeleteDC( HDC hdc ) if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); - if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn ); PATH_DestroyGdiPath(&dc->path); GDI_FreeObject( hdc, dc );