Skip to repository content77 lines · 2.3 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T02:59:04.844Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
color_space.rs
1//! Conversions between gpui's [`Hsla`] and the OKLab / OKLCh perceptual color
2//! spaces, backed by the `palette` crate.
3//!
4//! These are exposed so consumers can reason about perceptual color distance
5//! (e.g. bracket colorization) without taking a direct dependency on `palette`.
6
7use gpui::{Hsla, Rgba};
8use palette::{
9 FromColor, OklabHue,
10 rgb::{LinSrgba, Srgba},
11};
12
13/// A color in the OKLab perceptual color space.
14#[derive(Clone, Copy, Debug, PartialEq)]
15pub struct Oklab {
16 /// Perceptual lightness, in `0.0..=1.0`.
17 pub l: f32,
18 /// Green/red opponent axis.
19 pub a: f32,
20 /// Blue/yellow opponent axis.
21 pub b: f32,
22}
23
24/// A color in the OKLCh perceptual color space (the cylindrical form of OKLab).
25#[derive(Clone, Copy, Debug, PartialEq)]
26pub struct Oklch {
27 /// Perceptual lightness, in `0.0..=1.0`.
28 pub l: f32,
29 /// Chroma (colorfulness).
30 pub chroma: f32,
31 /// Hue, in degrees (`0.0..360.0`).
32 pub hue: f32,
33}
34
35/// Converts an [`Hsla`] color into the OKLab color space.
36pub fn hsla_to_oklab(color: Hsla) -> Oklab {
37 let oklab = palette::Oklab::from_color(hsla_to_linear(color));
38 Oklab {
39 l: oklab.l,
40 a: oklab.a,
41 b: oklab.b,
42 }
43}
44
45/// Converts an [`Hsla`] color into the OKLCh color space.
46pub fn hsla_to_oklch(color: Hsla) -> Oklch {
47 let oklch = palette::Oklch::from_color(hsla_to_linear(color));
48 Oklch {
49 l: oklch.l,
50 chroma: oklch.chroma,
51 hue: oklch.hue.into_positive_degrees(),
52 }
53}
54
55/// Converts an [`Oklch`] color back into [`Hsla`], using `alpha` for the
56/// resulting alpha channel. Channels outside the sRGB gamut are clamped.
57pub fn oklch_to_hsla(color: Oklch, alpha: f32) -> Hsla {
58 let oklch = palette::Oklch {
59 l: color.l,
60 chroma: color.chroma,
61 hue: OklabHue::from_degrees(color.hue),
62 };
63 let rgba: Srgba = Srgba::from_linear(LinSrgba::from_color(oklch));
64 let (red, green, blue, _) = rgba.into_components();
65 Hsla::from(Rgba {
66 r: red.clamp(0.0, 1.0),
67 g: green.clamp(0.0, 1.0),
68 b: blue.clamp(0.0, 1.0),
69 a: alpha,
70 })
71}
72
73fn hsla_to_linear(color: Hsla) -> LinSrgba {
74 let rgba = Rgba::from(color);
75 Srgba::new(rgba.r, rgba.g, rgba.b, rgba.a).into_linear()
76}
77