Commit 4a877221 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Add bounds rectangle tracking to all graphics entry points.

parent bb62ddeb
......@@ -391,7 +391,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr )
SetMapMode( hdc, MM_TEXT );
Rectangle( hdc, 2, 2, 4, 4 );
type = GetBoundsRect( hdc, &rect, DCB_RESET );
if (GetObjectType( hdc ) != OBJ_MEMDC || GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASDISPLAY)
if (GetObjectType( hdc ) == OBJ_ENHMETADC)
todo_wine
ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
"GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
......@@ -890,10 +890,8 @@ static void test_boundsrect(void)
MoveToEx( hdc, 10, 10, NULL );
LineTo( hdc, 20, 20 );
ret = GetBoundsRect( hdc, &rect, 0 );
todo_wine
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 10, 10, 21, 21 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
SetRect( &rect, 8, 8, 23, 23 );
expect = rect;
......@@ -907,32 +905,27 @@ static void test_boundsrect(void)
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 8, 8, 31, 26 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
SetBoundsRect( hdc, NULL, DCB_DISABLE );
LineTo( hdc, 40, 40 );
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 8, 8, 31, 26 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
SetRect( &rect, 6, 6, 30, 30 );
SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 6, 6, 31, 30 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
RestoreDC( hdc, level );
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
LineTo( hdc, 40, 40 );
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
SelectObject( hdc, old );
......@@ -947,14 +940,12 @@ static void test_boundsrect(void)
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 6, 6, 51, 41 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
SelectObject( hdc, GetStockObject( NULL_PEN ));
LineTo( hdc, 50, 50 );
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 6, 6, 51, 51 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
memset( buffer, 0, sizeof(buffer) );
......@@ -970,7 +961,6 @@ static void test_boundsrect(void)
ret = GetBoundsRect( hdc, &rect, 0 );
ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
SetRect( &expect, 6, 6, 51, 51 );
todo_wine
ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
LineTo( hdc, 55, 30 );
ret = GetBoundsRect( hdc, &rect, 0 );
......
......@@ -749,6 +749,7 @@ void execute_rop( X11DRV_PDEVICE *physdev, Pixmap src_pixmap, GC gc, const RECT
XFreePixmap( gdi_display, pixmaps[DST] );
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );
wine_tsx11_unlock();
add_device_bounds( physdev, visrect );
}
/***********************************************************************
......@@ -800,6 +801,7 @@ BOOL X11DRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
dst->visrect.right - dst->visrect.left,
dst->visrect.bottom - dst->visrect.top );
wine_tsx11_unlock();
add_device_bounds( physDev, &dst->visrect );
return TRUE;
}
......@@ -830,6 +832,8 @@ BOOL X11DRV_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
height = dst->visrect.bottom - dst->visrect.top;
opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
add_device_bounds( physDevDst, &dst->visrect );
/* a few optimizations for single-op ROPs */
if (!opcode[1] && OP_SRCDST(opcode[0]) == OP_ARGS(SRC,DST))
{
......@@ -1302,6 +1306,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
}
if (restore_region) restore_clipping_region( physdev );
add_device_bounds( physdev, &dst->visrect );
}
image->data = NULL;
}
......
......@@ -118,6 +118,7 @@ static X11DRV_PDEVICE *create_x11_physdev( Drawable drawable )
if (!(physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) ))) return NULL;
reset_bounds( &physDev->bounds );
wine_tsx11_lock();
physDev->drawable = drawable;
physDev->gc = XCreateGC( gdi_display, drawable, 0, NULL );
......@@ -187,6 +188,31 @@ static BOOL X11DRV_DeleteDC( PHYSDEV dev )
}
void add_device_bounds( X11DRV_PDEVICE *dev, const RECT *rect )
{
RECT rc;
if (dev->region && GetRgnBox( dev->region, &rc ))
{
if (IntersectRect( &rc, &rc, rect )) add_bounds_rect( &dev->bounds, &rc );
}
else add_bounds_rect( &dev->bounds, rect );
}
/***********************************************************************
* dibdrv_GetBoundsRect
*/
static UINT X11DRV_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
{
X11DRV_PDEVICE *pdev = get_x11drv_dev( dev );
if (IsRectEmpty( &pdev->bounds )) return DCB_RESET;
if (rect) *rect = pdev->bounds;
if (flags & DCB_RESET) reset_bounds( &pdev->bounds );
return DCB_SET;
}
/***********************************************************************
* GetDeviceCaps (X11DRV.@)
*/
......@@ -477,7 +503,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
NULL, /* pFrameRgn */
NULL, /* pGdiComment */
NULL, /* pGdiRealizationInfo */
NULL, /* pGetBoundsRect */
X11DRV_GetBoundsRect, /* pGetBoundsRect */
NULL, /* pGetCharABCWidths */
NULL, /* pGetCharABCWidthsI */
NULL, /* pGetCharWidth */
......
......@@ -2256,6 +2256,7 @@ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
void flush_gl_drawable(X11DRV_PDEVICE *physDev)
{
int w, h;
RECT rect;
if (!physDev->gl_copy || !physDev->current_pf)
return;
......@@ -2275,6 +2276,8 @@ void flush_gl_drawable(X11DRV_PDEVICE *physDev)
XCopyArea(gdi_display, src, physDev->drawable, physDev->gc, 0, 0, w, h,
physDev->dc_rect.left, physDev->dc_rect.top);
wine_tsx11_unlock();
SetRect( &rect, 0, 0, w, h );
add_device_bounds( physDev, &rect );
}
}
......
......@@ -26,6 +26,7 @@
# error You must include config.h to use this header
#endif
#include <limits.h>
#include <stdarg.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
......@@ -122,6 +123,7 @@ typedef struct
Drawable drawable;
RECT dc_rect; /* DC rectangle relative to drawable */
RECT drawable_rect; /* Drawable rectangle relative to screen */
RECT bounds; /* Graphics bounds */
HRGN region; /* Device region (visible region & clip region) */
X_PHYSPEN pen;
X_PHYSBRUSH brush;
......@@ -140,6 +142,21 @@ static inline X11DRV_PDEVICE *get_x11drv_dev( PHYSDEV dev )
return (X11DRV_PDEVICE *)dev;
}
static inline void reset_bounds( RECT *bounds )
{
bounds->left = bounds->top = INT_MAX;
bounds->right = bounds->bottom = INT_MIN;
}
static inline void add_bounds_rect( RECT *bounds, const RECT *rect )
{
if (rect->left >= rect->right || rect->top >= rect->bottom) return;
bounds->left = min( bounds->left, rect->left );
bounds->top = min( bounds->top, rect->top );
bounds->right = max( bounds->right, rect->right );
bounds->bottom = max( bounds->bottom, rect->bottom );
}
extern X_PHYSBITMAP BITMAP_stock_phys_bitmap DECLSPEC_HIDDEN; /* phys bitmap for the default stock bitmap */
/* Retrieve the GC used for bitmap operations */
......@@ -234,6 +251,7 @@ extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
extern BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
extern void restore_clipping_region( X11DRV_PDEVICE *dev ) DECLSPEC_HIDDEN;
extern void add_device_bounds( X11DRV_PDEVICE *dev, const RECT *rect ) DECLSPEC_HIDDEN;
extern void execute_rop( X11DRV_PDEVICE *physdev, Pixmap src_pixmap, GC gc, const RECT *visrect, DWORD rop ) DECLSPEC_HIDDEN;
......
......@@ -1680,6 +1680,7 @@ static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
POINT offset, desired, current;
int render_op = PictOpOver;
XRenderColor col;
RECT rect, bounds;
get_xrender_color( physdev, GetTextColor( physdev->dev.hdc ), &col );
pict = get_xrender_picture( physdev, 0, (flags & ETO_CLIPPED) ? lprect : NULL );
......@@ -1702,6 +1703,7 @@ static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
lprect->right - lprect->left,
lprect->bottom - lprect->top );
wine_tsx11_unlock();
add_device_bounds( physdev->x11dev, lprect );
}
if(count == 0) return TRUE;
......@@ -1750,6 +1752,7 @@ static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
if (physdev->format == WXR_FORMAT_MONO && col.red == 0 && col.green == 0 && col.blue == 0)
render_op = PictOpOutReverse; /* This gives us 'black' text */
reset_bounds( &bounds );
for(idx = 0; idx < count; idx++)
{
elts[idx].glyphset = formatEntry->glyphset;
......@@ -1761,6 +1764,12 @@ static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
current.x += (elts[idx].xOff + formatEntry->gis[wstr[idx]].xOff);
current.y += (elts[idx].yOff + formatEntry->gis[wstr[idx]].yOff);
rect.left = desired.x - physdev->x11dev->dc_rect.left - formatEntry->gis[wstr[idx]].x;
rect.top = desired.y - physdev->x11dev->dc_rect.top - formatEntry->gis[wstr[idx]].y;
rect.right = rect.left + formatEntry->gis[wstr[idx]].width;
rect.bottom = rect.top + formatEntry->gis[wstr[idx]].height;
add_bounds_rect( &bounds, &rect );
if(!lpDx)
{
desired.x += formatEntry->gis[wstr[idx]].xOff;
......@@ -1792,6 +1801,7 @@ static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
HeapFree(GetProcessHeap(), 0, elts);
LeaveCriticalSection(&xrender_cs);
add_device_bounds( physdev->x11dev, &bounds );
return TRUE;
}
......@@ -2170,6 +2180,7 @@ static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
}
else xrender_stretch_blit( physdev_src, physdev_dst, 0, src, dst );
add_device_bounds( physdev_dst->x11dev, &dst->visrect );
return TRUE;
x11drv_fallback:
......@@ -2272,6 +2283,8 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
}
else xrender_put_image( src_pixmap, src_pict, mask_pict, clip,
physdev->pict_format, physdev, 0, src, dst, use_repeat );
add_device_bounds( physdev->x11dev, &dst->visrect );
}
wine_tsx11_lock();
......@@ -2354,6 +2367,7 @@ static DWORD xrenderdrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct
wine_tsx11_unlock();
LeaveCriticalSection( &xrender_cs );
add_device_bounds( physdev->x11dev, &dst->visrect );
}
return ret;
......@@ -2459,6 +2473,7 @@ static BOOL xrenderdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
wine_tsx11_unlock();
LeaveCriticalSection( &xrender_cs );
add_device_bounds( physdev_dst->x11dev, &dst->visrect );
return TRUE;
}
......@@ -2476,6 +2491,7 @@ static BOOL xrenderdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG n
Picture src_pict, dst_pict;
unsigned int i;
const GRADIENT_RECT *rect = grad_array;
RECT rc;
POINT pt[2];
if (!pXRenderCreateLinearGradient) goto fallback;
......@@ -2535,8 +2551,13 @@ static BOOL xrenderdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG n
}
}
TRACE( "%u gradient %d,%d - %d,%d colors %04x,%04x,%04x,%04x -> %04x,%04x,%04x,%04x\n",
mode, pt[0].x, pt[0].y, pt[1].x, pt[1].y,
rc.left = min( pt[0].x, pt[1].x );
rc.top = min( pt[0].y, pt[1].y );
rc.right = max( pt[0].x, pt[1].x );
rc.bottom = max( pt[0].y, pt[1].y );
TRACE( "%u gradient %s colors %04x,%04x,%04x,%04x -> %04x,%04x,%04x,%04x\n",
mode, wine_dbgstr_rect( &rc ),
colors[0].red, colors[0].green, colors[0].blue, colors[0].alpha,
colors[1].red, colors[1].green, colors[1].blue, colors[1].alpha );
......@@ -2545,12 +2566,13 @@ static BOOL xrenderdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG n
wine_tsx11_lock();
src_pict = pXRenderCreateLinearGradient( gdi_display, &gradient, stops, colors, 2 );
xrender_blit( PictOpSrc, src_pict, 0, dst_pict,
0, 0, abs(pt[1].x - pt[0].x), abs(pt[1].y - pt[0].y),
physdev->x11dev->dc_rect.left + min( pt[0].x, pt[1].x ),
physdev->x11dev->dc_rect.top + min( pt[0].y, pt[1].y ),
abs(pt[1].x - pt[0].x), abs(pt[1].y - pt[0].y), 1, 1 );
0, 0, rc.right - rc.left, rc.bottom - rc.top,
physdev->x11dev->dc_rect.left + rc.left,
physdev->x11dev->dc_rect.top + rc.top,
rc.right - rc.left, rc.bottom - rc.top, 1, 1 );
pXRenderFreePicture( gdi_display, src_pict );
wine_tsx11_unlock();
add_device_bounds( physdev->x11dev, &rc );
}
return TRUE;
}
......
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