gdiplus: GdipGraphicsClear() should overwrite pixels, not alpha blend.

All sample code in the Python Pyglet library suffers from terrible
text corruption, caused by the inability to erase the background
between rendering sequential font glyphs, resulting in leftovers
from previous letters mixing with the image of new letters.

This is because it attempts to erase the background by calling
GdipGraphicsClear() with ARGB color 0x00000000 (completely
transparent black), and in our gdiplus alpha blending that into
the background has no effect. It should be using
CompositeModeSourceCopy to overwrite the background with that brush
instead.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=30506
Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 3c8784bf9c)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
oldstable
Damjan Jovanovic 2019-12-13 05:17:54 +02:00 committed by Michael Stefaniuc
parent aad05a928f
commit b4e12ea07f
2 changed files with 47 additions and 0 deletions

View File

@ -4942,6 +4942,7 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
GpSolidFill *brush;
GpStatus stat;
GpRectF wnd_rect;
CompositingMode prev_comp_mode;
TRACE("(%p, %x)\n", graphics, color);
@ -4962,8 +4963,11 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
return stat;
}
GdipGetCompositingMode(graphics, &prev_comp_mode);
GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
GdipFillRectangle(graphics, (GpBrush*)brush, wnd_rect.X, wnd_rect.Y,
wnd_rect.Width, wnd_rect.Height);
GdipSetCompositingMode(graphics, prev_comp_mode);
GdipDeleteBrush((GpBrush*)brush);

View File

@ -5484,6 +5484,48 @@ todo_wine
GdipDisposeImage((GpImage *)bitmap);
}
static void test_graphics_clear(void)
{
BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
BYTE cleared[8] = { 0,0,0,0, 0,0,0,0 };
BYTE *bits;
GpBitmap *bitmap;
GpGraphics *graphics;
BitmapData data;
GpStatus status;
int match;
status = GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB, argb, &bitmap);
expect(Ok, status);
status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
expect(Ok, status);
status = GdipGraphicsClear(graphics, 0x00000000);
expect(Ok, status);
status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppARGB, &data);
expect(Ok, status);
ok(data.Width == 2, "expected 2, got %d\n", data.Width);
ok(data.Height == 1, "expected 1, got %d\n", data.Height);
ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
ok(data.PixelFormat == PixelFormat32bppARGB, "expected PixelFormat32bppARGB, got %d\n", data.PixelFormat);
match = !memcmp(data.Scan0, cleared, sizeof(cleared));
ok(match, "bits don't match\n");
if (!match)
{
bits = data.Scan0;
trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB,
bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
}
status = GdipBitmapUnlockBits(bitmap, &data);
expect(Ok, status);
status = GdipDeleteGraphics(graphics);
expect(Ok, status);
GdipDisposeImage((GpImage *)bitmap);
}
START_TEST(image)
{
HMODULE mod = GetModuleHandleA("gdiplus.dll");
@ -5559,6 +5601,7 @@ START_TEST(image)
test_histogram();
test_imageabort();
test_GdipLoadImageFromStream();
test_graphics_clear();
GdiplusShutdown(gdiplusToken);
}