Fix `paint_quad` behavior change which clamped corner rounding (#27472)

Michael Sloan created

Turns out that git deletion indicator relied on using larger-than-bounds
corner rounding - see
https://github.com/zed-industries/zed/pull/27460#issuecomment-2753174153

Release Notes:

- N/A

Change summary

crates/gpui/src/elements/img.rs |  6 ++++--
crates/gpui/src/style.rs        | 13 ++++++-------
crates/gpui/src/window.rs       | 14 ++++++--------
3 files changed, 16 insertions(+), 17 deletions(-)

Detailed changes

crates/gpui/src/elements/img.rs 🔗

@@ -421,8 +421,10 @@ impl Element for Img {
             window,
             cx,
             |style, window, cx| {
-                let corner_radii = style.corner_radii.to_pixels(window.rem_size());
-
+                let corner_radii = style
+                    .corner_radii
+                    .to_pixels(window.rem_size())
+                    .clamp_radii_for_quad_size(bounds.size);
                 if let Some(Ok(data)) = source.use_data(window, cx) {
                     let new_bounds = self
                         .style

crates/gpui/src/style.rs 🔗

@@ -609,12 +609,12 @@ impl Style {
         }
 
         let rem_size = window.rem_size();
+        let corner_radii = self
+            .corner_radii
+            .to_pixels(rem_size)
+            .clamp_radii_for_quad_size(bounds.size);
 
-        window.paint_shadows(
-            bounds,
-            self.corner_radii.to_pixels(rem_size),
-            &self.box_shadow,
-        );
+        window.paint_shadows(bounds, corner_radii, &self.box_shadow);
 
         let background_color = self.background.as_ref().and_then(Fill::color);
         if background_color.map_or(false, |color| !color.is_transparent()) {
@@ -633,7 +633,7 @@ impl Style {
             border_color.a = 0.;
             window.paint_quad(quad(
                 bounds,
-                self.corner_radii.to_pixels(rem_size),
+                corner_radii,
                 background_color.unwrap_or_default(),
                 Edges::default(),
                 border_color,
@@ -644,7 +644,6 @@ impl Style {
         continuation(window, cx);
 
         if self.is_border_visible() {
-            let corner_radii = self.corner_radii.to_pixels(rem_size);
             let border_widths = self.border_widths.to_pixels(rem_size);
             let max_border_width = border_widths.max();
             let max_corner_radius = corner_radii.max();

crates/gpui/src/window.rs 🔗

@@ -2327,25 +2327,23 @@ impl Window {
     /// see [`fill`](crate::fill), [`outline`](crate::outline), and [`quad`](crate::quad) to construct this type.
     ///
     /// This method should only be called as part of the paint phase of element drawing.
+    ///
+    /// Note that the `quad.corner_radii` are allowed to exceed the bounds, creating sharp corners
+    /// where the circular arcs meet. This will not display well when combined with dashed borders.
+    /// Use `Corners::clamp_radii_for_quad_size` if the radii should fit within the bounds.
     pub fn paint_quad(&mut self, quad: PaintQuad) {
         self.invalidator.debug_assert_paint();
 
         let scale_factor = self.scale_factor();
         let content_mask = self.content_mask();
         let opacity = self.element_opacity();
-
-        let bounds = quad.bounds.scale(scale_factor);
-        let corner_radii = quad
-            .corner_radii
-            .scale(scale_factor)
-            .clamp_radii_for_quad_size(bounds.size);
         self.next_frame.scene.insert_primitive(Quad {
             order: 0,
-            bounds,
+            bounds: quad.bounds.scale(scale_factor),
             content_mask: content_mask.scale(scale_factor),
             background: quad.background.opacity(opacity),
             border_color: quad.border_color.opacity(opacity),
-            corner_radii,
+            corner_radii: quad.corner_radii.scale(scale_factor),
             border_widths: quad.border_widths.scale(scale_factor),
             border_style: quad.border_style,
         });