win32u: change the stretch mode of dst hdc from BlackOnWhite to ColorOnColor when using StretchBlt in TransparentBlt.
In NtGdiTransparentBlt function, the StretchBlt mode of dst hdc is not set. The Default StretchBlt Mode in wine is BlackOnWhite. It is not correct to use this StretchBltMode in TransparentBlt dealing with color bitmap. According to MSDN, it should be converted to ColorOnColor. My test code shows that, the image converted by wine generates a lot of chromatic noise.
[test_blt.c](/uploads/26101bc7bdb27400d02c8ff5bf741864/test_blt.c)
[test_blt.exe](/uploads/98ee3ab7ce0d590e1511bd8a5fb5a1bb/test_blt.exe)



-- v3: win32u: change the stretch mode of dst hdc from BlackOnWhite to ColorOnColor when using StretchBlt in TransparentBlt.
From: yangkun yangkun@uniontech.com
Signed-off-by: yangkun yangkun@uniontech.com Change-Id: Ic3c64a5d2ffef7d890f461b089223fbd7a972ffd --- dlls/win32u/bitblt.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/win32u/bitblt.c b/dlls/win32u/bitblt.c index a9f6f70daf6..d8c8aace7f0 100644 --- a/dlls/win32u/bitblt.c +++ b/dlls/win32u/bitblt.c @@ -857,6 +857,7 @@ BOOL WINAPI NtGdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDes int oldStretchMode; DIBSECTION dib; DC *dc_src; + DC *dc_work;
if(widthDest < 0 || heightDest < 0 || widthSrc < 0 || heightSrc < 0) { TRACE("Cannot mirror\n"); @@ -890,6 +891,11 @@ BOOL WINAPI NtGdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDes } else bmpWork = NtGdiCreateCompatibleBitmap( hdcDest, widthDest, heightDest ); oldWork = NtGdiSelectBitmap(hdcWork, bmpWork); + + if (!(dc_work = get_dc_ptr(hdcWork))) goto error; + dc_work->attr->stretch_blt_mode = COLORONCOLOR; + release_dc_ptr( dc_work ); + if (!NtGdiStretchBlt( hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY, 0 )) { @@ -937,6 +943,7 @@ error: release_dc_ptr( dc_src ); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, oldBackground, NULL ); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, oldForeground, NULL ); + if(hdcWork) { NtGdiSelectBitmap(hdcWork, oldWork); NtGdiDeleteObjectApp( hdcWork );
Jinoh Kang (@iamahuman) commented about dlls/win32u/bitblt.c:
release_dc_ptr( dc_src ); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, oldBackground, NULL ); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, oldForeground, NULL );
Gratuitous newline.
```suggestion:-0+0 ```
@huw while reviewing this patch I noticed that we're temporarily currently modifying stretch_blt_mode of the *source* DC, as introduced in 4a4b5d407c30dc79a632ec8c024566e5d096e47e.
I'm inclined to think that this was a mistake, since the stretch blit mode of the source DC should not affect the stretching operation. Should we fix it in this MR, or can we do it in another MR?