Don't apply contrast adjustment to decorative chars (#34238)
Closes #34234 Release Notes: - Automatic contrast adjustment in terminal is no longer applied to decorative characters used in block art.
This commit is contained in:
parent
d52f07b77c
commit
56d0ae6782
1 changed files with 105 additions and 1 deletions
|
@ -494,6 +494,22 @@ impl TerminalElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if a character is a decorative block/box-like character that should
|
||||||
|
/// preserve its exact colors without contrast adjustment.
|
||||||
|
///
|
||||||
|
/// Fixes https://github.com/zed-industries/zed/issues/34234 - we can
|
||||||
|
/// expand this list if we run into more similar cases, but the goal
|
||||||
|
/// is to be conservative here.
|
||||||
|
fn is_decorative_character(ch: char) -> bool {
|
||||||
|
matches!(
|
||||||
|
ch as u32,
|
||||||
|
// 0x2500..=0x257F Box Drawing
|
||||||
|
// 0x2580..=0x259F Block Elements
|
||||||
|
// 0x25A0..=0x25D7 Geometric Shapes (block/box-like subset)
|
||||||
|
0x2500..=0x25D7
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts the Alacritty cell styles to GPUI text styles and background color.
|
/// Converts the Alacritty cell styles to GPUI text styles and background color.
|
||||||
fn cell_style(
|
fn cell_style(
|
||||||
indexed: &IndexedCell,
|
indexed: &IndexedCell,
|
||||||
|
@ -508,7 +524,10 @@ impl TerminalElement {
|
||||||
let mut fg = convert_color(&fg, colors);
|
let mut fg = convert_color(&fg, colors);
|
||||||
let bg = convert_color(&bg, colors);
|
let bg = convert_color(&bg, colors);
|
||||||
|
|
||||||
fg = color_contrast::ensure_minimum_contrast(fg, bg, minimum_contrast);
|
// Only apply contrast adjustment to non-decorative characters
|
||||||
|
if !Self::is_decorative_character(indexed.c) {
|
||||||
|
fg = color_contrast::ensure_minimum_contrast(fg, bg, minimum_contrast);
|
||||||
|
}
|
||||||
|
|
||||||
// Ghostty uses (175/255) as the multiplier (~0.69), Alacritty uses 0.66, Kitty
|
// Ghostty uses (175/255) as the multiplier (~0.69), Alacritty uses 0.66, Kitty
|
||||||
// uses 0.75. We're using 0.7 because it's pretty well in the middle of that.
|
// uses 0.75. We're using 0.7 because it's pretty well in the middle of that.
|
||||||
|
@ -1575,6 +1594,91 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{AbsoluteLength, Hsla, font};
|
use gpui::{AbsoluteLength, Hsla, font};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_decorative_character() {
|
||||||
|
// Box Drawing characters (U+2500 to U+257F)
|
||||||
|
assert!(TerminalElement::is_decorative_character('─')); // U+2500
|
||||||
|
assert!(TerminalElement::is_decorative_character('│')); // U+2502
|
||||||
|
assert!(TerminalElement::is_decorative_character('┌')); // U+250C
|
||||||
|
assert!(TerminalElement::is_decorative_character('┐')); // U+2510
|
||||||
|
assert!(TerminalElement::is_decorative_character('└')); // U+2514
|
||||||
|
assert!(TerminalElement::is_decorative_character('┘')); // U+2518
|
||||||
|
assert!(TerminalElement::is_decorative_character('┼')); // U+253C
|
||||||
|
|
||||||
|
// Block Elements (U+2580 to U+259F)
|
||||||
|
assert!(TerminalElement::is_decorative_character('▀')); // U+2580
|
||||||
|
assert!(TerminalElement::is_decorative_character('▄')); // U+2584
|
||||||
|
assert!(TerminalElement::is_decorative_character('█')); // U+2588
|
||||||
|
assert!(TerminalElement::is_decorative_character('░')); // U+2591
|
||||||
|
assert!(TerminalElement::is_decorative_character('▒')); // U+2592
|
||||||
|
assert!(TerminalElement::is_decorative_character('▓')); // U+2593
|
||||||
|
|
||||||
|
// Geometric Shapes - block/box-like subset (U+25A0 to U+25D7)
|
||||||
|
assert!(TerminalElement::is_decorative_character('■')); // U+25A0
|
||||||
|
assert!(TerminalElement::is_decorative_character('□')); // U+25A1
|
||||||
|
assert!(TerminalElement::is_decorative_character('▲')); // U+25B2
|
||||||
|
assert!(TerminalElement::is_decorative_character('▼')); // U+25BC
|
||||||
|
assert!(TerminalElement::is_decorative_character('◆')); // U+25C6
|
||||||
|
assert!(TerminalElement::is_decorative_character('●')); // U+25CF
|
||||||
|
|
||||||
|
// The specific character from the issue
|
||||||
|
assert!(TerminalElement::is_decorative_character('◗')); // U+25D7
|
||||||
|
|
||||||
|
// Characters that should NOT be considered decorative
|
||||||
|
assert!(!TerminalElement::is_decorative_character('A'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character('a'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character('0'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character(' '));
|
||||||
|
assert!(!TerminalElement::is_decorative_character('←')); // U+2190 (Arrow, not in our ranges)
|
||||||
|
assert!(!TerminalElement::is_decorative_character('→')); // U+2192 (Arrow, not in our ranges)
|
||||||
|
assert!(!TerminalElement::is_decorative_character('◘')); // U+25D8 (Just outside our range)
|
||||||
|
assert!(!TerminalElement::is_decorative_character('◙')); // U+25D9 (Just outside our range)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decorative_character_boundary_cases() {
|
||||||
|
// Test exact boundaries of our ranges
|
||||||
|
// Box Drawing range boundaries
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{2500}')); // First char
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{257F}')); // Last char
|
||||||
|
assert!(!TerminalElement::is_decorative_character('\u{24FF}')); // Just before
|
||||||
|
|
||||||
|
// Block Elements range boundaries
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{2580}')); // First char
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{259F}')); // Last char
|
||||||
|
|
||||||
|
// Geometric Shapes subset boundaries
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{25A0}')); // First char
|
||||||
|
assert!(TerminalElement::is_decorative_character('\u{25D7}')); // Last char (◗)
|
||||||
|
assert!(!TerminalElement::is_decorative_character('\u{25D8}')); // Just after
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decorative_characters_bypass_contrast_adjustment() {
|
||||||
|
// Decorative characters should not be affected by contrast adjustment
|
||||||
|
|
||||||
|
// The specific character from issue #34234
|
||||||
|
let problematic_char = '◗'; // U+25D7
|
||||||
|
assert!(
|
||||||
|
TerminalElement::is_decorative_character(problematic_char),
|
||||||
|
"Character ◗ (U+25D7) should be recognized as decorative"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Verify some other commonly used decorative characters
|
||||||
|
assert!(TerminalElement::is_decorative_character('│')); // Vertical line
|
||||||
|
assert!(TerminalElement::is_decorative_character('─')); // Horizontal line
|
||||||
|
assert!(TerminalElement::is_decorative_character('█')); // Full block
|
||||||
|
assert!(TerminalElement::is_decorative_character('▓')); // Dark shade
|
||||||
|
assert!(TerminalElement::is_decorative_character('■')); // Black square
|
||||||
|
assert!(TerminalElement::is_decorative_character('●')); // Black circle
|
||||||
|
|
||||||
|
// Verify normal text characters are NOT decorative
|
||||||
|
assert!(!TerminalElement::is_decorative_character('A'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character('1'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character('$'));
|
||||||
|
assert!(!TerminalElement::is_decorative_character(' '));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_contrast_adjustment_logic() {
|
fn test_contrast_adjustment_logic() {
|
||||||
// Test the core contrast adjustment logic without needing full app context
|
// Test the core contrast adjustment logic without needing full app context
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue