Moved hGCClipRgn handling to the graphics driver.

This commit is contained in:
Alexandre Julliard 2004-02-13 20:26:27 +00:00
parent 41b89ddd53
commit e04fe7da4e
12 changed files with 74 additions and 66 deletions

View File

@ -140,7 +140,7 @@ typedef struct tagDC_FUNCS
INT (*pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT); INT (*pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
INT (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID, INT (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,
const BITMAPINFO*,UINT); const BITMAPINFO*,UINT);
VOID (*pSetDeviceClipping)(PHYSDEV,HRGN); VOID (*pSetDeviceClipping)(PHYSDEV,HRGN,HRGN);
BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID); BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
INT (*pSetMapMode)(PHYSDEV,INT); INT (*pSetMapMode)(PHYSDEV,INT);
DWORD (*pSetMapperFlags)(PHYSDEV,DWORD); DWORD (*pSetMapperFlags)(PHYSDEV,DWORD);

View File

@ -27,7 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
/*********************************************************************** /***********************************************************************
* PSDRV_SetDeviceClipping * 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 */ /* We could set a dirty flag here to speed up PSDRV_SetClip */
return; return;

View File

@ -31,7 +31,6 @@
#include "wingdi.h" #include "wingdi.h"
#include "winreg.h" #include "winreg.h"
#include "winuser.h" #include "winuser.h"
#include "gdi.h"
#include "x11drv.h" #include "x11drv.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -1142,7 +1141,7 @@ static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT y
rect.bottom = yDst + heightDst; rect.bottom = yDst + heightDst;
if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right ); if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom ); 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; if (!IntersectRect( visRectDst, &rect, &clipRect )) return FALSE;
/* Get the source visible rectangle */ /* Get the source visible rectangle */

View File

@ -109,11 +109,13 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
/*********************************************************************** /***********************************************************************
* X11DRV_SetDeviceClipping * X11DRV_SetDeviceClipping
*/ */
void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn ) void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn )
{ {
RGNDATA *data; 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(); wine_tsx11_lock();
XSetClipRectangles( gdi_display, physDev->gc, physDev->org.x, physDev->org.y, XSetClipRectangles( gdi_display, physDev->gc, physDev->org.x, physDev->org.y,
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded ); (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );

View File

@ -1284,12 +1284,15 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color,
{ {
XImage *image; XImage *image;
RECT rect; RECT rect;
POINT pt;
TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n", x, y, color, fillType ); TRACE("X11DRV_ExtFloodFill %d,%d %06lx %d\n", x, y, color, fillType );
if (!PtVisible( physDev->hdc, x, y )) return FALSE; pt.x = x;
if (GetClipBox( physDev->hdc, &rect ) == ERROR) return FALSE; pt.y = y;
LPtoDP( physDev->hdc, (LPPOINT)&rect, 2 ); LPtoDP( physDev->hdc, &pt, 1 );
if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
GetRgnBox( physDev->region, &rect );
wine_tsx11_lock(); wine_tsx11_lock();
image = XGetImage( gdi_display, physDev->drawable, 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 )) if (X11DRV_SetupGCForBrush( physDev ))
{ {
POINT pt;
pt.x = x;
pt.y = y;
LPtoDP(physDev->hdc, &pt, 1);
/* Update the pixmap from the DIB section */ /* Update the pixmap from the DIB section */
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE); X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);

View File

@ -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 */ if (!X11DRV_DC_Funcs) X11DRV_DC_Funcs = dc->funcs; /* hack */
physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) ); physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) );
if(!physDev) { if (!physDev) return FALSE;
ERR("Can't allocate physDev\n");
return FALSE;
}
*pdev = physDev; *pdev = physDev;
physDev->hdc = dc->hSelf; physDev->hdc = dc->hSelf;
physDev->dc = dc; /* FIXME */ 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->drawable = root_window;
physDev->depth = screen_depth; physDev->depth = screen_depth;
} }
physDev->org.x = physDev->org.y = 0; physDev->region = CreateRectRgn( 0, 0, 0, 0 );
physDev->drawable_org.x = physDev->drawable_org.y = 0;
physDev->current_pf = 0;
physDev->used_visuals = 0;
wine_tsx11_lock(); wine_tsx11_lock();
physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL ); physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
@ -136,6 +130,7 @@ BOOL X11DRV_DeleteDC( X11DRV_PDEVICE *physDev )
{ {
if(physDev->xrender) if(physDev->xrender)
X11DRV_XRender_DeleteDC( physDev ); X11DRV_XRender_DeleteDC( physDev );
DeleteObject( physDev->region );
wine_tsx11_lock(); wine_tsx11_lock();
XFreeGC( gdi_display, physDev->gc ); XFreeGC( gdi_display, physDev->gc );
while (physDev->used_visuals-- > 0) while (physDev->used_visuals-- > 0)

View File

@ -56,6 +56,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
XChar2b *str2b = NULL; XChar2b *str2b = NULL;
BOOL dibUpdateFlag = FALSE; BOOL dibUpdateFlag = FALSE;
BOOL result = TRUE; BOOL result = TRUE;
HRGN saved_region = 0;
POINT pt; POINT pt;
DC *dc = physDev->dc; DC *dc = physDev->dc;
UINT align = GetTextAlign( physDev->hdc ); UINT align = GetTextAlign( physDev->hdc );
@ -218,8 +219,12 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
SaveVisRgn16( HDC_16(physDev->hdc) ); HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom );
IntersectVisRect16( HDC_16(physDev->hdc), 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 */ /* Draw the text background if necessary */
@ -411,7 +416,12 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
} }
wine_tsx11_unlock(); 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; goto END;
FAIL: FAIL:

View File

@ -91,6 +91,7 @@ typedef struct
Drawable drawable; Drawable drawable;
POINT org; /* DC origin relative to drawable */ POINT org; /* DC origin relative to drawable */
POINT drawable_org; /* Origin of drawable relative to screen */ POINT drawable_org; /* Origin of drawable relative to screen */
HRGN region; /* Device region (visible region & clip region) */
X_PHYSFONT font; X_PHYSFONT font;
X_PHYSPEN pen; X_PHYSPEN pen;
X_PHYSBRUSH brush; X_PHYSBRUSH brush;
@ -170,6 +171,7 @@ extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
UINT flags, const RECT *lprect, UINT flags, const RECT *lprect,
LPCWSTR str, UINT count, const INT *lpDx ); LPCWSTR str, UINT count, const INT *lpDx );
extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count ); 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, extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
INT yDest, DWORD cx, DWORD cy, INT yDest, DWORD cx, DWORD cy,
INT xSrc, INT ySrc, INT xSrc, INT ySrc,

View File

@ -952,6 +952,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
int textPixel, backgroundPixel; int textPixel, backgroundPixel;
INT *deltas = NULL; INT *deltas = NULL;
INT char_extra; INT char_extra;
HRGN saved_region = 0;
UINT align = GetTextAlign( hdc ); UINT align = GetTextAlign( hdc );
COLORREF textColor = GetTextColor( 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) if (flags & ETO_CLIPPED)
{ {
SaveVisRgn16( HDC_16(hdc) ); HRGN clip_region = CreateRectRgn( lprect->left, lprect->top, lprect->right, lprect->bottom );
IntersectVisRect16( HDC_16(hdc), 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) { 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); physDev->xrender->pict, hdc, physDev->drawable);
} }
if ((data = X11DRV_GetRegionData( physDev->dc->hGCClipRgn, 0 ))) if ((data = X11DRV_GetRegionData( physDev->region, 0 )))
{ {
wine_tsx11_lock(); wine_tsx11_lock();
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict, 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); HeapFree(GetProcessHeap(), 0, deltas);
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
RestoreVisRgn16( HDC_16(hdc) ); {
/* restore the device region */
X11DRV_SetDeviceClipping( physDev, saved_region, 0 );
DeleteObject( saved_region );
}
retv = TRUE; retv = TRUE;

View File

@ -115,7 +115,6 @@ typedef struct tagDC
int flags; int flags;
HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hClipRgn; /* Clip region (may be 0) */
HRGN hVisRgn; /* Visible region (must never be 0) */ HRGN hVisRgn; /* Visible region (must never be 0) */
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
HPEN hPen; HPEN hPen;
HBRUSH hBrush; HBRUSH hBrush;
HFONT hFont; HFONT hFont;

View File

@ -39,8 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping);
*/ */
void CLIPPING_UpdateGCRegion( DC * dc ) void CLIPPING_UpdateGCRegion( DC * dc )
{ {
if (!dc->hGCClipRgn) dc->hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 );
if (!dc->hVisRgn) if (!dc->hVisRgn)
{ {
ERR("hVisRgn is zero. Please report this.\n" ); 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->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) 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 WINAPI PtVisible( HDC hdc, INT x, INT y )
{ {
BOOL ret = FALSE; POINT pt;
BOOL ret;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
TRACE("%p %d,%d\n", hdc, x, y ); TRACE("%p %d,%d\n", hdc, x, y );
if (!dc) return FALSE; if (!dc) return FALSE;
if (dc->hGCClipRgn)
{
POINT pt;
pt.x = x; pt.x = x;
pt.y = y; pt.y = y;
LPtoDP( hdc, &pt, 1 ); LPtoDP( hdc, &pt, 1 );
ret = PtInRegion( dc->hGCClipRgn, pt.x, pt.y ); ret = PtInRegion( dc->hVisRgn, pt.x, pt.y );
} if (ret && dc->hClipRgn) ret = PtInRegion( dc->hClipRgn, pt.x, pt.y );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
@ -369,26 +361,23 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
*/ */
BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{ {
BOOL ret = FALSE; RECT tmpRect;
BOOL ret;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return FALSE; if (!dc) return FALSE;
TRACE("%p %ld,%ldx%ld,%ld\n", hdc, rect->left, rect->top, rect->right, rect->bottom ); 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; tmpRect = *rect;
pt[0].y = rect->top; LPtoDP( hdc, (POINT *)&tmpRect, 2 );
pt[1].x = rect->right;
pt[1].y = rect->bottom; if (dc->hClipRgn)
LPtoDP( hdc, pt, 2 ); {
tmpRect.left = pt[0].x; HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
tmpRect.top = pt[0].y; CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND );
tmpRect.right = pt[1].x; ret = RectInRegion( hrgn, &tmpRect );
tmpRect.bottom = pt[1].y; DeleteObject( hrgn );
ret = RectInRegion( dc->hGCClipRgn, &tmpRect );
} }
else ret = RectInRegion( dc->hVisRgn, &tmpRect );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
@ -402,7 +391,14 @@ INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
INT ret; INT ret;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR; 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 ); DPtoLP( hdc, (LPPOINT)rect, 2 );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;

View File

@ -78,7 +78,6 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc->flags = 0; dc->flags = 0;
dc->hClipRgn = 0; dc->hClipRgn = 0;
dc->hVisRgn = 0; dc->hVisRgn = 0;
dc->hGCClipRgn = 0;
dc->hPen = GetStockObject( BLACK_PEN ); dc->hPen = GetStockObject( BLACK_PEN );
dc->hBrush = GetStockObject( WHITE_BRUSH ); dc->hBrush = GetStockObject( WHITE_BRUSH );
dc->hFont = GetStockObject( SYSTEM_FONT ); 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). */ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
newdc->hGCClipRgn = newdc->hVisRgn = 0; newdc->hVisRgn = 0;
if (dc->hClipRgn) if (dc->hClipRgn)
{ {
newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 ); newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
@ -764,7 +763,6 @@ BOOL WINAPI DeleteDC( HDC hdc )
dc->saveLevel--; dc->saveLevel--;
if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn ); if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn ); if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
if (dcs->hGCClipRgn) DeleteObject( dcs->hGCClipRgn );
PATH_DestroyGdiPath(&dcs->path); PATH_DestroyGdiPath(&dcs->path);
GDI_FreeObject( hdcs, dcs ); GDI_FreeObject( hdcs, dcs );
} }
@ -782,7 +780,6 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn );
PATH_DestroyGdiPath(&dc->path); PATH_DestroyGdiPath(&dc->path);
GDI_FreeObject( hdc, dc ); GDI_FreeObject( hdc, dc );