From e85258a212aa41237abc19a7051656e80321b07f Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 31 May 2022 08:47:28 -0700 Subject: [PATCH] background: allow specifying a solid color layer The color can have alpha and blend with other layers. This is helpful if your image has fully transparent portions and you want to explicitly place a color in there. --- color-types/src/lib.rs | 9 +++++++ config/src/background.rs | 3 ++- wezterm-gui/src/termwindow/background.rs | 33 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/color-types/src/lib.rs b/color-types/src/lib.rs index 91562f1cd..cfafe63f8 100644 --- a/color-types/src/lib.rs +++ b/color-types/src/lib.rs @@ -295,6 +295,15 @@ impl SrgbaTuple { ) } + pub fn to_srgb_u8(self) -> (u8, u8, u8, u8) { + ( + (self.0 * 255.) as u8, + (self.1 * 255.) as u8, + (self.2 * 255.) as u8, + (self.3 * 255.) as u8, + ) + } + /// Returns a string of the form `#RRGGBB` pub fn to_rgb_string(self) -> String { format!( diff --git a/config/src/background.rs b/config/src/background.rs index 3dad7e5c3..44a9b6fa8 100644 --- a/config/src/background.rs +++ b/config/src/background.rs @@ -1,4 +1,4 @@ -use crate::{default_one_point_oh, Config, HsbTransform}; +use crate::{default_one_point_oh, Config, HsbTransform, RgbaColor}; use luahelper::impl_lua_conversion_dynamic; use wezterm_dynamic::{FromDynamic, FromDynamicOptions, ToDynamic, Value}; @@ -48,6 +48,7 @@ impl FromDynamic for ImageFileSourceWrap { pub enum BackgroundSource { Gradient(Gradient), File(ImageFileSourceWrap), + Color(RgbaColor), } #[derive(Debug, Clone, FromDynamic, ToDynamic)] diff --git a/wezterm-gui/src/termwindow/background.rs b/wezterm-gui/src/termwindow/background.rs index aa7d8d26c..50dce5878 100644 --- a/wezterm-gui/src/termwindow/background.rs +++ b/wezterm-gui/src/termwindow/background.rs @@ -207,6 +207,39 @@ fn load_background_layer( width, height, data, ))) } + BackgroundSource::Color(color) => { + // In theory we could just make a 1x1 texture and allow + // the shader to stretch it, but if we do that, it'll blend + // around the edges and look weird. + // So we make a square texture in the ballpark of the window + // surface. + // It's not ideal. + let width = match layer.width { + BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_width as u32) / 100, + BackgroundSize::Length(u) => u as u32, + unsup => anyhow::bail!("{:?} not yet implemented", unsup), + }; + let height = match layer.height { + BackgroundSize::Percent(p) => (p as u32 * dimensions.pixel_height as u32) / 100, + BackgroundSize::Length(u) => u as u32, + unsup => anyhow::bail!("{:?} not yet implemented", unsup), + }; + + let size = width.min(height); + + let mut imgbuf = image::RgbaImage::new(size, size); + let src_pixel = { + let (r, g, b, a) = color.to_srgb_u8(); + image::Rgba([r, g, b, a]) + }; + for (_x, _y, pixel) in imgbuf.enumerate_pixels_mut() { + *pixel = src_pixel; + } + let data = imgbuf.into_vec(); + Arc::new(ImageData::with_data(ImageDataType::new_single_frame( + size, size, data, + ))) + } BackgroundSource::File(source) => CachedImage::load(&source.path, source.speed)?, };