[PATCH 0/2] MR6685: win32u: Fixes for arc drawing.
From: Elizabeth Figura <zfigura(a)codeweavers.com> The eventual array will only need 1/2 of the points, but we need the whole max_points to generate the ellipse top half. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57306 --- dlls/win32u/dibdrv/graphics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/win32u/dibdrv/graphics.c b/dlls/win32u/dibdrv/graphics.c index 414737fa8ca..197e91a7f5d 100644 --- a/dlls/win32u/dibdrv/graphics.c +++ b/dlls/win32u/dibdrv/graphics.c @@ -1529,7 +1529,7 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom, * is exactly as many as in one ellipse arc. */ max_points = get_arc_max_points( dc, &rect ); points = malloc( max_points * sizeof(*points) ); - top_points = malloc( max_points / 2 * sizeof(*points) ); + top_points = malloc( max_points * sizeof(*points) ); if (!points || !top_points) { free( points ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6685
From: Elizabeth Figura <zfigura(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57296 --- dlls/win32u/dibdrv/graphics.c | 45 ++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/dlls/win32u/dibdrv/graphics.c b/dlls/win32u/dibdrv/graphics.c index 197e91a7f5d..cc62d6a681b 100644 --- a/dlls/win32u/dibdrv/graphics.c +++ b/dlls/win32u/dibdrv/graphics.c @@ -217,7 +217,7 @@ static unsigned int generate_ellipse_top_half( const DC *dc, double width, doubl double dy = -(a * pt.x + b * pt.y); int x_inc = (dx > 0 ? 1 : -1); int y_inc = (dy > 0 ? 1 : -1); - double sigma; + double sigma1, sigma2; points[pos++] = pt; @@ -226,29 +226,42 @@ static unsigned int generate_ellipse_top_half( const DC *dc, double width, doubl /* Increment y, maybe increment x. */ pt.y += y_inc; - sigma = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; - /* σ < 0 if the next point would be inside the ellipse. - * If we are moving towards a vertical or horizontal tangent point, - * and (x, y+1) is outside the ellipse, then it's certainly - * closer to the ellipse than (x-1, y+1). [Same for the 180° - * rotation.] Hence we want to increment x if σ < 0. - * If we are moving away from a tangent point, the opposite applies, - * and we want to increment x if σ > 0. - * We are moving towards a tangent point if (dx > 0 XOR dy > 0), - * so want to increment x if (dx > 0 XOR dy > 0 XOR σ > 0). */ - if (sigma != 0.0 && (dx > 0) ^ (dy > 0) ^ (sigma > 0)) + /* If this point has 45° slope, and it's directly adjacent to one + * we just wrote, using the algorithm as-is will select this point + * and then the one horizontally adjacent to it (our reflection + * across the 45° line.) This creates an L-shaped corner, which we + * don't want. Force incrementing X to skip that corner. */ + if (fabs(b * pt.x + c * pt.y) == fabs(a * pt.x + b * pt.y)) + { pt.x += x_inc; + continue; + } + + sigma1 = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; + pt.x += x_inc; + sigma2 = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; + + /* Pick whichever point is closer to the ellipse. */ + if (fabs(sigma2) > fabs(sigma1)) + pt.x -= x_inc; } else { /* Increment x, maybe increment y. */ pt.x += x_inc; - sigma = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; - /* As above, but we are moving towards a tangent point if the - * opposite condition is true, i.e. (dx < 0 XOR dy > 0). */ - if (sigma != 0.0 && (dx < 0) ^ (dy > 0) ^ (sigma > 0)) + if (fabs(b * pt.x + c * pt.y) == fabs(a * pt.x + b * pt.y)) + { pt.y += y_inc; + continue; + } + + sigma1 = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; + pt.y += y_inc; + sigma2 = (a * pt.x * pt.x) + (2 * b * pt.x * pt.y) + (c * pt.y * pt.y) - d; + + if (fabs(sigma2) > fabs(sigma1)) + pt.y -= y_inc; } } return pos; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6685
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149049 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/win32u/dibdrv/graphics.c:217 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/win32u/dibdrv/graphics.c:217 Task: Patch failed to apply
This merge request was approved by Huw Davies. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6685
participants (4)
-
Elizabeth Figura -
Elizabeth Figura (@zfigura) -
Huw Davies (@huw) -
Marvin