Fix incorrect ANSI color contrast adjustment on some background colors (#38155)

Tim Vermeulen created

The `Hsla` -> `Rgba` conversion sometimes results in negative (but very
close to 0) color components due to floating point imprecision, causing
the `.powf(constants.main_trc)` computations in the `srgb_to_y` function
to evaluate to `NaN`. This propagates to `apca_contrast` which then
makes `ensure_minimum_contrast` unconditionally return `black` for
certain background colors. This PR addresses this by clamping the rgba
components in `impl From<Hsla> for Rgba` to 0-1.

Before/after:
<img width="1044" height="48" alt="before"
src="https://github.com/user-attachments/assets/771f809f-3959-43e9-8ed0-152ff284cef8"
/>
<img width="1044" height="49" alt="after"
src="https://github.com/user-attachments/assets/5fd6ae25-1ef0-4334-90d1-7fc5acf48958"
/>

Release Notes:

- Fixed an issue where ANSI colors were incorrectly adjusted to improve
contrast on some background colors

Change summary

crates/gpui/src/color.rs             | 6 +++---
crates/ui/src/utils/apca_contrast.rs | 7 +++++++
2 files changed, 10 insertions(+), 3 deletions(-)

Detailed changes

crates/gpui/src/color.rs 🔗

@@ -151,9 +151,9 @@ impl From<Hsla> for Rgba {
         };
 
         Rgba {
-            r,
-            g,
-            b,
+            r: r.clamp(0., 1.),
+            g: g.clamp(0., 1.),
+            b: b.clamp(0., 1.),
             a: color.a,
         }
     }

crates/ui/src/utils/apca_contrast.rs 🔗

@@ -393,6 +393,13 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_srgb_to_y_nan_issue() {
+        let dark_red = hsla_from_hex(0x5f0000);
+        let y_dark_red = srgb_to_y(dark_red, &APCAConstants::default());
+        assert!(!y_dark_red.is_nan());
+    }
+
     #[test]
     fn test_ensure_minimum_contrast() {
         let white_bg = hsla(0.0, 0.0, 1.0, 1.0);