[PATCH 2/5] gdi32: Implement EMFDRV_AlphaBlend().

Huw Davies huw at codeweavers.com
Mon Apr 19 03:33:08 CDT 2021


On Sun, Apr 18, 2021 at 09:00:44PM +0800, Zhiyi Zhang wrote:
> On 4/15/21 3:31 PM, Huw Davies wrote:
> > On Wed, Apr 14, 2021 at 03:27:57PM +0800, Zhiyi Zhang wrote:
> >> Fix a bug that Tally produces a blank print preview when images have to be scaled.
> >>
> >> Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
> >> ---
> >>  dlls/gdi32/enhmfdrv/bitblt.c         | 85 ++++++++++++++++++++++++++++
> >>  dlls/gdi32/enhmfdrv/enhmetafiledrv.h |  2 +
> >>  dlls/gdi32/enhmfdrv/init.c           |  2 +-
> >>  dlls/gdi32/tests/metafile.c          |  4 +-
> >>  4 files changed, 89 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c
> >> index 1fc5c0b1040..f0be2b52fc0 100644
> >> --- a/dlls/gdi32/enhmfdrv/bitblt.c
> >> +++ b/dlls/gdi32/enhmfdrv/bitblt.c
> >> @@ -27,6 +27,91 @@
> >>  #include "enhmetafiledrv.h"
> >>  #include "wine/debug.h"
> >>  
> >> +BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst, PHYSDEV dev_src,
> >> +                              struct bitblt_coords *src, BLENDFUNCTION func )
> >> +{
> >> +    UINT bits_size, bmi_size, emr_size, size, bpp;
> >> +    BITMAPINFOHEADER *bmih;
> >> +    EMRALPHABLEND *emr;
> >> +    HBITMAP hbitmap;
> >> +    BITMAP bitmap;
> >> +    BOOL ret;
> >> +
> >> +    /* can't use a metafile DC as source */
> >> +    if (dev_src->funcs == dev_dst->funcs)
> >> +        return FALSE;
> >> +
> >> +    hbitmap = GetCurrentObject(dev_src->hdc, OBJ_BITMAP);
> >> +    if (GetObjectW(hbitmap, sizeof(BITMAP), &bitmap) != sizeof(BITMAP))
> >> +        return FALSE;
> > This would likely be cleaner using the BlendImage entry point
> > (likewise I suspect StretchBlt would benefit from using PutImage).
> >
> I am afraid that it's not cleaner in practice. There are a few issues that make it less intuitive if I use the BlendImage entry point.
> 1. EMR_ALPHABLEND needs source DC to get world transform and background color, so we need to add a src_dev parameter to all BlendImage function calls.

Ah right.  In which case, as you say, we will need to implement
EMFDRV_AlphaBlend().  However to get the src bits call src's
pGetImage(), something like this (see nulldrv_AlphaBlend()):

    DC *dc_src = get_physdev_dc( src_dev );
    ...
    src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
    err = src_dev->funcs->pGetImage( src_dev, src_info, &bits, src );

The point is that this will work for src dcs that belong to the
display drivers too.

> 2. EMR_ALPHABLEND records always use BI_BITFIELDS compression when
> the source image is 16 bit or 32 bit. Something like the following
> in gdi32/dib.c#line 1367 in GetDIBits()
...
> Also need to reset biClrUsed to 0 as gdi32/dib.c#line 1462 in
> GetDIBits() to pass all the tests.

Fixing up these shouldn't be too horrible.

Huw.



More information about the wine-devel mailing list