winex11: Define a structure to hold coordinates information for BitBlt operations.

This commit is contained in:
Alexandre Julliard 2010-04-14 20:27:17 +02:00
parent 5842971b15
commit 39493b0660
3 changed files with 135 additions and 131 deletions

View File

@ -849,46 +849,58 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
* pixels to Windows colors. * pixels to Windows colors.
*/ */
static int BITBLT_GetSrcAreaStretch( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, static int BITBLT_GetSrcAreaStretch( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
Pixmap pixmap, GC gc, Pixmap pixmap, GC gc,
INT xSrc, INT ySrc, const struct bitblt_coords *src, const struct bitblt_coords *dst )
INT widthSrc, INT heightSrc,
INT xDst, INT yDst,
INT widthDst, INT heightDst,
RECT *visRectSrc, RECT *visRectDst )
{ {
XImage *imageSrc, *imageDst; XImage *imageSrc, *imageDst;
RECT rectSrc = *visRectSrc; RECT rectSrc = src->visrect;
RECT rectDst = *visRectDst; RECT rectDst = dst->visrect;
int fg, bg; int fg, bg;
if (widthSrc < 0) xSrc += widthSrc; rectSrc.left -= src->x;
if (widthDst < 0) xDst += widthDst; rectSrc.right -= src->x;
if (heightSrc < 0) ySrc += heightSrc; rectSrc.top -= src->y;
if (heightDst < 0) yDst += heightDst; rectSrc.bottom -= src->y;
rectSrc.left -= xSrc; rectDst.left -= dst->x;
rectSrc.right -= xSrc; rectDst.right -= dst->x;
rectSrc.top -= ySrc; rectDst.top -= dst->y;
rectSrc.bottom -= ySrc; rectDst.bottom -= dst->y;
rectDst.left -= xDst; if (src->width < 0)
rectDst.right -= xDst; {
rectDst.top -= yDst; rectSrc.left -= src->width;
rectDst.bottom -= yDst; rectSrc.right -= src->width;
}
if (dst->width < 0)
{
rectDst.left -= dst->width;
rectDst.right -= dst->width;
}
if (src->height < 0)
{
rectSrc.top -= src->height;
rectSrc.bottom -= src->height;
}
if (dst->height < 0)
{
rectDst.top -= dst->height;
rectDst.bottom -= dst->height;
}
get_colors(physDevDst, physDevSrc, &fg, &bg); get_colors(physDevDst, physDevSrc, &fg, &bg);
wine_tsx11_lock(); wine_tsx11_lock();
/* FIXME: avoid BadMatch errors */ /* FIXME: avoid BadMatch errors */
imageSrc = XGetImage( gdi_display, physDevSrc->drawable, imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
physDevSrc->dc_rect.left + visRectSrc->left, physDevSrc->dc_rect.left + src->visrect.left,
physDevSrc->dc_rect.top + visRectSrc->top, physDevSrc->dc_rect.top + src->visrect.top,
visRectSrc->right - visRectSrc->left, src->visrect.right - src->visrect.left,
visRectSrc->bottom - visRectSrc->top, src->visrect.bottom - src->visrect.top,
AllPlanes, ZPixmap ); AllPlanes, ZPixmap );
wine_tsx11_unlock(); wine_tsx11_unlock();
imageDst = X11DRV_DIB_CreateXImage( rectDst.right - rectDst.left, imageDst = X11DRV_DIB_CreateXImage( rectDst.right - rectDst.left,
rectDst.bottom - rectDst.top, physDevDst->depth ); rectDst.bottom - rectDst.top, physDevDst->depth );
BITBLT_StretchImage( imageSrc, imageDst, widthSrc, heightSrc, BITBLT_StretchImage( imageSrc, imageDst, src->width, src->height,
widthDst, heightDst, &rectSrc, &rectDst, dst->width, dst->height, &rectSrc, &rectDst,
fg, physDevDst->depth != 1 ? fg, physDevDst->depth != 1 ?
bg : physDevSrc->backgroundPixel, bg : physDevSrc->backgroundPixel,
GetStretchBltMode(physDevDst->hdc) ); GetStretchBltMode(physDevDst->hdc) );
@ -1142,64 +1154,55 @@ static int BITBLT_PutDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, RECT *visRe
* Get the source and destination visible rectangles for StretchBlt(). * Get the source and destination visible rectangles for StretchBlt().
* Return FALSE if one of the rectangles is empty. * Return FALSE if one of the rectangles is empty.
*/ */
static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, X11DRV_PDEVICE *physDevSrc,
INT widthDst, INT heightDst, struct bitblt_coords *dst, struct bitblt_coords *src )
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
INT widthSrc, INT heightSrc,
RECT *visRectSrc, RECT *visRectDst )
{ {
RECT rect, clipRect; RECT rect, clipRect;
/* Get the destination visible rectangle */ /* Get the destination visible rectangle */
rect.left = xDst; rect.left = dst->x;
rect.top = yDst; rect.top = dst->y;
rect.right = xDst + widthDst; rect.right = dst->x + dst->width;
rect.bottom = yDst + heightDst; rect.bottom = dst->y + dst->height;
if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right ); if (dst->width < 0) SWAP_INT32( &rect.left, &rect.right );
if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom ); if (dst->height < 0) SWAP_INT32( &rect.top, &rect.bottom );
GetRgnBox( physDevDst->region, &clipRect ); GetRgnBox( physDevDst->region, &clipRect );
if (!IntersectRect( visRectDst, &rect, &clipRect )) return FALSE; if (!IntersectRect( &dst->visrect, &rect, &clipRect )) return FALSE;
/* Get the source visible rectangle */ /* Get the source visible rectangle */
if (!physDevSrc) return TRUE; if (!physDevSrc) return TRUE;
rect.left = xSrc; rect.left = src->x;
rect.top = ySrc; rect.top = src->y;
rect.right = xSrc + widthSrc; rect.right = src->x + src->width;
rect.bottom = ySrc + heightSrc; rect.bottom = src->y + src->height;
if (widthSrc < 0) SWAP_INT32( &rect.left, &rect.right ); if (src->width < 0) SWAP_INT32( &rect.left, &rect.right );
if (heightSrc < 0) SWAP_INT32( &rect.top, &rect.bottom ); if (src->height < 0) SWAP_INT32( &rect.top, &rect.bottom );
/* Apparently the clipping and visible regions are only for output, /* Apparently the clipping and visible regions are only for output,
so just check against dc extent here to avoid BadMatch errors */ so just check against dc extent here to avoid BadMatch errors */
clipRect = physDevSrc->drawable_rect; clipRect = physDevSrc->drawable_rect;
OffsetRect( &clipRect, -(physDevSrc->drawable_rect.left + physDevSrc->dc_rect.left), OffsetRect( &clipRect, -(physDevSrc->drawable_rect.left + physDevSrc->dc_rect.left),
-(physDevSrc->drawable_rect.top + physDevSrc->dc_rect.top) ); -(physDevSrc->drawable_rect.top + physDevSrc->dc_rect.top) );
if (!IntersectRect( visRectSrc, &rect, &clipRect )) if (!IntersectRect( &src->visrect, &rect, &clipRect ))
return FALSE; return FALSE;
/* Intersect the rectangles */ /* Intersect the rectangles */
if ((widthSrc == widthDst) && (heightSrc == heightDst)) /* no stretching */ if ((src->width == dst->width) && (src->height == dst->height)) /* no stretching */
{ {
visRectSrc->left += xDst - xSrc; OffsetRect( &src->visrect, dst->x - src->x, dst->y - src->y );
visRectSrc->right += xDst - xSrc; if (!IntersectRect( &rect, &src->visrect, &dst->visrect )) return FALSE;
visRectSrc->top += yDst - ySrc; src->visrect = dst->visrect = rect;
visRectSrc->bottom += yDst - ySrc; OffsetRect( &src->visrect, src->x - dst->x, src->y - dst->y );
if (!IntersectRect( &rect, visRectSrc, visRectDst )) return FALSE;
*visRectSrc = *visRectDst = rect;
visRectSrc->left += xSrc - xDst;
visRectSrc->right += xSrc - xDst;
visRectSrc->top += ySrc - yDst;
visRectSrc->bottom += ySrc - yDst;
} }
else /* stretching */ else /* stretching */
{ {
/* Map source rectangle into destination coordinates */ /* Map source rectangle into destination coordinates */
rect.left = xDst + (visRectSrc->left - xSrc)*widthDst/widthSrc; rect.left = dst->x + (src->visrect.left - src->x)*dst->width/src->width;
rect.top = yDst + (visRectSrc->top - ySrc)*heightDst/heightSrc; rect.top = dst->y + (src->visrect.top - src->y)*dst->height/src->height;
rect.right = xDst + ((visRectSrc->right - xSrc)*widthDst)/widthSrc; rect.right = dst->x + (src->visrect.right - src->x)*dst->width/src->width;
rect.bottom = yDst + ((visRectSrc->bottom - ySrc)*heightDst)/heightSrc; rect.bottom = dst->y + (src->visrect.bottom - src->y)*dst->height/src->height;
if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right ); if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right );
if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom ); if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom );
@ -1208,14 +1211,14 @@ static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT y
rect.top--; rect.top--;
rect.right++; rect.right++;
rect.bottom++; rect.bottom++;
if (!IntersectRect( visRectDst, &rect, visRectDst )) return FALSE; if (!IntersectRect( &dst->visrect, &rect, &dst->visrect )) return FALSE;
/* Map destination rectangle back to source coordinates */ /* Map destination rectangle back to source coordinates */
rect = *visRectDst; rect = dst->visrect;
rect.left = xSrc + (visRectDst->left - xDst)*widthSrc/widthDst; rect.left = src->x + (dst->visrect.left - dst->x)*src->width/dst->width;
rect.top = ySrc + (visRectDst->top - yDst)*heightSrc/heightDst; rect.top = src->y + (dst->visrect.top - dst->y)*src->height/dst->height;
rect.right = xSrc + ((visRectDst->right - xDst)*widthSrc)/widthDst; rect.right = src->x + (dst->visrect.right - dst->x)*src->width/dst->width;
rect.bottom = ySrc + ((visRectDst->bottom - yDst)*heightSrc)/heightDst; rect.bottom = src->y + (dst->visrect.bottom - dst->y)*src->height/dst->height;
if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right ); if (rect.left > rect.right) SWAP_INT32( &rect.left, &rect.right );
if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom ); if (rect.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom );
@ -1224,7 +1227,7 @@ static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT y
rect.top--; rect.top--;
rect.right++; rect.right++;
rect.bottom++; rect.bottom++;
if (!IntersectRect( visRectSrc, &rect, visRectSrc )) return FALSE; if (!IntersectRect( &src->visrect, &rect, &src->visrect )) return FALSE;
} }
return TRUE; return TRUE;
} }
@ -1367,7 +1370,7 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
DWORD rop ) DWORD rop )
{ {
BOOL usePat, useSrc, useDst, destUsed, fStretch, fNullBrush; BOOL usePat, useSrc, useDst, destUsed, fStretch, fNullBrush;
RECT visRectDst, visRectSrc; struct bitblt_coords src, dst;
INT width, height; INT width, height;
INT sDst, sSrc = DIB_Status_None; INT sDst, sSrc = DIB_Status_None;
const BYTE *opcode; const BYTE *opcode;
@ -1422,31 +1425,35 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
TRACE(" rectsrc=%d,%d-%d,%d orgsrc=%d,%d\n", TRACE(" rectsrc=%d,%d-%d,%d orgsrc=%d,%d\n",
xSrc, ySrc, widthSrc, heightSrc, xSrc, ySrc, widthSrc, heightSrc,
physDevSrc->dc_rect.left, physDevSrc->dc_rect.top ); physDevSrc->dc_rect.left, physDevSrc->dc_rect.top );
if (!BITBLT_GetVisRectangles( physDevDst, xDst, yDst, widthDst, heightDst, src.x = xSrc;
physDevSrc, xSrc, ySrc, widthSrc, heightSrc, src.y = ySrc;
&visRectSrc, &visRectDst )) src.width = widthSrc;
src.height = heightSrc;
dst.x = xDst;
dst.y = yDst;
dst.width = widthDst;
dst.height = heightDst;
if (!BITBLT_GetVisRectangles( physDevDst, physDevSrc, &dst, &src ))
return TRUE; return TRUE;
TRACE(" vissrc=%d,%d-%d,%d visdst=%d,%d-%d,%d\n", TRACE(" vissrc=%s visdst=%s\n",
visRectSrc.left, visRectSrc.top, wine_dbgstr_rect( &src.visrect ), wine_dbgstr_rect( &dst.visrect ) );
visRectSrc.right, visRectSrc.bottom,
visRectDst.left, visRectDst.top,
visRectDst.right, visRectDst.bottom );
if (physDevDst != physDevSrc) if (physDevDst != physDevSrc)
sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None ); sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None );
} }
else else
{ {
fStretch = FALSE; fStretch = FALSE;
if (!BITBLT_GetVisRectangles( physDevDst, xDst, yDst, widthDst, heightDst, dst.x = xDst;
NULL, 0, 0, 0, 0, NULL, &visRectDst )) dst.y = yDst;
dst.width = widthDst;
dst.height = heightDst;
if (!BITBLT_GetVisRectangles( physDevDst, NULL, &dst, NULL ))
return TRUE; return TRUE;
TRACE(" vissrc=none visdst=%d,%d-%d,%d\n", TRACE(" vissrc=none visdst=%s\n", wine_dbgstr_rect( &dst.visrect ) );
visRectDst.left, visRectDst.top,
visRectDst.right, visRectDst.bottom );
} }
width = visRectDst.right - visRectDst.left; width = dst.visrect.right - dst.visrect.left;
height = visRectDst.bottom - visRectDst.top; height = dst.visrect.bottom - dst.visrect.top;
sDst = X11DRV_LockDIBSection( physDevDst, DIB_Status_None ); sDst = X11DRV_LockDIBSection( physDevDst, DIB_Status_None );
if (physDevDst == physDevSrc) sSrc = sDst; if (physDevDst == physDevSrc) sSrc = sDst;
@ -1456,8 +1463,8 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
sSrc == DIB_Status_AppMod && sDst == DIB_Status_AppMod && sSrc == DIB_Status_AppMod && sDst == DIB_Status_AppMod &&
same_format(physDevSrc, physDevDst)) same_format(physDevSrc, physDevDst))
{ {
if (client_side_dib_copy( physDevSrc, visRectSrc.left, visRectSrc.top, if (client_side_dib_copy( physDevSrc, src.visrect.left, src.visrect.top,
physDevDst, visRectDst.left, visRectDst.top, width, height )) physDevDst, dst.visrect.left, dst.visrect.top, width, height ))
goto done; goto done;
} }
@ -1485,8 +1492,8 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
WhitePixel( gdi_display, DefaultScreen(gdi_display) )); WhitePixel( gdi_display, DefaultScreen(gdi_display) ));
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid ); XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + dst.visrect.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + dst.visrect.top,
width, height ); width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
goto done; goto done;
@ -1505,8 +1512,8 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
XSetForeground( gdi_display, physDevDst->gc, xor_pix); XSetForeground( gdi_display, physDevDst->gc, xor_pix);
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid ); XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + dst.visrect.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + dst.visrect.top,
width, height ); width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
goto done; goto done;
@ -1518,8 +1525,8 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
wine_tsx11_lock(); wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + dst.visrect.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + dst.visrect.top,
width, height ); width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
@ -1537,8 +1544,8 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
{ {
if (sSrc == DIB_Status_AppMod) if (sSrc == DIB_Status_AppMod)
{ {
X11DRV_DIB_CopyDIBSection( physDevSrc, physDevDst, visRectSrc.left, visRectSrc.top, X11DRV_DIB_CopyDIBSection( physDevSrc, physDevDst, src.visrect.left, src.visrect.top,
visRectDst.left, visRectDst.top, width, height ); dst.visrect.left, dst.visrect.top, width, height );
goto done; goto done;
} }
X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
@ -1546,11 +1553,11 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
wine_tsx11_lock(); wine_tsx11_lock();
XCopyArea( gdi_display, physDevSrc->drawable, XCopyArea( gdi_display, physDevSrc->drawable,
physDevDst->drawable, physDevDst->gc, physDevDst->drawable, physDevDst->gc,
physDevSrc->dc_rect.left + visRectSrc.left, physDevSrc->dc_rect.left + src.visrect.left,
physDevSrc->dc_rect.top + visRectSrc.top, physDevSrc->dc_rect.top + src.visrect.top,
width, height, width, height,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + dst.visrect.left,
physDevDst->dc_rect.top + visRectDst.top ); physDevDst->dc_rect.top + dst.visrect.top );
physDevDst->exposures++; physDevDst->exposures++;
wine_tsx11_unlock(); wine_tsx11_unlock();
goto done; goto done;
@ -1567,11 +1574,11 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
XCopyPlane( gdi_display, physDevSrc->drawable, XCopyPlane( gdi_display, physDevSrc->drawable,
physDevDst->drawable, physDevDst->gc, physDevDst->drawable, physDevDst->gc,
physDevSrc->dc_rect.left + visRectSrc.left, physDevSrc->dc_rect.left + src.visrect.left,
physDevSrc->dc_rect.top + visRectSrc.top, physDevSrc->dc_rect.top + src.visrect.top,
width, height, width, height,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + dst.visrect.left,
physDevDst->dc_rect.top + visRectDst.top, 1 ); physDevDst->dc_rect.top + dst.visrect.top, 1 );
physDevDst->exposures++; physDevDst->exposures++;
wine_tsx11_unlock(); wine_tsx11_unlock();
goto done; goto done;
@ -1596,22 +1603,16 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, &src, &dst ))
widthSrc, heightSrc, widthDst, heightDst,
&visRectSrc, &visRectDst))
{ {
if (fStretch) if (fStretch)
BITBLT_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, BITBLT_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, &src, &dst );
xSrc, ySrc, widthSrc, heightSrc,
xDst, yDst, widthDst, heightDst,
&visRectSrc, &visRectDst );
else else
BITBLT_GetSrcArea( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, BITBLT_GetSrcArea( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, &src.visrect );
&visRectSrc );
} }
} }
if (useDst) BITBLT_GetDstArea( physDevDst, pixmaps[DST], tmpGC, &visRectDst ); if (useDst) BITBLT_GetDstArea( physDevDst, pixmaps[DST], tmpGC, &dst.visrect );
if (usePat) fNullBrush = !X11DRV_SetupGCForPatBlt( physDevDst, tmpGC, TRUE ); if (usePat) fNullBrush = !X11DRV_SetupGCForPatBlt( physDevDst, tmpGC, TRUE );
else fNullBrush = FALSE; else fNullBrush = FALSE;
destUsed = FALSE; destUsed = FALSE;
@ -1653,8 +1654,7 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, IN
} }
} }
XSetFunction( gdi_display, physDevDst->gc, GXcopy ); XSetFunction( gdi_display, physDevDst->gc, GXcopy );
physDevDst->exposures += BITBLT_PutDstArea( physDevDst, pixmaps[destUsed ? DST : SRC], physDevDst->exposures += BITBLT_PutDstArea( physDevDst, pixmaps[destUsed ? DST : SRC], &dst.visrect );
&visRectDst );
XFreePixmap( gdi_display, pixmaps[DST] ); XFreePixmap( gdi_display, pixmaps[DST] );
if (pixmaps[SRC]) XFreePixmap( gdi_display, pixmaps[SRC] ); if (pixmaps[SRC]) XFreePixmap( gdi_display, pixmaps[SRC] );
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] ); if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );

View File

@ -169,6 +169,15 @@ typedef struct
struct xrender_info *xrender; struct xrender_info *xrender;
} X11DRV_PDEVICE; } X11DRV_PDEVICE;
struct bitblt_coords
{
int x; /* original position and width */
int y;
int width;
int height;
RECT visrect; /* rectangle clipped to the visible part */
};
extern X_PHYSBITMAP BITMAP_stock_phys_bitmap; /* phys bitmap for the default stock bitmap */ extern X_PHYSBITMAP BITMAP_stock_phys_bitmap; /* phys bitmap for the default stock bitmap */
@ -293,9 +302,7 @@ extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UIN
extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib); extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib);
BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
Pixmap pixmap, GC gc, Pixmap pixmap, GC gc,
INT widthSrc, INT heightSrc, const struct bitblt_coords *src, const struct bitblt_coords *dst );
INT widthDst, INT heightDst,
RECT *visRectSrc, RECT *visRectDst);
extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev); extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev); extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev);

View File

@ -2187,15 +2187,13 @@ void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap,
BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
Pixmap pixmap, GC gc, Pixmap pixmap, GC gc,
INT widthSrc, INT heightSrc, const struct bitblt_coords *src, const struct bitblt_coords *dst )
INT widthDst, INT heightDst,
RECT *visRectSrc, RECT *visRectDst )
{ {
BOOL stretch = (widthSrc != widthDst) || (heightSrc != heightDst); BOOL stretch = (src->width != dst->width) || (src->height != dst->height);
int width = visRectDst->right - visRectDst->left; int width = dst->visrect.right - dst->visrect.left;
int height = visRectDst->bottom - visRectDst->top; int height = dst->visrect.bottom - dst->visrect.top;
int x_src = physDevSrc->dc_rect.left + visRectSrc->left; int x_src = physDevSrc->dc_rect.left + src->visrect.left;
int y_src = physDevSrc->dc_rect.top + visRectSrc->top; int y_src = physDevSrc->dc_rect.top + src->visrect.top;
struct xrender_info *src_info = get_xrender_info(physDevSrc); struct xrender_info *src_info = get_xrender_info(physDevSrc);
const WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDevDst->depth, physDevDst->color_shifts); const WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDevDst->depth, physDevDst->color_shifts);
Picture src_pict=0, dst_pict=0, mask_pict=0; Picture src_pict=0, dst_pict=0, mask_pict=0;
@ -2206,8 +2204,9 @@ BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
pa.subwindow_mode = IncludeInferiors; pa.subwindow_mode = IncludeInferiors;
pa.repeat = RepeatNone; pa.repeat = RepeatNone;
TRACE("src depth=%d widthSrc=%d heightSrc=%d xSrc=%d ySrc=%d\n", physDevSrc->depth, widthSrc, heightSrc, x_src, y_src); TRACE("src depth=%d widthSrc=%d heightSrc=%d xSrc=%d ySrc=%d\n",
TRACE("dst depth=%d widthDst=%d heightDst=%d\n", physDevDst->depth, widthDst, heightDst); physDevSrc->depth, src->width, src->height, x_src, y_src);
TRACE("dst depth=%d widthDst=%d heightDst=%d\n", physDevDst->depth, dst->width, dst->height);
if(!X11DRV_XRender_Installed) if(!X11DRV_XRender_Installed)
{ {
@ -2236,8 +2235,8 @@ BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
use_repeat = use_source_repeat( physDevSrc ); use_repeat = use_source_repeat( physDevSrc );
if (!use_repeat) if (!use_repeat)
{ {
xscale = widthSrc / (double)widthDst; xscale = src->width / (double)dst->width;
yscale = heightSrc / (double)heightDst; yscale = src->height / (double)dst->height;
} }
else xscale = yscale = 1; /* no scaling needed with a repeating source */ else xscale = yscale = 1; /* no scaling needed with a repeating source */
@ -2354,9 +2353,7 @@ BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel,
BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
Pixmap pixmap, GC gc, Pixmap pixmap, GC gc,
INT widthSrc, INT heightSrc, const struct bitblt_coords *src, const struct bitblt_coords *dst )
INT widthDst, INT heightDst,
RECT *visRectSrc, RECT *visRectDst )
{ {
return FALSE; return FALSE;
} }