decorations: improve spinner rendering

Fixes #9032

This commit improves spinner rendering by:
    - Removing the constant 1px reduction to the spinner radius
      introduced by 2f983c1. This caused the spinner radius to be too
      small at higher line widths.
    - Always considering half the line width to be at or above 0.5
      pixels since visually the line cannot actually be rendered at a
      width below 1 pixel. This allows for more consistent behavior at
      different line widths and resolutions.
    - Accounting for the line width when setting up the 'ClipRect'.
      Before, the top and bottom of a spinner would get cut off at high
      line widths.
This commit is contained in:
alex-huff 2025-09-29 10:03:16 -05:00
parent 13e3ecad5c
commit 8abdff10f7

View file

@ -837,9 +837,10 @@ static void
spinner(Canvas *self, uint level, double start_degrees, double end_degrees) {
double x = self->width / 2.0, y = self->height / 2.0;
double line_width = thickness_as_float(self, level, true);
double radius = fmax(0, fmin(x, y) - 1 - line_width / 2.0);
double half_real_line_width = fmax(0.5, line_width / 2.0);
double radius = fmax(0, fmin(x, y) - half_real_line_width);
Circle c = circle(x, y, radius, start_degrees, end_degrees);
uint leftover = minus(self->height, 2*(uint)ceil(radius) + 1) / 2;
uint leftover = minus(self->height, 2*(uint)(ceil(radius) + half_real_line_width) + 1) / 2;
ClipRect cr = {.top=leftover, .y_end=self->height - leftover, .x_end=self->width};
draw_parametrized_curve_with_derivative_and_antialiasing(
self, &c, line_width, circle_x, circle_y, circle_prime_x, circle_prime_y, 0, 0, &cr);