From: Conor McCarthy <cmccarthy@codeweavers.com> This make it relatively simple to add an alternative to alpha_blend_pixels_hrgn() for bitmap rendering. --- dlls/gdiplus/graphics.c | 73 +++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 2419eea94db..4ceaea2757e 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -4795,7 +4795,7 @@ GpStatus WINGDIPAPI GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush, GD return ret; } -static GpStatus get_clipped_region_hrgn(GpGraphics* graphics, GpRegion* region, HRGN *hrgn) +static GpStatus get_clipped_device_region(GpGraphics* graphics, GpRegion* region, GpRegion** clipped_region) { GpStatus status; GpRegion *tmp_region, *device_region; @@ -4860,7 +4860,24 @@ static GpStatus get_clipped_region_hrgn(GpGraphics* graphics, GpRegion* region, } if (status == Ok) - status = GdipGetRegionHRgn(device_region, NULL, hrgn); + *clipped_region = device_region; + else + GdipDeleteRegion(device_region); + } + + return status; +} + +static GpStatus get_clipped_region_hrgn(GpGraphics* graphics, GpRegion* region, HRGN *hrgn) +{ + GpStatus status; + GpRegion *device_region; + + status = get_clipped_device_region(graphics, region, &device_region); + + if (status == Ok) + { + status = GdipGetRegionHRgn(device_region, NULL, hrgn); GdipDeleteRegion(device_region); } @@ -4922,7 +4939,7 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, GpStatus stat; DWORD *pixel_data; HRGN hregion; - RECT bound_rect; + GpRegion* device_region = NULL; GpRect gp_bound_rect; if (!brush_can_fill_pixels(brush)) @@ -4931,22 +4948,49 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, stat = gdi_transform_acquire(graphics); if (stat == Ok) - stat = get_clipped_region_hrgn(graphics, region, &hregion); - - if (stat == Ok && GetRgnBox(hregion, &bound_rect) == NULLREGION) { - DeleteObject(hregion); - gdi_transform_release(graphics); - return Ok; + if (graphics->image && graphics->image->type == ImageTypeBitmap) + { + stat = get_clipped_device_region(graphics, region, &device_region); + + if (stat == Ok) + stat = GdipGetRegionBoundsI(device_region, graphics, &gp_bound_rect); + + if (stat == Ok && gp_bound_rect.Width == 0 && gp_bound_rect.Height == 0) + { + GdipDeleteRegion(device_region); + gdi_transform_release(graphics); + return Ok; + } + + if (stat == Ok) + stat = GdipGetRegionHRgn(device_region, NULL, &hregion); + } + else + { + RECT bound_rect; + + stat = get_clipped_region_hrgn(graphics, region, &hregion); + + if (stat == Ok && GetRgnBox(hregion, &bound_rect) == NULLREGION) + { + DeleteObject(hregion); + gdi_transform_release(graphics); + return Ok; + } + + if (stat == Ok) + { + gp_bound_rect.X = bound_rect.left; + gp_bound_rect.Y = bound_rect.top; + gp_bound_rect.Width = bound_rect.right - bound_rect.left; + gp_bound_rect.Height = bound_rect.bottom - bound_rect.top; + } + } } if (stat == Ok) { - gp_bound_rect.X = bound_rect.left; - gp_bound_rect.Y = bound_rect.top; - gp_bound_rect.Width = bound_rect.right - bound_rect.left; - gp_bound_rect.Height = bound_rect.bottom - bound_rect.top; - pixel_data = calloc(gp_bound_rect.Width * gp_bound_rect.Height, sizeof(*pixel_data)); if (!pixel_data) stat = OutOfMemory; @@ -4968,6 +5012,7 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush, DeleteObject(hregion); } + GdipDeleteRegion(device_region); gdi_transform_release(graphics); return stat; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10359