From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/gdiplus/region.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index d0d911d2721..d63f679c70d 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -2321,9 +2321,27 @@ static GpStatus rect_to_spans(const RECT *rc, struct span_list *spans) return Ok; } +static BOOL bounds_intersect_region_element_rect(RECT *bounds, const struct region_element *element) +{ + if (element->type == RegionDataInfiniteRect) + return TRUE; + + if (element->type == RegionDataRect) + { + RECT rc; + + rect_round_from_gp_rect_f(&rc, &element->elementdata.rect); + IntersectRect(bounds, bounds, &rc); + return TRUE; + } + + return FALSE; +} + static GpStatus combine_regions_to_spans(const struct region_element *left, const struct region_element *right, - DWORD type, const RECT *bounds, struct span_list *spans) + DWORD type, const RECT *bound_rect, struct span_list *spans) { + RECT bounds = *bound_rect; struct span_list spans_left = {0}, spans_right = {0}; size_t i_left = 0, i_right = 0; const struct span *cur_left, *cur_right; @@ -2331,17 +2349,27 @@ static GpStatus combine_regions_to_spans(const struct region_element *left, cons int x, y, x1_left, x1_right, x1_min; GpStatus stat; - stat = region_element_to_spans(left, bounds, &spans_left); + if (type == CombineModeIntersect) + { + /* In intersect mode, where one side is a rect, it is sufficient to intersect + * it with the bounds and convert the other side to spans */ + if (bounds_intersect_region_element_rect(&bounds, left)) + return region_element_to_spans(right, &bounds, spans); + if (bounds_intersect_region_element_rect(&bounds, right)) + return region_element_to_spans(left, &bounds, spans); + } + + stat = region_element_to_spans(left, &bounds, &spans_left); if (stat == Ok) - stat = region_element_to_spans(right, bounds, &spans_right); + stat = region_element_to_spans(right, &bounds, &spans_right); cur_left = spans_left.length ? &spans_left.spans[0] : NULL; cur_right = spans_right.length ? &spans_right.spans[0] : NULL; - for (y = bounds->top; stat == Ok && y < bounds->bottom; ++y) + for (y = bounds.top; stat == Ok && y < bounds.bottom; ++y) { - for (x = bounds->left; stat == Ok && x < bounds->right; ) + for (x = bounds.left; stat == Ok && x < bounds.right; ) { /* Update the current left and right spans */ @@ -2366,7 +2394,7 @@ static GpStatus combine_regions_to_spans(const struct region_element *left, cons else { in_left = FALSE; - x1_left = bounds->right; + x1_left = bounds.right; } if (cur_right && y == cur_right->y) @@ -2377,7 +2405,7 @@ static GpStatus combine_regions_to_spans(const struct region_element *left, cons else { in_right = FALSE; - x1_right = bounds->right; + x1_right = bounds.right; } x1_min = min(x1_left, x1_right); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10359