1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 13:16:39 +03:00

palette now stores alpha for all color values

We're now capable of remembering an alpha value for everything
in the palette and the main window theme, but not the tab bar theme.

Whether the alpha is correctly respected at render time is a different
story!

refs: #1835
This commit is contained in:
Wez Furlong 2022-04-08 07:08:33 -07:00
parent d356b72ca9
commit 5914a91490
10 changed files with 207 additions and 165 deletions

View File

@ -405,7 +405,7 @@ macro_rules! pdu {
/// The overall version of the codec.
/// This must be bumped when backwards incompatible changes
/// are made to the types and protocol.
pub const CODEC_VERSION: usize = 21;
pub const CODEC_VERSION: usize = 22;
// Defines the Pdu enum.
// Each struct has an explicit identifying number.

View File

@ -1,6 +1,7 @@
#[cfg(feature = "use_serde")]
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::str::FromStr;
lazy_static::lazy_static! {
@ -269,6 +270,13 @@ impl SrgbaTuple {
NAMED_COLORS.get(&name.to_ascii_lowercase()).cloned()
}
/// Returns self multiplied by the supplied alpha value.
/// We don't need to linearize for this, as alpha is defined
/// as being linear even in srgba!
pub fn mul_alpha(self, alpha: f32) -> Self {
Self(self.0, self.1, self.2, self.3 * alpha)
}
pub fn to_linear(self) -> LinearRgba {
// See https://docs.rs/palette/0.5.0/src/palette/encoding/srgb.rs.html#43
fn to_linear(v: f32) -> f32 {
@ -318,6 +326,17 @@ impl SrgbaTuple {
}
}
impl Hash for SrgbaTuple {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.to_ne_bytes().hash(state);
self.1.to_ne_bytes().hash(state);
self.2.to_ne_bytes().hash(state);
self.3.to_ne_bytes().hash(state);
}
}
impl Eq for SrgbaTuple {}
impl FromStr for SrgbaTuple {
type Err = ();
@ -529,6 +548,11 @@ impl LinearRgba {
}
}
/// Returns self multiplied by the supplied alpha value
pub fn mul_alpha(self, alpha: f32) -> Self {
Self(self.0, self.1, self.2, self.3 * alpha)
}
/// Convert to an SRGB u32 pixel
pub fn srgba_pixel(self) -> SrgbaPixel {
SrgbaPixel::rgba(

View File

@ -25,12 +25,12 @@ impl Default for HsbTransform {
}
}
fn de_indexed<'de, D>(deserializer: D) -> Result<HashMap<u8, RgbColor>, D::Error>
fn de_indexed<'de, D>(deserializer: D) -> Result<HashMap<u8, RgbaColor>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Wrap(HashMap<String, RgbColor>);
struct Wrap(HashMap<String, RgbaColor>);
let Wrap(map) = Wrap::deserialize(deserializer)?;
Ok(map
@ -45,13 +45,28 @@ where
.collect())
}
#[derive(Default, Debug, Deserialize, Serialize, Clone, Copy)]
#[derive(Default, Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(try_from = "String", into = "String")]
pub struct RgbaColor {
#[serde(flatten)]
color: SrgbaTuple,
}
impl From<RgbColor> for RgbaColor {
fn from(color: RgbColor) -> Self {
Self {
color: color.into(),
}
}
}
impl std::ops::Deref for RgbaColor {
type Target = SrgbaTuple;
fn deref(&self) -> &SrgbaTuple {
&self.color
}
}
impl Into<String> for RgbaColor {
fn into(self) -> String {
self.color.to_rgb_string()
@ -77,37 +92,37 @@ impl std::convert::TryFrom<String> for RgbaColor {
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
pub struct Palette {
/// The text color to use when the attributes are reset to default
pub foreground: Option<RgbColor>,
pub foreground: Option<RgbaColor>,
/// The background color to use when the attributes are reset to default
pub background: Option<RgbColor>,
pub background: Option<RgbaColor>,
/// The color of the cursor
pub cursor_fg: Option<RgbColor>,
pub cursor_bg: Option<RgbColor>,
pub cursor_border: Option<RgbColor>,
pub cursor_fg: Option<RgbaColor>,
pub cursor_bg: Option<RgbaColor>,
pub cursor_border: Option<RgbaColor>,
/// The color of selected text
pub selection_fg: Option<RgbaColor>,
pub selection_bg: Option<RgbaColor>,
/// A list of 8 colors corresponding to the basic ANSI palette
pub ansi: Option<[RgbColor; 8]>,
pub ansi: Option<[RgbaColor; 8]>,
/// A list of 8 colors corresponding to bright versions of the
/// ANSI palette
pub brights: Option<[RgbColor; 8]>,
pub brights: Option<[RgbaColor; 8]>,
/// A map for setting arbitrary colors ranging from 16 to 256 in the color
/// palette
#[serde(default, deserialize_with = "de_indexed")]
pub indexed: HashMap<u8, RgbColor>,
pub indexed: HashMap<u8, RgbaColor>,
/// Configure the colors and styling of the tab bar
pub tab_bar: Option<TabBarColors>,
/// The color of the "thumb" of the scrollbar; the segment that
/// represents the current viewable area
pub scrollbar_thumb: Option<RgbColor>,
pub scrollbar_thumb: Option<RgbaColor>,
/// The color of the split line between panes
pub split: Option<RgbColor>,
pub split: Option<RgbaColor>,
/// The color of the visual bell. If unspecified, the foreground
/// color is used instead.
pub visual_bell: Option<RgbColor>,
pub visual_bell: Option<RgbaColor>,
/// The color to use for the cursor when a dead key or leader state is active
pub compose_cursor: Option<RgbColor>,
pub compose_cursor: Option<RgbaColor>,
}
impl_lua_conversion!(Palette);
@ -133,16 +148,16 @@ impl From<Palette> for wezterm_term::color::ColorPalette {
if let Some(ansi) = cfg.ansi {
for (idx, col) in ansi.iter().enumerate() {
p.colors.0[idx] = *col;
p.colors.0[idx] = (*col).into();
}
}
if let Some(brights) = cfg.brights {
for (idx, col) in brights.iter().enumerate() {
p.colors.0[idx + 8] = *col;
p.colors.0[idx + 8] = (*col).into();
}
}
for (&idx, &col) in &cfg.indexed {
p.colors.0[idx as usize] = col;
p.colors.0[idx as usize] = col.into();
}
p
}
@ -213,10 +228,10 @@ pub struct TabBarColors {
pub new_tab_hover: TabBarColor,
#[serde(default = "default_inactive_tab_edge")]
pub inactive_tab_edge: RgbColor,
pub inactive_tab_edge: RgbaColor,
#[serde(default = "default_inactive_tab_edge_hover")]
pub inactive_tab_edge_hover: RgbColor,
pub inactive_tab_edge_hover: RgbaColor,
}
impl_lua_conversion!(TabBarColors);
@ -224,12 +239,12 @@ fn default_background() -> RgbColor {
RgbColor::new_8bpc(0x33, 0x33, 0x33)
}
fn default_inactive_tab_edge() -> RgbColor {
RgbColor::new_8bpc(0x57, 0x57, 0x57)
fn default_inactive_tab_edge() -> RgbaColor {
RgbColor::new_8bpc(0x57, 0x57, 0x57).into()
}
fn default_inactive_tab_edge_hover() -> RgbColor {
RgbColor::new_8bpc(0x36, 0x36, 0x36)
fn default_inactive_tab_edge_hover() -> RgbaColor {
RgbColor::new_8bpc(0x36, 0x36, 0x36).into()
}
fn default_inactive_tab() -> TabBarColor {

View File

@ -1,3 +1,4 @@
use crate::color::RgbaColor;
use crate::*;
use bitflags::*;
use enum_display_derive::Display;
@ -5,7 +6,6 @@ use luahelper::impl_lua_conversion;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::convert::TryFrom;
use std::fmt::Display;
use termwiz::color::RgbColor;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Hash, Display, PartialOrd, Ord,
@ -439,7 +439,7 @@ pub struct TextStyle {
/// foreground color, use this color instead. This is most
/// useful in a `[[font_rules]]` section to implement changing
/// the text color for eg: bold text.
pub foreground: Option<RgbColor>,
pub foreground: Option<RgbaColor>,
}
impl_lua_conversion!(TextStyle);

View File

@ -1,6 +1,7 @@
use crate::keyassignment::KeyAssignment;
use crate::{
FontAttributes, FontStretch, FontStyle, FontWeight, FreeTypeLoadTarget, Gradient, TextStyle,
FontAttributes, FontStretch, FontStyle, FontWeight, FreeTypeLoadTarget, Gradient, RgbaColor,
TextStyle,
};
use anyhow::anyhow;
use bstr::BString;
@ -461,7 +462,7 @@ struct TextStyleAttributes {
/// foreground color, use this color instead. This is most
/// useful in a `[[font_rules]]` section to implement changing
/// the text color for eg: bold text.
pub foreground: Option<termwiz::color::RgbColor>,
pub foreground: Option<RgbaColor>,
}
impl<'lua> FromLua<'lua> for TextStyleAttributes {
fn from_lua(value: Value<'lua>, _lua: &'lua Lua) -> Result<Self, mlua::Error> {

View File

@ -6,8 +6,8 @@ use std::fmt;
use std::result::Result;
pub use termwiz::color::{AnsiColor, ColorAttribute, RgbColor, SrgbaTuple};
#[derive(Clone, PartialEq, Eq)]
pub struct Palette256(pub [RgbColor; 256]);
#[derive(Clone, PartialEq)]
pub struct Palette256(pub [SrgbaTuple; 256]);
#[cfg(feature = "use_serde")]
impl Serialize for Palette256 {
@ -25,7 +25,7 @@ impl<'de> Deserialize<'de> for Palette256 {
where
D: Deserializer<'de>,
{
let s = Vec::<RgbColor>::deserialize(deserializer)?;
let s = Vec::<SrgbaTuple>::deserialize(deserializer)?;
use std::convert::TryInto;
Ok(Self(s.try_into().map_err(|_| {
serde::de::Error::custom("Palette256 size mismatch")
@ -33,9 +33,9 @@ impl<'de> Deserialize<'de> for Palette256 {
}
}
impl std::iter::FromIterator<RgbColor> for Palette256 {
fn from_iter<I: IntoIterator<Item = RgbColor>>(iter: I) -> Self {
let mut colors = [RgbColor::default(); 256];
impl std::iter::FromIterator<SrgbaTuple> for Palette256 {
fn from_iter<I: IntoIterator<Item = SrgbaTuple>>(iter: I) -> Self {
let mut colors = [SrgbaTuple::default(); 256];
for (s, d) in iter.into_iter().zip(colors.iter_mut()) {
*d = s;
}
@ -47,15 +47,15 @@ impl std::iter::FromIterator<RgbColor> for Palette256 {
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
pub struct ColorPalette {
pub colors: Palette256,
pub foreground: RgbColor,
pub background: RgbColor,
pub foreground: SrgbaTuple,
pub background: SrgbaTuple,
pub cursor_fg: SrgbaTuple,
pub cursor_bg: SrgbaTuple,
pub cursor_border: SrgbaTuple,
pub selection_fg: SrgbaTuple,
pub selection_bg: SrgbaTuple,
pub scrollbar_thumb: RgbColor,
pub split: RgbColor,
pub scrollbar_thumb: SrgbaTuple,
pub split: SrgbaTuple,
}
impl fmt::Debug for Palette256 {
@ -69,20 +69,20 @@ impl fmt::Debug for Palette256 {
}
impl ColorPalette {
pub fn resolve_fg(&self, color: ColorAttribute) -> RgbColor {
pub fn resolve_fg(&self, color: ColorAttribute) -> SrgbaTuple {
match color {
ColorAttribute::Default => self.foreground,
ColorAttribute::PaletteIndex(idx) => self.colors.0[idx as usize],
ColorAttribute::TrueColorWithPaletteFallback(color, _)
| ColorAttribute::TrueColorWithDefaultFallback(color) => color,
| ColorAttribute::TrueColorWithDefaultFallback(color) => color.into(),
}
}
pub fn resolve_bg(&self, color: ColorAttribute) -> RgbColor {
pub fn resolve_bg(&self, color: ColorAttribute) -> SrgbaTuple {
match color {
ColorAttribute::Default => self.background,
ColorAttribute::PaletteIndex(idx) => self.colors.0[idx as usize],
ColorAttribute::TrueColorWithPaletteFallback(color, _)
| ColorAttribute::TrueColorWithDefaultFallback(color) => color,
| ColorAttribute::TrueColorWithDefaultFallback(color) => color.into(),
}
}
}
@ -100,45 +100,45 @@ impl Default for ColorPalette {
impl ColorPalette {
fn compute_default() -> Self {
let mut colors = [RgbColor::default(); 256];
let mut colors = [SrgbaTuple::default(); 256];
// The XTerm ansi color set
static ANSI: [RgbColor; 16] = [
let ansi: [SrgbaTuple; 16] = [
// Black
RgbColor::new_8bpc(0x00, 0x00, 0x00),
RgbColor::new_8bpc(0x00, 0x00, 0x00).into(),
// Maroon
RgbColor::new_8bpc(0xcc, 0x55, 0x55),
RgbColor::new_8bpc(0xcc, 0x55, 0x55).into(),
// Green
RgbColor::new_8bpc(0x55, 0xcc, 0x55),
RgbColor::new_8bpc(0x55, 0xcc, 0x55).into(),
// Olive
RgbColor::new_8bpc(0xcd, 0xcd, 0x55),
RgbColor::new_8bpc(0xcd, 0xcd, 0x55).into(),
// Navy
RgbColor::new_8bpc(0x54, 0x55, 0xcb),
RgbColor::new_8bpc(0x54, 0x55, 0xcb).into(),
// Purple
RgbColor::new_8bpc(0xcc, 0x55, 0xcc),
RgbColor::new_8bpc(0xcc, 0x55, 0xcc).into(),
// Teal
RgbColor::new_8bpc(0x7a, 0xca, 0xca),
RgbColor::new_8bpc(0x7a, 0xca, 0xca).into(),
// Silver
RgbColor::new_8bpc(0xcc, 0xcc, 0xcc),
RgbColor::new_8bpc(0xcc, 0xcc, 0xcc).into(),
// Grey
RgbColor::new_8bpc(0x55, 0x55, 0x55),
RgbColor::new_8bpc(0x55, 0x55, 0x55).into(),
// Red
RgbColor::new_8bpc(0xff, 0x55, 0x55),
RgbColor::new_8bpc(0xff, 0x55, 0x55).into(),
// Lime
RgbColor::new_8bpc(0x55, 0xff, 0x55),
RgbColor::new_8bpc(0x55, 0xff, 0x55).into(),
// Yellow
RgbColor::new_8bpc(0xff, 0xff, 0x55),
RgbColor::new_8bpc(0xff, 0xff, 0x55).into(),
// Blue
RgbColor::new_8bpc(0x55, 0x55, 0xff),
RgbColor::new_8bpc(0x55, 0x55, 0xff).into(),
// Fuchsia
RgbColor::new_8bpc(0xff, 0x55, 0xff),
RgbColor::new_8bpc(0xff, 0x55, 0xff).into(),
// Aqua
RgbColor::new_8bpc(0x55, 0xff, 0xff),
RgbColor::new_8bpc(0x55, 0xff, 0xff).into(),
// White
RgbColor::new_8bpc(0xff, 0xff, 0xff),
RgbColor::new_8bpc(0xff, 0xff, 0xff).into(),
];
colors[0..16].copy_from_slice(&ANSI);
colors[0..16].copy_from_slice(&ansi);
// 216 color cube.
// This isn't the perfect color cube, but it matches the values used
@ -149,7 +149,7 @@ impl ColorPalette {
let green = RAMP6[idx / 6 % 6];
let red = RAMP6[idx / 6 / 6 % 6];
colors[16 + idx] = RgbColor::new_8bpc(red, green, blue);
colors[16 + idx] = RgbColor::new_8bpc(red, green, blue).into();
}
// 24 grey scales
@ -161,7 +161,7 @@ impl ColorPalette {
for idx in 0..24 {
let grey = GREYS[idx];
colors[232 + idx] = RgbColor::new_8bpc(grey, grey, grey);
colors[232 + idx] = RgbColor::new_8bpc(grey, grey, grey).into();
}
let foreground = colors[249]; // Grey70
@ -174,8 +174,8 @@ impl ColorPalette {
let selection_fg = SrgbaTuple(0., 0., 0., 0.);
let selection_bg = SrgbaTuple(0.5, 0.4, 0.6, 0.5);
let scrollbar_thumb = RgbColor::new_8bpc(0x22, 0x22, 0x22);
let split = RgbColor::new_8bpc(0x44, 0x44, 0x44);
let scrollbar_thumb = RgbColor::new_8bpc(0x22, 0x22, 0x22).into();
let split = RgbColor::new_8bpc(0x44, 0x44, 0x44).into();
ColorPalette {
colors: Palette256(colors),

View File

@ -24,7 +24,7 @@ pub use self::osc::OperatingSystemCommand;
use vtparse::CsiParam;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
/// Send a single printable character to the display
Print(char),

View File

@ -1,4 +1,4 @@
use crate::color::RgbColor;
use crate::color::{RgbColor, SrgbaTuple};
pub use crate::hyperlink::Hyperlink;
use crate::{bail, ensure, Result};
use bitflags::bitflags;
@ -9,9 +9,9 @@ use std::collections::HashMap;
use std::fmt::{Display, Error as FmtError, Formatter, Result as FmtResult};
use std::str;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub enum ColorOrQuery {
Color(RgbColor),
Color(SrgbaTuple),
Query,
}
@ -24,7 +24,7 @@ impl Display for ColorOrQuery {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub enum OperatingSystemCommand {
SetIconNameAndWindowTitle(String),
SetWindowTitle(String),
@ -63,7 +63,7 @@ pub enum DynamicColorNumber {
HighlightForegroundColor = 19,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub struct ChangeColorPair {
pub palette_index: u8,
pub color: ColorOrQuery,
@ -204,7 +204,8 @@ impl OperatingSystemCommand {
} else {
ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| format!("invalid color spec {:?}", spec))?,
.ok_or_else(|| format!("invalid color spec {:?}", spec))?
.into(),
)
};
@ -235,7 +236,8 @@ impl OperatingSystemCommand {
let spec = str::from_utf8(spec)?;
colors.push(ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| format!("invalid color spec {:?}", spec))?,
.ok_or_else(|| format!("invalid color spec {:?}", spec))?
.into(),
));
}
}

View File

@ -2,7 +2,6 @@
use crate::color::LinearRgba;
use crate::customglyph::{BlockKey, Poly};
use crate::glyphcache::CachedGlyph;
use crate::termwindow::render::rgbcolor_to_window_color;
use crate::termwindow::{
MappedQuads, MouseCapture, RenderState, SrgbTexture2d, TermWindowNotif, UIItem, UIItemType,
};
@ -265,13 +264,17 @@ impl Element {
bg: if cluster.attrs.background() == ColorAttribute::Default {
InheritableColor::Inherited
} else {
rgbcolor_to_window_color(palette.resolve_bg(cluster.attrs.background()))
palette
.resolve_bg(cluster.attrs.background())
.to_linear()
.into()
},
text: if cluster.attrs.foreground() == ColorAttribute::Default {
InheritableColor::Inherited
} else {
rgbcolor_to_window_color(palette.resolve_fg(cluster.attrs.foreground()))
palette
.resolve_fg(cluster.attrs.foreground())
.to_linear()
.into()
},
});

View File

@ -583,17 +583,19 @@ impl super::TermWindow {
bottom_right: SizedPoly::none(),
}))
.colors(ElementColors {
border: BorderColor::new(rgbcolor_to_window_color(
bg_color.unwrap_or(colors.active_tab.bg_color),
)),
bg: rgbcolor_to_window_color(
bg_color.unwrap_or(colors.active_tab.bg_color),
)
.into(),
text: rgbcolor_to_window_color(
fg_color.unwrap_or(colors.active_tab.fg_color),
)
.into(),
border: BorderColor::new(
bg_color
.unwrap_or_else(|| colors.active_tab.bg_color.into())
.to_linear(),
),
bg: bg_color
.unwrap_or_else(|| colors.active_tab.bg_color.into())
.to_linear()
.into(),
text: fg_color
.unwrap_or_else(|| colors.active_tab.fg_color.into())
.to_linear()
.into(),
}),
TabBarItem::Tab { .. } => element
.item_type(UIItemType::TabBar(item.item.clone()))
@ -633,10 +635,10 @@ impl super::TermWindow {
},
}))
.colors({
let bg = rgbcolor_to_window_color(
bg_color.unwrap_or(colors.inactive_tab.bg_color),
);
let edge = rgbcolor_to_window_color(colors.inactive_tab_edge);
let bg = bg_color
.unwrap_or_else(|| colors.inactive_tab.bg_color.into())
.to_linear();
let edge = colors.inactive_tab_edge.to_linear();
ElementColors {
border: BorderColor {
left: bg,
@ -645,24 +647,26 @@ impl super::TermWindow {
bottom: bg,
},
bg: bg.into(),
text: rgbcolor_to_window_color(
fg_color.unwrap_or(colors.inactive_tab.fg_color),
)
.into(),
text: fg_color
.unwrap_or_else(|| colors.inactive_tab.fg_color.into())
.to_linear()
.into(),
}
})
.hover_colors(Some(ElementColors {
border: BorderColor::new(rgbcolor_to_window_color(
bg_color.unwrap_or(colors.inactive_tab_hover.bg_color),
)),
bg: rgbcolor_to_window_color(
bg_color.unwrap_or(colors.inactive_tab_hover.bg_color),
)
.into(),
text: rgbcolor_to_window_color(
fg_color.unwrap_or(colors.inactive_tab_hover.fg_color),
)
.into(),
border: BorderColor::new(
bg_color
.unwrap_or_else(|| colors.inactive_tab_hover.bg_color.into())
.to_linear(),
),
bg: bg_color
.unwrap_or_else(|| colors.inactive_tab_hover.bg_color.into())
.to_linear()
.into(),
text: fg_color
.unwrap_or_else(|| colors.inactive_tab_hover.fg_color.into())
.to_linear()
.into(),
})),
}
};
@ -875,14 +879,14 @@ impl super::TermWindow {
let gl_state = self.render_state.as_ref().unwrap();
let white_space = gl_state.util_sprites.white_space.texture_coords();
let filled_box = gl_state.util_sprites.filled_box.texture_coords();
let default_bg = rgbcolor_alpha_to_window_color(
palette.resolve_bg(ColorAttribute::Default),
if window_is_transparent {
let default_bg = palette
.resolve_bg(ColorAttribute::Default)
.to_linear()
.mul_alpha(if window_is_transparent {
0.
} else {
self.config.text_background_opacity
},
);
});
let vb = [&gl_state.vb[0], &gl_state.vb[1], &gl_state.vb[2]];
let mut vb_mut0 = vb[0].current_vb_mut();
@ -913,7 +917,7 @@ impl super::TermWindow {
},
config: &self.config,
cursor_border_color: LinearRgba::default(),
foreground: rgbcolor_to_window_color(palette.foreground),
foreground: palette.foreground.to_linear(),
pane: None,
is_active: true,
selection_fg: LinearRgba::default(),
@ -1076,31 +1080,31 @@ impl super::TermWindow {
metrics::histogram!("quad.map", start.elapsed());
let cursor_border_color = palette.cursor_border.to_linear();
let foreground = rgbcolor_to_window_color(palette.foreground);
let foreground = palette.foreground.to_linear();
let white_space = gl_state.util_sprites.white_space.texture_coords();
let filled_box = gl_state.util_sprites.filled_box.texture_coords();
let window_is_transparent =
self.window_background.is_some() || config.window_background_opacity != 1.0;
let default_bg = rgbcolor_alpha_to_window_color(
palette.resolve_bg(ColorAttribute::Default),
if window_is_transparent {
let default_bg = palette
.resolve_bg(ColorAttribute::Default)
.to_linear()
.mul_alpha(if window_is_transparent {
0.
} else {
config.text_background_opacity
},
);
});
// Render the full window background
if pos.index == 0 {
match (self.window_background.as_ref(), self.allow_images) {
(Some(im), true) => {
// Render the window background image
let color = rgbcolor_alpha_to_window_color(
palette.background,
config.window_background_opacity,
);
let color = palette
.background
.to_linear()
.mul_alpha(config.window_background_opacity);
let (sprite, next_due) =
gl_state.glyph_cache.borrow_mut().cached_image(im, None)?;
@ -1124,16 +1128,15 @@ impl super::TermWindow {
}
_ => {
// Regular window background color
let background = rgbcolor_alpha_to_window_color(
if num_panes == 1 {
// If we're the only pane, use the pane's palette
// to draw the padding background
palette.background
} else {
global_bg_color
},
config.window_background_opacity,
);
let background = if num_panes == 1 {
// If we're the only pane, use the pane's palette
// to draw the padding background
palette.background
} else {
global_bg_color
}
.to_linear()
.mul_alpha(config.window_background_opacity);
self.filled_rectangle(
&mut layers[0],
euclid::rect(
@ -1211,10 +1214,10 @@ impl super::TermWindow {
0.
},
),
rgbcolor_alpha_to_window_color(
palette.background,
config.window_background_opacity,
),
palette
.background
.to_linear()
.mul_alpha(config.window_background_opacity),
)?;
quad.set_hsv(if pos.is_active {
None
@ -1235,8 +1238,9 @@ impl super::TermWindow {
let LinearRgba(r, g, b, _) = config
.resolved_palette
.visual_bell
.unwrap_or(palette.foreground)
.to_linear_tuple_rgba();
.as_deref()
.unwrap_or(&palette.foreground)
.to_linear();
let background = if window_is_transparent {
// for transparent windows, we fade in the target color
@ -1245,11 +1249,11 @@ impl super::TermWindow {
} else {
// otherwise We'll interpolate between the background color
// and the the target color
let (r1, g1, b1, a) = rgbcolor_alpha_to_window_color(
palette.background,
config.window_background_opacity,
)
.tuple();
let (r1, g1, b1, a) = palette
.background
.to_linear()
.mul_alpha(config.window_background_opacity)
.tuple();
LinearRgba::with_components(
r1 + (r - r1) * intensity,
g1 + (g - g1) * intensity,
@ -1299,7 +1303,7 @@ impl super::TermWindow {
);
let abs_thumb_top = thumb_y_offset + info.top;
let thumb_size = info.height;
let color = rgbcolor_to_window_color(palette.scrollbar_thumb);
let color = palette.scrollbar_thumb.to_linear();
// Adjust the scrollbar thumb position
let config = &self.config;
@ -1541,7 +1545,7 @@ impl super::TermWindow {
let mut vb_mut = vb.current_vb_mut();
let mut quads = vb.map(&mut vb_mut);
let palette = pane.palette();
let foreground = rgbcolor_to_window_color(palette.split);
let foreground = palette.split.to_linear();
let cell_width = self.render_metrics.cell_size.width as f32;
let cell_height = self.render_metrics.cell_size.height as f32;
@ -1677,12 +1681,9 @@ impl super::TermWindow {
)?
.texture_coords();
let bg_is_default = attrs.background() == ColorAttribute::Default;
let bg_color = params.palette.resolve_bg(attrs.background());
let bg_color = params.palette.resolve_bg(attrs.background()).to_linear();
let fg_color = resolve_fg_color_attr(&attrs, attrs.foreground(), &params, style);
let fg_color = rgbcolor_to_window_color(fg_color);
let bg_color = rgbcolor_to_window_color(bg_color);
let (fg_color, bg_color, bg_is_default) = {
let mut fg = fg_color;
let mut bg = bg_color;
@ -1731,7 +1732,7 @@ impl super::TermWindow {
let glyph_color = fg_color;
let underline_color = match attrs.underline_color() {
ColorAttribute::Default => fg_color,
c => rgbcolor_to_window_color(resolve_fg_color_attr(&attrs, c, &params, style)),
c => resolve_fg_color_attr(&attrs, c, &params, style),
};
let (bg_r, bg_g, bg_b, _) = bg_color.tuple();
@ -1938,7 +1939,7 @@ impl super::TermWindow {
let cluster_width = cluster.width;
let bg_is_default = attrs.background() == ColorAttribute::Default;
let bg_color = params.palette.resolve_bg(attrs.background());
let bg_color = params.palette.resolve_bg(attrs.background()).to_linear();
let fg_color =
resolve_fg_color_attr(&attrs, attrs.foreground(), &params, &Default::default());
@ -1955,7 +1956,7 @@ impl super::TermWindow {
}
(
rgbcolor_alpha_to_window_color(bg, self.config.text_background_opacity),
bg.mul_alpha(self.config.text_background_opacity),
bg_default,
)
};
@ -2030,15 +2031,10 @@ impl super::TermWindow {
let (fg_color, bg_color) = if let Some(c) = params.line.cells().get(cursor_range.start)
{
let attrs = c.attrs();
let bg_color =
rgbcolor_to_window_color(params.palette.resolve_bg(attrs.background()));
let bg_color = params.palette.resolve_bg(attrs.background()).to_linear();
let fg_color = rgbcolor_to_window_color(resolve_fg_color_attr(
&attrs,
attrs.foreground(),
&params,
&Default::default(),
));
let fg_color =
resolve_fg_color_attr(&attrs, attrs.foreground(), &params, &Default::default());
(fg_color, bg_color)
} else {
@ -2510,7 +2506,7 @@ impl super::TermWindow {
.config
.resolved_palette
.visual_bell
.map(|c| c.to_linear_tuple_rgba().tuple())
.map(|c| c.to_linear().tuple())
.unwrap_or_else(|| fg_color.tuple());
let bg_color = LinearRgba::with_components(
@ -2543,7 +2539,7 @@ impl super::TermWindow {
.config
.resolved_palette
.compose_cursor
.map(rgbcolor_to_window_color)
.map(|c| c.to_linear())
.unwrap_or(bg_color);
return ComputeCellFgBgResult {
@ -2834,11 +2830,11 @@ fn resolve_fg_color_attr(
fg: ColorAttribute,
params: &RenderScreenLineOpenGLParams,
style: &config::TextStyle,
) -> RgbColor {
) -> LinearRgba {
match fg {
wezterm_term::color::ColorAttribute::Default => {
if let Some(fg) = style.foreground {
fg
fg.into()
} else {
params.palette.resolve_fg(attrs.foreground())
}
@ -2860,4 +2856,5 @@ fn resolve_fg_color_attr(
}
_ => params.palette.resolve_fg(fg),
}
.to_linear()
}