winex11: Add helper functions for changing and restoring the current clipping region.

This commit is contained in:
Alexandre Julliard 2011-07-21 19:03:10 +02:00
parent 0d9dde7953
commit 72607b3817
4 changed files with 51 additions and 34 deletions

View File

@ -185,27 +185,62 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
} }
/*********************************************************************** static void update_x11_clipping( X11DRV_PDEVICE *physDev )
* X11DRV_SetDeviceClipping
*/
void X11DRV_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_rgn )
{ {
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
RGNDATA *data; RGNDATA *data;
CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
if (!(data = X11DRV_GetRegionData( physDev->region, 0 ))) return; if (!(data = X11DRV_GetRegionData( physDev->region, 0 ))) return;
wine_tsx11_lock(); wine_tsx11_lock();
XSetClipRectangles( gdi_display, physDev->gc, physDev->dc_rect.left, physDev->dc_rect.top, XSetClipRectangles( gdi_display, physDev->gc, physDev->dc_rect.left, physDev->dc_rect.top,
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded ); (XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
wine_tsx11_unlock(); wine_tsx11_unlock();
if (physDev->xrender) X11DRV_XRender_SetDeviceClipping(physDev, data); if (physDev->xrender) X11DRV_XRender_SetDeviceClipping(physDev, data);
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
} }
/***********************************************************************
* add_extra_clipping_region
*
* Temporarily add a region to the current clipping region.
* The returned region must be restored with restore_clipping_region.
*/
HRGN add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn )
{
HRGN ret, clip;
if (!(clip = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
CombineRgn( clip, dev->region, rgn, RGN_AND );
ret = dev->region;
dev->region = clip;
update_x11_clipping( dev );
return ret;
}
/***********************************************************************
* restore_clipping_region
*/
void restore_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn )
{
if (!rgn) return;
DeleteObject( dev->region );
dev->region = rgn;
update_x11_clipping( dev );
}
/***********************************************************************
* X11DRV_SetDeviceClipping
*/
void X11DRV_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_rgn )
{
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
update_x11_clipping( physDev );
}
/*********************************************************************** /***********************************************************************
* X11DRV_SetupGCForPatBlt * X11DRV_SetupGCForPatBlt

View File

@ -85,13 +85,8 @@ BOOL X11DRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
HRGN clip_region; HRGN clip_region = CreateRectRgnIndirect( lprect );
saved_region = add_extra_clipping_region( physDev, clip_region );
clip_region = CreateRectRgnIndirect( lprect );
/* 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( dev, saved_region, clip_region );
DeleteObject( clip_region ); DeleteObject( clip_region );
} }
@ -177,12 +172,7 @@ BOOL X11DRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
} }
HeapFree( GetProcessHeap(), 0, str2b ); HeapFree( GetProcessHeap(), 0, str2b );
if (flags & ETO_CLIPPED) if (saved_region) restore_clipping_region( physDev, saved_region );
{
/* restore the device region */
X11DRV_SetDeviceClipping( dev, saved_region, 0 );
DeleteObject( saved_region );
}
goto END; goto END;
FAIL: FAIL:

View File

@ -289,6 +289,8 @@ extern X_PHYSBITMAP *X11DRV_init_phys_bitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern Pixmap X11DRV_get_pixmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN; extern Pixmap X11DRV_get_pixmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN; extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
extern HRGN add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
extern void restore_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) DECLSPEC_HIDDEN; extern BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_SetupGCForBrush( X11DRV_PDEVICE *physDev ) DECLSPEC_HIDDEN; extern BOOL X11DRV_SetupGCForBrush( X11DRV_PDEVICE *physDev ) DECLSPEC_HIDDEN;

View File

@ -1866,13 +1866,8 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
HRGN clip_region; HRGN clip_region = CreateRectRgnIndirect( lprect );
saved_region = add_extra_clipping_region( physDev, clip_region );
clip_region = CreateRectRgnIndirect( lprect );
/* 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->dev, saved_region, clip_region );
DeleteObject( clip_region ); DeleteObject( clip_region );
} }
@ -2131,12 +2126,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
} }
LeaveCriticalSection(&xrender_cs); LeaveCriticalSection(&xrender_cs);
if (flags & ETO_CLIPPED) if (saved_region) restore_clipping_region( physDev, saved_region );
{
/* restore the device region */
X11DRV_SetDeviceClipping( &physDev->dev, saved_region, 0 );
DeleteObject( saved_region );
}
retv = TRUE; retv = TRUE;