From bfc12c0c948c7d07d1c776375604b4a489f73f4b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 11 Jul 2011 14:17:04 +0200 Subject: [PATCH] gdi32: Pass the source/dest visible rectangles to the AlphaBlend driver entry point. --- dlls/gdi32/bitblt.c | 31 +++++-- dlls/gdi32/driver.c | 5 +- dlls/gdi32/gdi_private.h | 2 +- dlls/winex11.drv/bitblt.c | 146 ++---------------------------- dlls/winex11.drv/winex11.drv.spec | 2 +- dlls/winex11.drv/x11drv.h | 4 +- dlls/winex11.drv/xrender.c | 4 +- 7 files changed, 40 insertions(+), 154 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index f065290b473..9a9d7157f0c 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -607,22 +607,39 @@ BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heig BOOL ret = FALSE; DC *dcDst, *dcSrc; - TRACE( "%p %d,%d %dx%d -> %p %d,%d %dx%d op=%02x flags=%02x srcconstalpha=%02x alphafmt=%02x\n", - hdcSrc, xSrc, ySrc, widthSrc, heightSrc, hdcDst, xDst, yDst, widthDst, heightDst, - blendFunction.BlendOp, blendFunction.BlendFlags, - blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat ); - dcSrc = get_dc_ptr( hdcSrc ); if (!dcSrc) return FALSE; if ((dcDst = get_dc_ptr( hdcDst ))) { + struct bitblt_coords src, dst; PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend ); PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend ); + update_dc( dcSrc ); update_dc( dcDst ); - ret = dst_dev->funcs->pAlphaBlend( dst_dev, xDst, yDst, widthDst, heightDst, - src_dev, xSrc, ySrc, widthSrc, heightSrc, blendFunction ); + + src.log_x = xSrc; + src.log_y = ySrc; + src.log_width = widthSrc; + src.log_height = heightSrc; + src.layout = GetLayout( src_dev->hdc ); + dst.log_x = xDst; + dst.log_y = yDst; + dst.log_width = widthDst; + dst.log_height = heightDst; + dst.layout = GetLayout( dst_dev->hdc ); + get_vis_rectangles( dcDst, &dst, dcSrc, &src ); + + TRACE("src %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s dst %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s blend=%02x/%02x/%02x/%02x\n", + hdcSrc, src.log_x, src.log_y, src.log_width, src.log_height, + src.x, src.y, src.width, src.height, wine_dbgstr_rect(&src.visrect), + hdcDst, dst.log_x, dst.log_y, dst.log_width, dst.log_height, + dst.x, dst.y, dst.width, dst.height, wine_dbgstr_rect(&dst.visrect), + blendFunction.BlendOp, blendFunction.BlendFlags, + blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat ); + + ret = dst_dev->funcs->pAlphaBlend( dst_dev, &dst, src_dev, &src, blendFunction ); release_dc_ptr( dcDst ); } release_dc_ptr( dcSrc ); diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 2be12b8f0bf..1c4c2d7ee94 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -318,9 +318,8 @@ static INT CDECL nulldrv_AbortDoc( PHYSDEV dev ) return 0; } -static BOOL CDECL nulldrv_AlphaBlend( PHYSDEV dst_dev, INT x_dst, INT y_dst, INT width_dst, INT height_dst, - PHYSDEV src_dev, INT x_src, INT y_src, INT width_src, INT height_src, - BLENDFUNCTION func) +static BOOL CDECL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, + PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func) { return TRUE; } diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index feb30f82827..2d8ea5d15b8 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -152,7 +152,7 @@ typedef struct gdi_dc_funcs { INT (CDECL *pAbortDoc)(PHYSDEV); BOOL (CDECL *pAbortPath)(PHYSDEV); - BOOL (CDECL *pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,BLENDFUNCTION); + BOOL (CDECL *pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION); BOOL (CDECL *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT); BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 71fd11abaef..277cfb57bc5 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1165,116 +1165,6 @@ static int BITBLT_PutDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, RECT *visRe } -/*********************************************************************** - * BITBLT_GetVisRectangles - * - * Get the source and destination visible rectangles for StretchBlt(). - * Return FALSE if one of the rectangles is empty. - */ -static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, X11DRV_PDEVICE *physDevSrc, - struct bitblt_coords *dst, struct bitblt_coords *src ) -{ - RECT rect, clipRect; - - /* Get the destination visible rectangle */ - - rect.left = dst->x; - rect.top = dst->y; - rect.right = dst->x + dst->width; - rect.bottom = dst->y + dst->height; - LPtoDP( physDevDst->dev.hdc, (POINT *)&rect, 2 ); - dst->x = rect.left; - dst->y = rect.top; - dst->width = rect.right - rect.left; - dst->height = rect.bottom - rect.top; - if (dst->layout & LAYOUT_RTL && dst->layout & LAYOUT_BITMAPORIENTATIONPRESERVED) - { - SWAP_INT32( &rect.left, &rect.right ); - dst->x = rect.left; - dst->width = rect.right - rect.left; - } - if (rect.left > rect.right) { SWAP_INT32( &rect.left, &rect.right ); rect.left++; rect.right++; } - if (rect.top > rect.bottom) { SWAP_INT32( &rect.top, &rect.bottom ); rect.top++; rect.bottom++; } - - GetRgnBox( physDevDst->region, &clipRect ); - if (!IntersectRect( &dst->visrect, &rect, &clipRect )) return FALSE; - - /* Get the source visible rectangle */ - - if (!physDevSrc) return TRUE; - - rect.left = src->x; - rect.top = src->y; - rect.right = src->x + src->width; - rect.bottom = src->y + src->height; - LPtoDP( physDevSrc->dev.hdc, (POINT *)&rect, 2 ); - src->x = rect.left; - src->y = rect.top; - src->width = rect.right - rect.left; - src->height = rect.bottom - rect.top; - if (src->layout & LAYOUT_RTL && src->layout & LAYOUT_BITMAPORIENTATIONPRESERVED) - { - SWAP_INT32( &rect.left, &rect.right ); - src->x = rect.left; - src->width = rect.right - rect.left; - } - if (rect.left > rect.right) { SWAP_INT32( &rect.left, &rect.right ); rect.left++; rect.right++; } - if (rect.top > rect.bottom) { SWAP_INT32( &rect.top, &rect.bottom ); rect.top++; rect.bottom++; } - - /* Apparently the clipping and visible regions are only for output, - so just check against dc extent here to avoid BadMatch errors */ - clipRect = physDevSrc->drawable_rect; - OffsetRect( &clipRect, -(physDevSrc->drawable_rect.left + physDevSrc->dc_rect.left), - -(physDevSrc->drawable_rect.top + physDevSrc->dc_rect.top) ); - if (!IntersectRect( &src->visrect, &rect, &clipRect )) - return FALSE; - - /* Intersect the rectangles */ - - if ((src->width == dst->width) && (src->height == dst->height)) /* no stretching */ - { - OffsetRect( &src->visrect, dst->x - src->x, dst->y - src->y ); - if (!IntersectRect( &rect, &src->visrect, &dst->visrect )) return FALSE; - src->visrect = dst->visrect = rect; - OffsetRect( &src->visrect, src->x - dst->x, src->y - dst->y ); - } - else /* stretching */ - { - /* Map source rectangle into destination coordinates */ - rect.left = dst->x + (src->visrect.left - src->x)*dst->width/src->width; - rect.top = dst->y + (src->visrect.top - src->y)*dst->height/src->height; - rect.right = dst->x + (src->visrect.right - src->x)*dst->width/src->width; - 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.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom ); - - /* Avoid rounding errors */ - rect.left--; - rect.top--; - rect.right++; - rect.bottom++; - if (!IntersectRect( &dst->visrect, &rect, &dst->visrect )) return FALSE; - - /* Map destination rectangle back to source coordinates */ - rect = dst->visrect; - rect.left = src->x + (dst->visrect.left - dst->x)*src->width/dst->width; - rect.top = src->y + (dst->visrect.top - dst->y)*src->height/dst->height; - rect.right = src->x + (dst->visrect.right - dst->x)*src->width/dst->width; - 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.top > rect.bottom) SWAP_INT32( &rect.top, &rect.bottom ); - - /* Avoid rounding errors */ - rect.left--; - rect.top--; - rect.right++; - rect.bottom++; - if (!IntersectRect( &src->visrect, &rect, &src->visrect )) return FALSE; - } - return TRUE; -} - - /*********************************************************************** * client_side_dib_copy */ @@ -1639,41 +1529,21 @@ done: /*********************************************************************** * X11DRV_AlphaBlend */ -BOOL CDECL X11DRV_AlphaBlend( PHYSDEV dst_dev, INT xDst, INT yDst, INT widthDst, INT heightDst, - PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, - BLENDFUNCTION blendfn ) +BOOL CDECL X11DRV_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, + PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION blendfn ) { X11DRV_PDEVICE *physDevDst = get_x11drv_dev( dst_dev ); X11DRV_PDEVICE *physDevSrc = get_x11drv_dev( src_dev ); /* FIXME: check that it's really an x11 dev */ - struct bitblt_coords src, dst; - src.x = xSrc; - src.y = ySrc; - src.width = widthSrc; - src.height = heightSrc; - src.layout = GetLayout( src_dev->hdc ); - dst.x = xDst; - dst.y = yDst; - dst.width = widthDst; - dst.height = heightDst; - dst.layout = GetLayout( dst_dev->hdc ); - - if (!BITBLT_GetVisRectangles( physDevDst, physDevSrc, &dst, &src )) return TRUE; - - TRACE( "format %x alpha %u rectdst=%d,%d %dx%d orgdst=%d,%d visdst=%s rectsrc=%d,%d %dx%d orgsrc=%d,%d vissrc=%s\n", - blendfn.AlphaFormat, blendfn.SourceConstantAlpha, dst.x, dst.y, dst.width, dst.height, - physDevDst->dc_rect.left, physDevDst->dc_rect.top, wine_dbgstr_rect( &dst.visrect ), - src.x, src.y, src.width, src.height, - physDevSrc->dc_rect.left, physDevSrc->dc_rect.top, wine_dbgstr_rect( &src.visrect ) ); - - if (src.x < 0 || src.y < 0 || src.width < 0 || src.height < 0 || - src.width > physDevSrc->drawable_rect.right - physDevSrc->drawable_rect.left - src.x || - src.height > physDevSrc->drawable_rect.bottom - physDevSrc->drawable_rect.top - src.y) + if (src->x < 0 || src->y < 0 || src->width < 0 || src->height < 0 || + src->width > physDevSrc->drawable_rect.right - physDevSrc->drawable_rect.left - src->x || + src->height > physDevSrc->drawable_rect.bottom - physDevSrc->drawable_rect.top - src->y) { - WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src.x, src.y, src.width, src.height ); + WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src->x, src->y, src->width, src->height ); SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } + if (IsRectEmpty( &dst->visrect )) return TRUE; - return XRender_AlphaBlend( physDevDst, physDevSrc, &dst, &src, blendfn ); + return XRender_AlphaBlend( physDevDst, dst, physDevSrc, src, blendfn ); } diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 07c6ec7a07a..0c63c15383b 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -1,6 +1,6 @@ # GDI driver -@ cdecl AlphaBlend(ptr long long long long ptr long long long long long) X11DRV_AlphaBlend +@ cdecl AlphaBlend(ptr ptr ptr ptr long) X11DRV_AlphaBlend @ cdecl Arc(ptr long long long long long long long long) X11DRV_Arc @ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat @ cdecl Chord(ptr long long long long long long long long) X11DRV_Chord diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 149b5ce0346..8bbf04dc12f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -290,8 +290,8 @@ BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE Pixmap pixmap, GC gc, const struct bitblt_coords *src, const struct bitblt_coords *dst ) DECLSPEC_HIDDEN; extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN; -extern BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, X11DRV_PDEVICE *devSrc, - struct bitblt_coords *dst, struct bitblt_coords *src, +extern BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst, + X11DRV_PDEVICE *devSrc, struct bitblt_coords *src, BLENDFUNCTION blendfn ) DECLSPEC_HIDDEN; extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 17e646ac7c6..dc603af237f 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2208,8 +2208,8 @@ static void xrender_mono_blit( Picture src_pict, Picture mask_pict, Picture dst_ /****************************************************************************** * AlphaBlend */ -BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, X11DRV_PDEVICE *devSrc, - struct bitblt_coords *dst, struct bitblt_coords *src, BLENDFUNCTION blendfn ) +BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst, + X11DRV_PDEVICE *devSrc, struct bitblt_coords *src, BLENDFUNCTION blendfn ) { Picture dst_pict, src_pict = 0, mask_pict = 0, tmp_pict = 0; struct xrender_info *src_info = get_xrender_info( devSrc );