-- v4: gdiplus: Fix drawing indexed bitmaps with a palette that has alpha. gdiplus/tests: Test drawing indexed bitmaps with a palette that has alpha.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/gdiplus/tests/graphics.c | 46 ++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index dd25dd54fb2..fc9700b1058 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -6849,6 +6849,7 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void) RECT rect = {100, 100, 180, 180}; UINT width = rect.right - rect.left; UINT height = rect.bottom - rect.top; + ColorPalette palette; GpStatus status = 0; union { @@ -6896,7 +6897,6 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void) expect(Ok, status);
GdipDisposeImage(src_img.image); - GdipDeleteGraphics(graphics); GdipFree(src_img_data);
pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); @@ -6914,6 +6914,50 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void) "Expected GdipDrawImageRectRectI take effect!\n" ); GdipFree(pixel);
+ /* Draw a PixelFormat8bppIndexed bitmap with a palette that has alpha */ + src_img_data = GdipAlloc(src_img_width * src_img_height); + memset(src_img_data, 0, src_img_width * src_img_height); + status = GdipCreateBitmapFromScan0(src_img_width, src_img_height, src_img_width, + PixelFormat8bppIndexed, src_img_data, &src_img.bitmap); + expect(Ok, status); + + palette.Flags = PaletteFlagsHasAlpha; + palette.Count = 1; + palette.Entries[0] = 0x00ffffff; + status = GdipSetImagePalette(src_img.image, &palette); + expect(Ok, status); + + status = GdipDrawImageRectRectI(graphics, src_img.image, rect.left + width / 2, + rect.top + height / 2, width / 2, height / 2, 0, 0, + src_img_width, src_img_height, UnitPixel, NULL, NULL, NULL); + expect(Ok, status); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + color[0] = get_bitmap_pixel(width / 2, height / 2); + todo_wine + ok(is_blue_color(color[0]), "Got unexpected color %#lx.\n", color[0]); + GdipFree(pixel); + + /* Draw a PixelFormat8bppIndexed bitmap with a palette that has alpha without PaletteFlagsHasAlpha */ + palette.Flags = PaletteFlagsGrayScale; + status = GdipSetImagePalette(src_img.image, &palette); + expect(Ok, status); + + status = GdipDrawImageRectRectI(graphics, src_img.image, rect.left + width / 2, + rect.top + height / 2, width / 2, height / 2, 0, 0, + src_img_width, src_img_height, UnitPixel, NULL, NULL, NULL); + expect(Ok, status); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + color[0] = get_bitmap_pixel(width / 2, height / 2); + todo_wine + ok(is_blue_color(color[0]), "Got unexpected color %#lx.\n", color[0]); + GdipFree(pixel); + + GdipDisposeImage(src_img.image); + GdipFree(src_img_data); + + GdipDeleteGraphics(graphics); SelectObject(hdc, old); DeleteObject(bmp); DeleteDC(hdc);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/gdiplus/graphics.c | 4 ++-- dlls/gdiplus/tests/graphics.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 49a9d453b3d..700914e6f6e 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3451,7 +3451,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image if (bitmap->format == PixelFormat16bppRGB555 || bitmap->format == PixelFormat24bppRGB) dst_format = bitmap->format; - else if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha)) + else if (bitmap->image.flags & ImageFlagsHasAlpha) dst_format = PixelFormat32bppPARGB; else dst_format = PixelFormat32bppRGB; @@ -3494,7 +3494,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
gdi_transform_acquire(graphics);
- if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha)) + if (bitmap->image.flags & ImageFlagsHasAlpha) { gdi_alpha_blend(graphics, pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y, src_hdc, srcx, srcy, srcwidth, srcheight); diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index fc9700b1058..96ef52ce935 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -6934,7 +6934,6 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void)
pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); color[0] = get_bitmap_pixel(width / 2, height / 2); - todo_wine ok(is_blue_color(color[0]), "Got unexpected color %#lx.\n", color[0]); GdipFree(pixel);
@@ -6950,7 +6949,6 @@ static void test_GdipDrawImagePointsRectOnMemoryDC(void)
pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); color[0] = get_bitmap_pixel(width / 2, height / 2); - todo_wine ok(is_blue_color(color[0]), "Got unexpected color %#lx.\n", color[0]); GdipFree(pixel);
On Tue Jul 1 03:25:34 2025 +0000, Zhiyi Zhang wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/8461/diffs?diff_id=189892&start_sha=9baa15765a3635f938025660c71e1035409d3cc8#5be9ed8b7c2f88d687bb28583f357cc92af4f881_6919_6919)
Removing this line causes test failures because GdipAlloc() on Windows doesn't zero memory. Please see https://gitlab.winehq.org/wine/wine/-/jobs/170083 for the result with v3 that doesn't have this line.
On Tue Jul 1 04:37:01 2025 +0000, Zhiyi Zhang wrote:
Removing this line causes test failures because GdipAlloc() on Windows doesn't zero memory. Please see https://gitlab.winehq.org/wine/wine/-/jobs/170083 for the result with v3 that doesn't have this line.
We should probably change GdipAlloc() to use malloc() for better performance. We had cases in MediaFoundation where zeroing memory for a large buffer causes stutters. I will send a patch.
On Tue Jul 1 04:40:57 2025 +0000, Zhiyi Zhang wrote:
We should probably change GdipAlloc() to use malloc() for better performance. We had cases in MediaFoundation where zeroing memory for a large buffer causes stutters. I will send a patch.
I sent https://gitlab.winehq.org/wine/wine/-/merge_requests/8471 to avoid zeroing out allocated memory from GdipAlloc().
This merge request was approved by Esme Povirk.