gdi32: Pass the source/dest visible rectangles to the AlphaBlend driver entry point.
This commit is contained in:
parent
1ac1d7c69b
commit
bfc12c0c94
|
@ -607,22 +607,39 @@ BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heig
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
DC *dcDst, *dcSrc;
|
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 );
|
dcSrc = get_dc_ptr( hdcSrc );
|
||||||
if (!dcSrc) return FALSE;
|
if (!dcSrc) return FALSE;
|
||||||
|
|
||||||
if ((dcDst = get_dc_ptr( hdcDst )))
|
if ((dcDst = get_dc_ptr( hdcDst )))
|
||||||
{
|
{
|
||||||
|
struct bitblt_coords src, dst;
|
||||||
PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend );
|
PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend );
|
||||||
PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend );
|
PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend );
|
||||||
|
|
||||||
update_dc( dcSrc );
|
update_dc( dcSrc );
|
||||||
update_dc( dcDst );
|
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( dcDst );
|
||||||
}
|
}
|
||||||
release_dc_ptr( dcSrc );
|
release_dc_ptr( dcSrc );
|
||||||
|
|
|
@ -318,9 +318,8 @@ static INT CDECL nulldrv_AbortDoc( PHYSDEV dev )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CDECL nulldrv_AlphaBlend( PHYSDEV dst_dev, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
|
static BOOL CDECL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
||||||
PHYSDEV src_dev, INT x_src, INT y_src, INT width_src, INT height_src,
|
PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func)
|
||||||
BLENDFUNCTION func)
|
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ typedef struct gdi_dc_funcs
|
||||||
{
|
{
|
||||||
INT (CDECL *pAbortDoc)(PHYSDEV);
|
INT (CDECL *pAbortDoc)(PHYSDEV);
|
||||||
BOOL (CDECL *pAbortPath)(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 *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
|
||||||
BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
||||||
BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
||||||
|
|
|
@ -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
|
* client_side_dib_copy
|
||||||
*/
|
*/
|
||||||
|
@ -1639,41 +1529,21 @@ done:
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* X11DRV_AlphaBlend
|
* X11DRV_AlphaBlend
|
||||||
*/
|
*/
|
||||||
BOOL CDECL X11DRV_AlphaBlend( PHYSDEV dst_dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
|
BOOL CDECL X11DRV_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
||||||
PHYSDEV src_dev, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
|
PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION blendfn )
|
||||||
BLENDFUNCTION blendfn )
|
|
||||||
{
|
{
|
||||||
X11DRV_PDEVICE *physDevDst = get_x11drv_dev( dst_dev );
|
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 */
|
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;
|
if (src->x < 0 || src->y < 0 || src->width < 0 || src->height < 0 ||
|
||||||
src.y = ySrc;
|
src->width > physDevSrc->drawable_rect.right - physDevSrc->drawable_rect.left - src->x ||
|
||||||
src.width = widthSrc;
|
src->height > physDevSrc->drawable_rect.bottom - physDevSrc->drawable_rect.top - src->y)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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 );
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (IsRectEmpty( &dst->visrect )) return TRUE;
|
||||||
|
|
||||||
return XRender_AlphaBlend( physDevDst, physDevSrc, &dst, &src, blendfn );
|
return XRender_AlphaBlend( physDevDst, dst, physDevSrc, src, blendfn );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# GDI driver
|
# 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 Arc(ptr long long long long long long long long) X11DRV_Arc
|
||||||
@ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat
|
@ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat
|
||||||
@ cdecl Chord(ptr long long long long long long long long) X11DRV_Chord
|
@ cdecl Chord(ptr long long long long long long long long) X11DRV_Chord
|
||||||
|
|
|
@ -290,8 +290,8 @@ BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
|
||||||
Pixmap pixmap, GC gc,
|
Pixmap pixmap, GC gc,
|
||||||
const struct bitblt_coords *src, const struct bitblt_coords *dst ) DECLSPEC_HIDDEN;
|
const struct bitblt_coords *src, const struct bitblt_coords *dst ) DECLSPEC_HIDDEN;
|
||||||
extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
|
extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
|
||||||
extern BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, X11DRV_PDEVICE *devSrc,
|
extern BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
|
||||||
struct bitblt_coords *dst, struct bitblt_coords *src,
|
X11DRV_PDEVICE *devSrc, struct bitblt_coords *src,
|
||||||
BLENDFUNCTION blendfn ) DECLSPEC_HIDDEN;
|
BLENDFUNCTION blendfn ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
|
extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -2208,8 +2208,8 @@ static void xrender_mono_blit( Picture src_pict, Picture mask_pict, Picture dst_
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* AlphaBlend
|
* AlphaBlend
|
||||||
*/
|
*/
|
||||||
BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, X11DRV_PDEVICE *devSrc,
|
BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
|
||||||
struct bitblt_coords *dst, struct bitblt_coords *src, BLENDFUNCTION blendfn )
|
X11DRV_PDEVICE *devSrc, struct bitblt_coords *src, BLENDFUNCTION blendfn )
|
||||||
{
|
{
|
||||||
Picture dst_pict, src_pict = 0, mask_pict = 0, tmp_pict = 0;
|
Picture dst_pict, src_pict = 0, mask_pict = 0, tmp_pict = 0;
|
||||||
struct xrender_info *src_info = get_xrender_info( devSrc );
|
struct xrender_info *src_info = get_xrender_info( devSrc );
|
||||||
|
|
Loading…
Reference in New Issue