gpui: Fix partial dashed border rendering (#38190)

Francisco Gonzalez created

Closes #38189 

- Fixed border dashed for diverse scenarios, as demonstrated in the
images below.
- This change has no impact on the rendering of solid borders, as it was
implemented inside an if block for dashed styles

Release Notes:
  - N/A

## Before Images
<details><summary>click to expand (small top border, medium right
border, large bottom border)</summary>
<img width="289" height="95" alt="Screenshot From 2025-09-15 13-28-14"
src="https://github.com/user-attachments/assets/5226cd0a-49c2-43b8-9df9-f64390e3759e"
/>
</details>
<details><summary> click to expand (Same size pairs of borders)
</summary>
<img width="289" height="95" alt="Screenshot From 2025-09-15 13-32-22"
src="https://github.com/user-attachments/assets/603e7b49-e8b1-45a4-ac35-1b3aedf52bca"
/>
<img width="289" height="95" alt="Screenshot From 2025-09-15 13-33-24"
src="https://github.com/user-attachments/assets/4243786c-4c9d-4419-91d6-4594b5ee4390"
/>
</details>

## After Images

<details><summary>click to expand (small top border, medium right
border, large bottom border)</summary>

<img width="289" height="95" alt="Screenshot From 2025-09-15 13-17-28"
src="https://github.com/user-attachments/assets/e2652b38-1c24-432e-b7fd-c6f4d4c71de6"
/>

</details>


<details><summary> click to expand (same size pairs of
borders)</summary>
<img width="289" height="95" alt="Screenshot From 2025-09-15 13-37-59"
src="https://github.com/user-attachments/assets/05228431-4a91-4531-adcd-d70acd2c3b44"
/>

<img width="289" height="95" alt="Screenshot From 2025-09-15 13-36-34"
src="https://github.com/user-attachments/assets/6da946b8-1ccd-4ed1-9b38-539eba4edf42"
/>
</details>

Change summary

crates/gpui/src/platform/blade/shaders.wgsl   | 19 ++++++++++++++++++-
crates/gpui/src/platform/mac/shaders.metal    | 10 +++++++++-
crates/gpui/src/platform/windows/shaders.hlsl |  9 ++++++++-
3 files changed, 35 insertions(+), 3 deletions(-)

Detailed changes

crates/gpui/src/platform/blade/shaders.wgsl 🔗

@@ -683,7 +683,24 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4<f32> {
                 let is_horizontal =
                         corner_center_to_point.x <
                         corner_center_to_point.y;
-                let border_width = select(border.y, border.x, is_horizontal);
+
+                // When applying dashed borders to just some, not all, the sides.
+                // The way we chose border widths above sometimes comes with a 0 width value.
+                // So we choose again to avoid division by zero.
+                // TODO: A better solution exists taking a look at the whole file.
+                // this does not fix single dashed borders at the corners
+                let dashed_border = vec2<f32>(
+                        max(
+                            quad.border_widths.bottom,
+                            quad.border_widths.top,
+                        ),
+                        max(
+                            quad.border_widths.right,
+                            quad.border_widths.left,
+                        )
+                   );
+
+                let border_width = select(dashed_border.y, dashed_border.x, is_horizontal);
                 dash_velocity = dv_numerator / border_width;
                 t = select(point.y, point.x, is_horizontal) * dash_velocity;
                 max_t = select(size.y, size.x, is_horizontal) * dash_velocity;

crates/gpui/src/platform/mac/shaders.metal 🔗

@@ -245,7 +245,15 @@ fragment float4 quad_fragment(QuadFragmentInput input [[stage_in]],
         // out on each straight line, rather than around the whole
         // perimeter. This way each line starts and ends with a dash.
         bool is_horizontal = corner_center_to_point.x < corner_center_to_point.y;
-        float border_width = is_horizontal ? border.x : border.y;
+
+        // Choosing the right border width for dashed borders.
+        // TODO: A better solution exists taking a look at the whole file.
+        // this does not fix single dashed borders at the corners
+        float2 dashed_border = float2(
+        fmax(quad.border_widths.bottom, quad.border_widths.top),
+        fmax(quad.border_widths.right, quad.border_widths.left));
+
+        float border_width = is_horizontal ? dashed_border.x : dashed_border.y;
         dash_velocity = dv_numerator / border_width;
         t = is_horizontal ? point.x : point.y;
         t *= dash_velocity;

crates/gpui/src/platform/windows/shaders.hlsl 🔗

@@ -660,7 +660,14 @@ float4 quad_fragment(QuadFragmentInput input): SV_Target {
                 // out on each straight line, rather than around the whole
                 // perimeter. This way each line starts and ends with a dash.
                 bool is_horizontal = corner_center_to_point.x < corner_center_to_point.y;
-                float border_width = is_horizontal ? border.x : border.y;
+                // Choosing the right border width for dashed borders.
+                // TODO: A better solution exists taking a look at the whole file.
+                // this does not fix single dashed borders at the corners
+                float2 dashed_border = float2(
+                    max(quad.border_widths.bottom, quad.border_widths.top),
+                    max(quad.border_widths.right, quad.border_widths.left)
+                );
+                float border_width = is_horizontal ? dashed_border.x : dashed_border.y;
                 dash_velocity = dv_numerator / border_width;
                 t = is_horizontal ? the_point.x : the_point.y;
                 t *= dash_velocity;