From c819e4bdea373406521e7e8a5361a0f40efec173 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 14 Sep 2011 11:57:45 +0200 Subject: [PATCH] gdi32: Add a null driver fallback for AlphaBlend, using a new BlendImage driver entry point. --- dlls/gdi32/bitblt.c | 45 +++++++++++++++++++++++++++++++++++++- dlls/gdi32/dibdrv/dc.c | 1 + dlls/gdi32/driver.c | 9 ++++---- dlls/gdi32/enhmfdrv/init.c | 1 + dlls/gdi32/gdi_private.h | 2 ++ dlls/gdi32/mfdrv/init.c | 1 + dlls/wineps.drv/init.c | 1 + dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/xrender.c | 1 + include/wine/gdi_driver.h | 3 ++- 10 files changed, 59 insertions(+), 6 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index 999f5ba2e12..98ced520521 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -196,7 +196,10 @@ static DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src return err; } -/* nulldrv fallback implementation using StretchDIBits */ +/*********************************************************************** + * null driver fallback implementations + */ + BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) { @@ -267,6 +270,46 @@ BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst, return !err; } + +BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, + PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func ) +{ + DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev ); + char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *src_info = (BITMAPINFO *)src_buffer; + BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer; + DWORD err; + struct gdi_image_bits bits; + + if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE; + src_dev = GET_DC_PHYSDEV( dc_src, pGetImage ); + err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &bits, src ); + release_dc_ptr( dc_src ); + if (err) return FALSE; + + dst_dev = GET_DC_PHYSDEV( dc_dst, pBlendImage ); + memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )); + err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); + if (err == ERROR_BAD_FORMAT) + { + err = convert_bits( src_info, src, dst_info, &bits ); + if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); + } + + if (err == ERROR_TRANSFORM_NOT_SUPPORTED && + ((src->width != dst->width) || (src->height != dst->height))) + { + memcpy( src_info, dst_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )); + err = stretch_bits( src_info, src, dst_info, dst, &bits, COLORONCOLOR ); + if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func ); + } + + if (bits.free) bits.free( &bits ); + return !err; +} + + /*********************************************************************** * PatBlt (GDI32.@) */ diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 99b441c02ff..b02ae8aec92 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -506,6 +506,7 @@ const DC_FUNCTIONS dib_driver = NULL, /* pArc */ NULL, /* pArcTo */ NULL, /* pBeginPath */ + NULL, /* pBlendImage */ NULL, /* pChoosePixelFormat */ NULL, /* pChord */ NULL, /* pCloseFigure */ diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 51e241f3c87..4f111c3f8f2 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -190,14 +190,14 @@ static INT nulldrv_AbortDoc( PHYSDEV dev ) return 0; } -static BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, - PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func) +static BOOL nulldrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ) { return TRUE; } -static BOOL nulldrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, - INT xstart, INT ystart, INT xend, INT yend ) +static DWORD nulldrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct gdi_image_bits *bits, + struct bitblt_coords *src, struct bitblt_coords *dst, BLENDFUNCTION func ) { return TRUE; } @@ -666,6 +666,7 @@ const DC_FUNCTIONS null_driver = nulldrv_Arc, /* pArc */ nulldrv_ArcTo, /* pArcTo */ nulldrv_BeginPath, /* pBeginPath */ + nulldrv_BlendImage, /* pBlendImage */ nulldrv_ChoosePixelFormat, /* pChoosePixelFormat */ nulldrv_Chord, /* pChord */ nulldrv_CloseFigure, /* pCloseFigure */ diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index 8ccb0503409..292f505fbfa 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -43,6 +43,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs = EMFDRV_Arc, /* pArc */ NULL, /* pArcTo */ EMFDRV_BeginPath, /* pBeginPath */ + NULL, /* pBlendImage */ NULL, /* pChoosePixelFormat */ EMFDRV_Chord, /* pChord */ EMFDRV_CloseFigure, /* pCloseFigure */ diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 4fe2e59711a..6cb8693b552 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -383,6 +383,8 @@ static inline void release_wine_region(HRGN rgn) /* null driver entry points */ extern BOOL nulldrv_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN; +extern BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst, + PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func) DECLSPEC_HIDDEN; extern BOOL nulldrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN; extern BOOL nulldrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN; extern BOOL nulldrv_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index 2139b989ed4..0c93571075d 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -88,6 +88,7 @@ static const DC_FUNCTIONS MFDRV_Funcs = MFDRV_Arc, /* pArc */ NULL, /* pArcTo */ MFDRV_BeginPath, /* pBeginPath */ + NULL, /* pBlendImage */ NULL, /* pChoosePixelFormat */ MFDRV_Chord, /* pChord */ MFDRV_CloseFigure, /* pCloseFigure */ diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index e7e545e44b5..3a6f89f4de4 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -825,6 +825,7 @@ static const struct gdi_dc_funcs psdrv_funcs = PSDRV_Arc, /* pArc */ NULL, /* pArcTo */ NULL, /* pBeginPath */ + NULL, /* pBlendImage */ NULL, /* pChoosePixelFormat */ PSDRV_Chord, /* pChord */ NULL, /* pCloseFigure */ diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index df6084a047c..96b6a7ad5b7 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -472,6 +472,7 @@ static const struct gdi_dc_funcs x11drv_funcs = X11DRV_Arc, /* pArc */ NULL, /* pArcTo */ NULL, /* pBeginPath */ + NULL, /* pBlendImage */ X11DRV_ChoosePixelFormat, /* pChoosePixelFormat */ X11DRV_Chord, /* pChord */ NULL, /* pCloseFigure */ diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 2e7aca36d86..e525d5f7702 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2598,6 +2598,7 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pArc */ NULL, /* pArcTo */ NULL, /* pBeginPath */ + NULL, /* pBlendImage */ NULL, /* pChoosePixelFormat */ NULL, /* pChord */ NULL, /* pCloseFigure */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 1e7ebdbd979..b15dbd184e2 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -61,6 +61,7 @@ struct gdi_dc_funcs BOOL (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); BOOL (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); BOOL (*pBeginPath)(PHYSDEV); + DWORD (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION); INT (*pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *); BOOL (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); BOOL (*pCloseFigure)(PHYSDEV); @@ -189,7 +190,7 @@ struct gdi_dc_funcs }; /* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 13 +#define WINE_GDI_DRIVER_VERSION 14 static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset ) {