https://bugs.winehq.org/show_bug.cgi?id=30506
--- Comment #10 from Damjan Jovanovic damjan.jov@gmail.com --- Pyglet code, font/win32.py, class GDIPlusGlyphRenderer, method render(), is called multiple times, once for each letter.
The section entitled: # Draw character to bitmap calls GdipGraphicsClear() to clear the region to draw on, then GdipDrawString() to render the character in the given font, then locks the bitmap and extracts the pixels.
What we observe if we dump bitmaps in between those steps, is that the first character is drawn correctly. With "Hello world!", the "H" comes out right. But then the next character, "e", begins with the bitmap containing a portion of the "H", and draws on top of the "H", resulting in a corrupted glyph. The "l" draws on top of both "H" and "e".
The problem seems to be the call to GdipGraphicsClear(). It is called as follows: gdiplus.GdipGraphicsClear(self._graphics, 0x00000000)
The 0x00000000 is A R G B fully transparent black.
1. GdipGraphicsClear() creates a solid fill brush with that color and calls GdipFillRectangle() 2. which calls GdipFillRectangles() 3. which adds the rectangle to a path and calls GdipFillPath() 4. which, since there is alpha, calls SOFTWARE_GdipFillPath() 5. which calls GdipFillPath() 6. which calls SOFTWARE_GdipFillPath() 7. which calls GdipFillRegion() 8. which calls SOFTWARE_GdipFillRegion() 9. which creates a memory block, and calls brush_fill_pixels() to fill it with the brush, then calls alpha_blend_pixels_hrgn() to mix it into the background 10. which calls alpha_blend_bmp_pixels() 11. which does nothing as the color is 0x00000000 and:
if (!(src_color & 0xff000000)) continue;
Even if we commented that out, further on, color_over_fgpremult() would ignore the 0x00000000 as it is fully transparent, leaving the background unmodified.
So it seems GdipGraphicsClear() needs to overwrite pixels unconditionally, not alpha blend them into the background.