Skip to content

Commit

Permalink
feat: enforce minimum contrast ratio for reverse video cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
jameshurst committed Jan 19, 2025
1 parent 6c443be commit bf466ab
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 18 deletions.
52 changes: 42 additions & 10 deletions color-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,16 +538,8 @@ impl SrgbaTuple {
*deltae::DeltaE::new(a, b, deltae::DEMethod::DE2000).value()
}

pub fn contrast_ratio(&self, other: &Self) -> f64 {
let (_, _, l_a, _) = self.to_hsla();
let (_, _, l_b, _) = other.to_hsla();
let a = l_a + 0.05;
let b = l_b + 0.05;
if a > b {
a / b
} else {
b / a
}
pub fn contrast_ratio(&self, other: &Self) -> f32 {
self.to_linear().contrast_ratio(&other.to_linear())
}
}

Expand Down Expand Up @@ -891,6 +883,22 @@ impl LinearRgba {
self.3,
)
}

pub fn relative_luminance(&self) -> f32 {
0.2126 * self.0 + 0.7152 * self.1 + 0.0722 * self.2
}

pub fn contrast_ratio(&self, other: &Self) -> f32 {
let l_a = self.relative_luminance();
let l_b = other.relative_luminance();
let a = l_a + 0.05;
let b = l_b + 0.05;
if a > b {
a / b
} else {
b / a
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -960,4 +968,28 @@ mod tests {
let grey = SrgbaTuple::from_str("rgb:f0f0/f0f0/f0f0").unwrap();
assert_eq!(grey.to_rgb_string(), "#f0f0f0");
}

#[test]
fn linear_rgb_contrast_ratio() {
let a = LinearRgba::with_srgba(255, 0, 0, 1);
let b = LinearRgba::with_srgba(0, 255, 0, 1);
let contrast_ratio = a.contrast_ratio(&b);
assert!(
(2.91 - contrast_ratio).abs() < 0.01,
"contrast({}) == 2.91",
contrast_ratio
);
}

#[test]
fn srgba_contrast_ratio() {
let a = SrgbaTuple::from_str("hsl:0 100 50").unwrap();
let b = SrgbaTuple::from_str("hsl:120 100 50").unwrap();
let contrast_ratio = a.contrast_ratio(&b);
assert!(
(2.91 - contrast_ratio).abs() < 0.01,
"contrast({}) == 2.91",
contrast_ratio
);
}
}
26 changes: 18 additions & 8 deletions wezterm-gui/src/termwindow/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ impl crate::TermWindow {
}

pub fn compute_cell_fg_bg(&self, params: ComputeCellFgBgParams) -> ComputeCellFgBgResult {
const CURSOR_MIN_CONTRAST: f32 = 2.5;

if params.cursor.is_some() {
if let Some(bg_color_mix) = self.get_intensity_if_bell_target_ringing(
params.pane.expect("cursor only set if pane present"),
Expand Down Expand Up @@ -524,12 +526,14 @@ impl crate::TermWindow {
self.dead_key_status != DeadKeyStatus::None || self.leader_is_active();

if dead_key_or_leader && params.is_active_pane {
let (fg_color, bg_color) =
if self.config.force_reverse_video_cursor && params.cursor_is_default_color {
(params.bg_color, params.fg_color)
} else {
(params.cursor_fg, params.cursor_bg)
};
let (fg_color, bg_color) = if self.config.force_reverse_video_cursor
&& params.cursor_is_default_color
&& params.fg_color.contrast_ratio(&params.bg_color) >= CURSOR_MIN_CONTRAST
{
(params.bg_color, params.fg_color)
} else {
(params.cursor_fg, params.cursor_bg)
};

let color = params
.config
Expand Down Expand Up @@ -585,7 +589,10 @@ impl crate::TermWindow {
CursorShape::BlinkingBlock | CursorShape::SteadyBlock,
CursorVisibility::Visible,
) => {
if self.config.force_reverse_video_cursor && params.cursor_is_default_color {
if self.config.force_reverse_video_cursor
&& params.cursor_is_default_color
&& params.fg_color.contrast_ratio(&params.bg_color) >= CURSOR_MIN_CONTRAST
{
(params.bg_color, params.fg_color, params.fg_color)
} else {
(
Expand All @@ -604,7 +611,10 @@ impl crate::TermWindow {
| CursorShape::SteadyBar,
CursorVisibility::Visible,
) => {
if self.config.force_reverse_video_cursor && params.cursor_is_default_color {
if self.config.force_reverse_video_cursor
&& params.cursor_is_default_color
&& params.fg_color.contrast_ratio(&params.bg_color) >= CURSOR_MIN_CONTRAST
{
(params.fg_color, params.bg_color, params.fg_color)
} else {
(params.fg_color, params.bg_color, params.cursor_bg)
Expand Down

0 comments on commit bf466ab

Please sign in to comment.