From 75e785e01e06e69d534da275e4173dc01182ed4a Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 6 Feb 2022 08:20:56 -0700 Subject: [PATCH] allow using CSS style color specs in the config This change also allows removing the dep on the palette crate, which I found to be difficult to use (API changed often, and relied on a lot of `.into` that was hard to follow and reconcile across upgrades). We already pulled in the csscolorparse crate as an indirect dep of colorgrad, so we can replace the color conversion we need for sixel with that crate while we're in here. refs: #1615 --- Cargo.lock | 37 ++------------------------------- color-types/Cargo.toml | 1 + color-types/src/lib.rs | 18 ++++++++++++++++ docs/config/appearance.md | 35 +++++++++++++++++++++++-------- term/Cargo.toml | 2 +- term/src/terminalstate/sixel.rs | 19 ++++++++--------- wezterm-gui/Cargo.toml | 1 - 7 files changed, 57 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b3ef7a84..c534e0c77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,15 +67,6 @@ version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" -[[package]] -name = "approx" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -dependencies = [ - "num-traits", -] - [[package]] name = "arrayref" version = "0.3.6" @@ -2709,30 +2700,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "palette" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a05c0334468e62a4dfbda34b29110aa7d70d58c7fdb2c9857b5874dd9827cc59" -dependencies = [ - "approx", - "num-traits", - "palette_derive", - "phf", - "phf_codegen", -] - -[[package]] -name = "palette_derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b4b5f600e60dd3a147fb57b4547033d382d1979eb087af310e91cb45a63b1f4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "parking" version = "2.0.0" @@ -4700,6 +4667,7 @@ dependencies = [ name = "wezterm-color-types" version = "0.1.0" dependencies = [ + "csscolorparser", "lazy_static", "serde", ] @@ -4774,7 +4742,6 @@ dependencies = [ "mux", "open", "ordered-float", - "palette", "portable-pty", "pretty_env_logger", "promise", @@ -4918,6 +4885,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bitflags", + "csscolorparser", "hex", "image", "k9", @@ -4927,7 +4895,6 @@ dependencies = [ "miniz_oxide 0.4.4", "num-traits", "ordered-float", - "palette", "pretty_assertions", "pretty_env_logger", "serde", diff --git a/color-types/Cargo.toml b/color-types/Cargo.toml index 8777bb115..5e081f46a 100644 --- a/color-types/Cargo.toml +++ b/color-types/Cargo.toml @@ -11,5 +11,6 @@ license = "MIT" use_serde = ["serde"] [dependencies] +csscolorparser = "0.5" lazy_static = "1.4" serde = {version="1.0", features = ["derive"], optional=true} diff --git a/color-types/src/lib.rs b/color-types/src/lib.rs index eed16e803..c0b8799a8 100644 --- a/color-types/src/lib.rs +++ b/color-types/src/lib.rs @@ -473,6 +473,8 @@ impl FromStr for SrgbaTuple { } else { Err(()) } + } else if let Ok(c) = csscolorparser::parse(s) { + Ok(Self(c.r as f32, c.g as f32, c.b as f32, c.a as f32)) } else { Self::from_named(s).ok_or(()) } @@ -572,6 +574,22 @@ mod tests { ); } + #[test] + fn from_css() { + assert_eq!( + SrgbaTuple::from_str("rgb(255,0,0)") + .unwrap() + .to_rgb_string(), + "#ff0000" + ); + assert_eq!( + SrgbaTuple::from_str("rgba(255,0,0,1)") + .unwrap() + .to_rgba_string(), + "rgba:255 0 0 100%" + ); + } + #[test] fn from_rgb() { assert!(SrgbaTuple::from_str("").is_err()); diff --git a/docs/config/appearance.md b/docs/config/appearance.md index 56f282d40..398864f74 100644 --- a/docs/config/appearance.md +++ b/docs/config/appearance.md @@ -90,7 +90,30 @@ return { *Since: nightly builds only* -`selection_fg` and `selection_bg` may set the alpha channel value. +Colors now also accept the following CSS-style color specifications: + +``` +#00ff00ff +rgb(0,255,0) +rgb(0% 100% 0%) +rgb(0 255 0 / 100%) +rgba(0,255,0,1) +hsl(120,100%,50%) +hsl(120deg 100% 50%) +hsl(-240 100% 50%) +hsl(-240deg 100% 50%) +hsl(0.3333turn 100% 50%) +hsl(133.333grad 100% 50%) +hsl(2.0944rad 100% 50%) +hsla(120,100%,50%,100%) +hwb(120 0% 0%) +hwb(480deg 0% 0% / 100%) +hsv(120,100%,100%) +hsv(120deg 100% 100% / 100%) +``` + +The alpha value is ignored except when used with `selection_fg` and +`selection_bg`: ```lua return { @@ -98,16 +121,10 @@ return { -- Make the selection text color fully transparent. -- When fully transparent, the current text color will be used. selection_fg = "none", - -- Set the selection background color with alpha; - -- The first number is the red channel, set here to 50%. - -- If the number doesn't end with a % then it must be in the range - -- 0 through 255. - -- The second number is the green channel. - -- The third number is the blue channel. - -- The last number is the alpha channel. + -- Set the selection background color with alpha. -- When selection_bg is transparent, it will be alpha blended over -- the current cell background color, rather than replace it - selection_bg = "rgba:50% 50% 50% 50%" + selection_bg = "rgba(50% 50% 50% 50%)" } } ``` diff --git a/term/Cargo.toml b/term/Cargo.toml index 82c755f39..64233ca07 100644 --- a/term/Cargo.toml +++ b/term/Cargo.toml @@ -16,6 +16,7 @@ use_serde = ["termwiz/use_serde", "wezterm-bidi/use_serde"] [dependencies] anyhow = "1.0" bitflags = "1.3" +csscolorparser = "0.5" miniz_oxide = "0.4" hex = "0.4" image = "0.23" @@ -24,7 +25,6 @@ log = "0.4" lru = "0.7" num-traits = "0.2" ordered-float = "2.10" -palette = "0.5" serde = {version="1.0", features = ["rc"]} terminfo = "0.7" unicode-segmentation = "1.8" diff --git a/term/src/terminalstate/sixel.rs b/term/src/terminalstate/sixel.rs index 9e2c7c12e..3ec35abbf 100644 --- a/term/src/terminalstate/sixel.rs +++ b/term/src/terminalstate/sixel.rs @@ -81,22 +81,21 @@ impl TerminalState { saturation, lightness, } => { - use palette::encoding::pixel::Pixel; // Sixel's hue angles are: blue=0, red=120, green=240, // whereas Hsl has red=0, green=120, blue=240. // Looking at red, we need to rotate left by 120 to - // go from sixel red to palette::RgbHue red. + // go from sixel red to standard hsl red. // Negative values wrap around the circle. // https://github.com/wez/wezterm/issues/775 - let angle = (*hue_angle as f32) - 120.0; + let angle = (*hue_angle as f64) - 120.0; let angle = if angle < 0. { 360.0 + angle } else { angle }; - let hue = palette::RgbHue::from_degrees(angle); - let hsl = - palette::Hsl::new(hue, *saturation as f32 / 100., *lightness as f32 / 100.); - let rgb: palette::Srgb = hsl.into(); - let rgb: [u8; 3] = rgb.into_linear().into_format().into_raw(); - - color_map.insert(*color_number, RgbColor::new_8bpc(rgb[0], rgb[1], rgb[2])); + let c = csscolorparser::Color::from_hsl( + angle, + *saturation as f64 / 100., + *lightness as f64 / 100., + ); + let (r, g, b, _) = c.rgba_u8(); + color_map.insert(*color_number, RgbColor::new_8bpc(r, g, b)); } SixelData::SelectColorMapEntry(n) => { diff --git a/wezterm-gui/Cargo.toml b/wezterm-gui/Cargo.toml index 2687368fa..e3611b8f4 100644 --- a/wezterm-gui/Cargo.toml +++ b/wezterm-gui/Cargo.toml @@ -47,7 +47,6 @@ mlua = "0.7" mux = { path = "../mux" } open = "2.0" ordered-float = "2.10" -palette = "0.5" portable-pty = { path = "../pty", features = ["serde_support", "ssh"]} promise = { path = "../promise" } pulldown-cmark = "0.9"