1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-18 13:55:23 -05:00

Add dim color support

Add support for the VTE 'dim' flag, with additional support for
custom-themed dim colors. If no color is specified in the config, it
will default to 2/3 the previous (not a spec, but the value other
terminals seem to use).

The actual dimming behavior brings bright colors to normal and regular
colors to the new dim ones. Custom RGB values are not changed, nor are
non-named indexed colors.
This commit is contained in:
Jake Merdich 2017-06-23 10:01:53 -07:00 committed by Joe Wilm
parent 0091d3cb99
commit b4a839aee9
8 changed files with 150 additions and 16 deletions

View file

@ -121,6 +121,17 @@ colors:
cyan: '0x54ced6' cyan: '0x54ced6'
white: '0xffffff' white: '0xffffff'
# Dim colors (Optional)
dim:
black: '0x333333'
red: '0xf2777a'
green: '0x99cc99'
yellow: '0xffcc66'
blue: '0x6699cc'
magenta: '0xcc99cc'
cyan: '0x66cccc'
white: '0xdddddd'
# Visual Bell # Visual Bell
# #
# Any time the BEL code is received, Alacritty "rings" the visual bell. Once # Any time the BEL code is received, Alacritty "rings" the visual bell. Once

View file

@ -120,6 +120,18 @@ colors:
cyan: '0x54ced6' cyan: '0x54ced6'
white: '0xffffff' white: '0xffffff'
# Dim colors (Optional)
dim:
black: '0x333333'
red: '0xf2777a'
green: '0x99cc99'
yellow: '0xffcc66'
blue: '0x6699cc'
magenta: '0xcc99cc'
cyan: '0x66cccc'
white: '0xdddddd'
# Visual Bell # Visual Bell
# #
# Any time the BEL code is received, Alacritty "rings" the visual bell. Once # Any time the BEL code is received, Alacritty "rings" the visual bell. Once

View file

@ -442,6 +442,22 @@ pub enum NamedColor {
CursorText, CursorText,
/// Color for the cursor itself /// Color for the cursor itself
Cursor, Cursor,
/// Dim black
DimBlack,
/// Dim red
DimRed,
/// Dim green
DimGreen,
/// Dim yellow
DimYellow,
/// Dim blue
DimBlue,
/// Dim magenta
DimMagenta,
/// Dim cyan
DimCyan,
/// Dim white
DimWhite,
} }
impl NamedColor { impl NamedColor {
@ -455,6 +471,36 @@ impl NamedColor {
NamedColor::Magenta => NamedColor::BrightMagenta, NamedColor::Magenta => NamedColor::BrightMagenta,
NamedColor::Cyan => NamedColor::BrightCyan, NamedColor::Cyan => NamedColor::BrightCyan,
NamedColor::White => NamedColor::BrightWhite, NamedColor::White => NamedColor::BrightWhite,
NamedColor::DimBlack => NamedColor::Black,
NamedColor::DimRed => NamedColor::Red,
NamedColor::DimGreen => NamedColor::Green,
NamedColor::DimYellow => NamedColor::Yellow,
NamedColor::DimBlue => NamedColor::Blue,
NamedColor::DimMagenta => NamedColor::Magenta,
NamedColor::DimCyan => NamedColor::Cyan,
NamedColor::DimWhite => NamedColor::White,
val => val
}
}
pub fn to_dim(&self) -> Self {
match *self {
NamedColor::Black => NamedColor::DimBlack,
NamedColor::Red => NamedColor::DimRed,
NamedColor::Green => NamedColor::DimGreen,
NamedColor::Yellow => NamedColor::DimYellow,
NamedColor::Blue => NamedColor::DimBlue,
NamedColor::Magenta => NamedColor::DimMagenta,
NamedColor::Cyan => NamedColor::DimCyan,
NamedColor::White => NamedColor::DimWhite,
NamedColor::BrightBlack => NamedColor::Black,
NamedColor::BrightRed => NamedColor::Red,
NamedColor::BrightGreen => NamedColor::Green,
NamedColor::BrightYellow => NamedColor::Yellow,
NamedColor::BrightBlue => NamedColor::Blue,
NamedColor::BrightMagenta => NamedColor::Magenta,
NamedColor::BrightCyan => NamedColor::Cyan,
NamedColor::BrightWhite => NamedColor::White,
val => val val => val
} }
} }

View file

@ -741,6 +741,7 @@ pub struct Colors {
pub cursor: CursorColors, pub cursor: CursorColors,
pub normal: AnsiColors, pub normal: AnsiColors,
pub bright: AnsiColors, pub bright: AnsiColors,
pub dim: Option<AnsiColors>,
} }
fn deserialize_cursor_colors<D>(deserializer: D) -> ::std::result::Result<CursorColors, D::Error> fn deserialize_cursor_colors<D>(deserializer: D) -> ::std::result::Result<CursorColors, D::Error>
@ -838,12 +839,13 @@ impl Default for Colors {
magenta: Rgb {r: 0xb7, g: 0x7e, b: 0xe0}, magenta: Rgb {r: 0xb7, g: 0x7e, b: 0xe0},
cyan: Rgb {r: 0x54, g: 0xce, b: 0xd6}, cyan: Rgb {r: 0x54, g: 0xce, b: 0xd6},
white: Rgb {r: 0xff, g: 0xff, b: 0xff}, white: Rgb {r: 0xff, g: 0xff, b: 0xff},
} },
dim: None,
} }
} }
} }
/// The normal or bright colors section of config /// The 8-colors sections of config
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct AnsiColors { pub struct AnsiColors {
#[serde(deserialize_with = "rgb_from_hex")] #[serde(deserialize_with = "rgb_from_hex")]

View file

@ -71,6 +71,8 @@ pub mod tty;
pub mod util; pub mod util;
pub mod window; pub mod window;
use std::ops::Mul;
pub use grid::Grid; pub use grid::Grid;
pub use term::Term; pub use term::Term;
@ -81,6 +83,24 @@ pub struct Rgb {
pub b: u8, pub b: u8,
} }
// a multiply function for Rgb, as the default dim is just *2/3
impl Mul<f32> for Rgb {
type Output = Rgb;
fn mul(self, rhs: f32) -> Rgb {
let result = Rgb {
r: (self.r as f32 * rhs).max(0.0).min(255.0) as u8,
g: (self.g as f32 * rhs).max(0.0).min(255.0) as u8,
b: (self.b as f32 * rhs).max(0.0).min(255.0) as u8
};
trace!("Scaling RGB by {} from {:?} to {:?}", rhs, self, result);
result
}
}
#[cfg_attr(feature = "clippy", allow(too_many_arguments))] #[cfg_attr(feature = "clippy", allow(too_many_arguments))]
#[cfg_attr(feature = "clippy", allow(doc_markdown))] #[cfg_attr(feature = "clippy", allow(doc_markdown))]
pub mod gl { pub mod gl {

View file

@ -25,6 +25,8 @@ bitflags! {
const WRAPLINE = 0b00010000, const WRAPLINE = 0b00010000,
const WIDE_CHAR = 0b00100000, const WIDE_CHAR = 0b00100000,
const WIDE_CHAR_SPACER = 0b01000000, const WIDE_CHAR_SPACER = 0b01000000,
const DIM = 0b10000000,
const DIM_BOLD = 0b10000010,
} }
} }
@ -73,14 +75,21 @@ impl LineLength for grid::Row<Cell> {
} }
impl Cell { impl Cell {
#[inline]
pub fn bold(&self) -> bool { pub fn bold(&self) -> bool {
self.flags.contains(BOLD) self.flags.contains(BOLD)
} }
#[inline]
pub fn inverse(&self) -> bool { pub fn inverse(&self) -> bool {
self.flags.contains(INVERSE) self.flags.contains(INVERSE)
} }
#[inline]
pub fn dim(&self) -> bool {
self.flags.contains(DIM)
}
pub fn new(c: char, fg: Color, bg: Color) -> Cell { pub fn new(c: char, fg: Color, bg: Color) -> Cell {
Cell { Cell {
c: c.into(), c: c.into(),

View file

@ -7,11 +7,11 @@ use config::Colors;
/// List of indexed colors /// List of indexed colors
/// ///
/// The first 16 entries are the standard ansi named colors. Items 16..232 are /// The first 16 entries are the standard ansi named colors. Items 16..232 are
/// the color cube. Items 233..256 are the grayscale ramp. Finally, item 256 is /// the color cube. Items 233..256 are the grayscale ramp. Item 256 is
/// the configured foreground color, item 257 is the configured background /// the configured foreground color, item 257 is the configured background
/// color, item 258 is the cursor foreground color, item 259 is the cursor /// color, item 258 is the cursor foreground color, item 259 is the cursor
/// background color. /// background color. Following that are 8 positions for dim colors.
pub struct List([Rgb; 260]); pub struct List([Rgb; 268]);
impl<'a> From<&'a Colors> for List { impl<'a> From<&'a Colors> for List {
fn from(colors: &Colors) -> List { fn from(colors: &Colors) -> List {
@ -55,6 +55,32 @@ impl List {
// Foreground and background for custom cursor colors // Foreground and background for custom cursor colors
self[ansi::NamedColor::CursorText] = colors.cursor.text; self[ansi::NamedColor::CursorText] = colors.cursor.text;
self[ansi::NamedColor::Cursor] = colors.cursor.cursor; self[ansi::NamedColor::Cursor] = colors.cursor.cursor;
// Dims
match colors.dim {
Some(ref dim) => {
trace!("Using config-provided dim colors");
self[ansi::NamedColor::DimBlack] = dim.black;
self[ansi::NamedColor::DimRed] = dim.red;
self[ansi::NamedColor::DimGreen] = dim.green;
self[ansi::NamedColor::DimYellow] = dim.yellow;
self[ansi::NamedColor::DimBlue] = dim.blue;
self[ansi::NamedColor::DimMagenta] = dim.magenta;
self[ansi::NamedColor::DimCyan] = dim.cyan;
self[ansi::NamedColor::DimWhite] = dim.white;
}
None => {
trace!("Deriving dim colors from normal colors");
self[ansi::NamedColor::DimBlack] = colors.normal.black * 0.66;
self[ansi::NamedColor::DimRed] = colors.normal.red * 0.66;
self[ansi::NamedColor::DimGreen] = colors.normal.green * 0.66;
self[ansi::NamedColor::DimYellow] = colors.normal.yellow * 0.66;
self[ansi::NamedColor::DimBlue] = colors.normal.blue * 0.66;
self[ansi::NamedColor::DimMagenta] = colors.normal.magenta * 0.66;
self[ansi::NamedColor::DimCyan] = colors.normal.cyan * 0.66;
self[ansi::NamedColor::DimWhite] = colors.normal.white * 0.66;
}
}
} }
fn fill_cube(&mut self) { fn fill_cube(&mut self) {

View file

@ -268,23 +268,30 @@ impl<'a> RenderableCellsIter<'a> {
} }
fn compute_fg_rgb(&self, fg: &Color, cell: &Cell) -> Rgb { fn compute_fg_rgb(&self, fg: &Color, cell: &Cell) -> Rgb {
use self::cell::DIM_BOLD;
match *fg { match *fg {
Color::Spec(rgb) => rgb, Color::Spec(rgb) => rgb,
Color::Named(ansi) => { Color::Named(ansi) => {
if self.config.draw_bold_text_with_bright_colors() && cell.bold() { match (self.config.draw_bold_text_with_bright_colors(), cell.flags & DIM_BOLD) {
self.colors[ansi.to_bright()] // Draw bold text in bright colors *and* contains bold flag.
} else { (true, self::cell::DIM_BOLD) |
self.colors[ansi] (true, self::cell::BOLD) => self.colors[ansi.to_bright()],
// Cell is marked as dim and not bold
(_, self::cell::DIM) => self.colors[ansi.to_dim()],
// None of the above, keep original color.
_ => self.colors[ansi]
} }
}, },
Color::Indexed(idx) => { Color::Indexed(idx) => {
let idx = if self.config.draw_bold_text_with_bright_colors() let idx = match (
&& cell.bold() self.config.draw_bold_text_with_bright_colors(),
&& idx < 8 cell.flags & DIM_BOLD,
{
idx + 8
} else {
idx idx
) {
(true, self::cell::BOLD, 0...7) => idx as usize + 8,
(false, self::cell::DIM, 8...15) => idx as usize - 8,
(false, self::cell::DIM, 0...7) => idx as usize + 260,
_ => idx as usize,
}; };
self.colors[idx] self.colors[idx]
@ -1696,7 +1703,8 @@ impl ansi::Handler for Term {
Attr::Reverse => self.cursor.template.flags.insert(cell::INVERSE), Attr::Reverse => self.cursor.template.flags.insert(cell::INVERSE),
Attr::CancelReverse => self.cursor.template.flags.remove(cell::INVERSE), Attr::CancelReverse => self.cursor.template.flags.remove(cell::INVERSE),
Attr::Bold => self.cursor.template.flags.insert(cell::BOLD), Attr::Bold => self.cursor.template.flags.insert(cell::BOLD),
Attr::CancelBoldDim => self.cursor.template.flags.remove(cell::BOLD), Attr::Dim => self.cursor.template.flags.insert(cell::DIM),
Attr::CancelBoldDim => self.cursor.template.flags.remove(cell::BOLD | cell::DIM),
Attr::Italic => self.cursor.template.flags.insert(cell::ITALIC), Attr::Italic => self.cursor.template.flags.insert(cell::ITALIC),
Attr::CancelItalic => self.cursor.template.flags.remove(cell::ITALIC), Attr::CancelItalic => self.cursor.template.flags.remove(cell::ITALIC),
Attr::Underscore => self.cursor.template.flags.insert(cell::UNDERLINE), Attr::Underscore => self.cursor.template.flags.insert(cell::UNDERLINE),