diff options
author | Joe Wilm <joe@jwilm.com> | 2017-02-11 12:49:40 -0800 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-02-11 14:18:05 -0800 |
commit | 908ea5543a40b772d2336e2ce981aae61dc6b2d7 (patch) | |
tree | 65c265378a75e214a0bc05f74de8c50156cc8dee /src/term | |
parent | d2e8a0cd103a4923d296136ac499ce026fdd625a (diff) | |
download | alacritty-908ea5543a40b772d2336e2ce981aae61dc6b2d7.tar.gz alacritty-908ea5543a40b772d2336e2ce981aae61dc6b2d7.zip |
Move color list to Term struct
The color list needs to be updated by the parser, and this isn't
possible if it's on the config. This change makes sense semantically as
well since it's really part of the terminal state.
This is in preparation for OSC color parsing.
Diffstat (limited to 'src/term')
-rw-r--r-- | src/term/color.rs | 147 | ||||
-rw-r--r-- | src/term/mod.rs | 105 |
2 files changed, 218 insertions, 34 deletions
diff --git a/src/term/color.rs b/src/term/color.rs new file mode 100644 index 00000000..8e15ad41 --- /dev/null +++ b/src/term/color.rs @@ -0,0 +1,147 @@ +use std::ops::{Index, IndexMut}; +use std::fmt; + +use {Rgb, ansi}; +use config::Colors; + +/// List of indexed colors +/// +/// 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 configured foreground color, item 257 is the configured background +/// color, item 258 is the cursor foreground color, item 259 is the cursor +/// background color. +pub struct List([Rgb; 260]); + +impl<'a> From<&'a Colors> for List { + fn from(colors: &Colors) -> List { + // Type inference fails without this annotation + let mut list: List = unsafe { ::std::mem::uninitialized() }; + + list.fill_named(&colors); + list.fill_cube(); + list.fill_gray_ramp(); + + list + } +} + +impl List { + pub fn fill_named(&mut self, colors: &Colors) { + // Normals + self[ansi::NamedColor::Black] = colors.normal.black; + self[ansi::NamedColor::Red] = colors.normal.red; + self[ansi::NamedColor::Green] = colors.normal.green; + self[ansi::NamedColor::Yellow] = colors.normal.yellow; + self[ansi::NamedColor::Blue] = colors.normal.blue; + self[ansi::NamedColor::Magenta] = colors.normal.magenta; + self[ansi::NamedColor::Cyan] = colors.normal.cyan; + self[ansi::NamedColor::White] = colors.normal.white; + + // Brights + self[ansi::NamedColor::BrightBlack] = colors.bright.black; + self[ansi::NamedColor::BrightRed] = colors.bright.red; + self[ansi::NamedColor::BrightGreen] = colors.bright.green; + self[ansi::NamedColor::BrightYellow] = colors.bright.yellow; + self[ansi::NamedColor::BrightBlue] = colors.bright.blue; + self[ansi::NamedColor::BrightMagenta] = colors.bright.magenta; + self[ansi::NamedColor::BrightCyan] = colors.bright.cyan; + self[ansi::NamedColor::BrightWhite] = colors.bright.white; + + // Foreground and background + self[ansi::NamedColor::Foreground] = colors.primary.foreground; + self[ansi::NamedColor::Background] = colors.primary.background; + + // Foreground and background for custom cursor colors + self[ansi::NamedColor::CursorForeground] = colors.cursor.foreground; + self[ansi::NamedColor::CursorBackground] = colors.cursor.background; + } + + fn fill_cube(&mut self) { + let mut index: usize = 16; + // Build colors + for r in 0..6 { + for g in 0..6 { + for b in 0..6 { + self[index] = Rgb { r: if r == 0 { 0 } else { r * 40 + 55 }, + b: if b == 0 { 0 } else { b * 40 + 55 }, + g: if g == 0 { 0 } else { g * 40 + 55 }, + }; + index += 1; + } + } + } + + debug_assert!(index == 232); + } + + fn fill_gray_ramp(&mut self) { + let mut index: usize = 232; + + for i in 0..24 { + let value = i * 10 + 8; + self[index] = Rgb { + r: value, + g: value, + b: value + }; + index += 1; + } + + debug_assert!(index == 256); + } +} + +impl fmt::Debug for List { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("List[..]") + } +} + +impl Index<ansi::NamedColor> for List { + type Output = Rgb; + + #[inline] + fn index(&self, idx: ansi::NamedColor) -> &Self::Output { + &self.0[idx as usize] + } +} + +impl IndexMut<ansi::NamedColor> for List { + #[inline] + fn index_mut(&mut self, idx: ansi::NamedColor) -> &mut Self::Output { + &mut self.0[idx as usize] + } +} + +impl Index<usize> for List { + type Output = Rgb; + + #[inline] + fn index(&self, idx: usize) -> &Self::Output { + &self.0[idx] + } +} + +impl IndexMut<usize> for List { + #[inline] + fn index_mut(&mut self, idx: usize) -> &mut Self::Output { + &mut self.0[idx] + } +} + +impl Index<u8> for List { + type Output = Rgb; + + #[inline] + fn index(&self, idx: u8) -> &Self::Output { + &self.0[idx as usize] + } +} + +impl IndexMut<u8> for List { + #[inline] + fn index_mut(&mut self, idx: u8) -> &mut Self::Output { + &mut self.0[idx as usize] + } +} diff --git a/src/term/mod.rs b/src/term/mod.rs index 26ed2fad..3a86f887 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -14,19 +14,21 @@ // //! Exports the `Term` type which is a high-level API for the Grid use std::mem; -use std::ops::{Deref, Range, Index, IndexMut}; +use std::ops::{Range, Index, IndexMut}; use std::ptr; use std::cmp::min; use std::io; use std::time::{Duration, Instant}; use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset}; -use grid::{BidirectionalIterator, Grid, ClearRegion, ToRange}; +use grid::{BidirectionalIterator, Grid, ClearRegion, ToRange, Indexed}; use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive, Side}; use selection::{Span, Selection}; use config::{Config, VisualBellAnimation}; +use Rgb; pub mod cell; +pub mod color; pub use self::cell::Cell; use self::cell::LineLength; @@ -44,8 +46,10 @@ pub struct RenderableCellsIter<'a> { mode: TermMode, line: Line, column: Column, + config: &'a Config, + colors: &'a color::List, selection: Option<RangeInclusive<index::Linear>>, - cursor_original: Option<IndexedCell> + cursor_original: Option<Indexed<Cell>> } impl<'a> RenderableCellsIter<'a> { @@ -56,9 +60,10 @@ impl<'a> RenderableCellsIter<'a> { fn new<'b>( grid: &'b mut Grid<Cell>, cursor: &'b Point, + colors: &'b color::List, mode: TermMode, + config: &'b Config, selection: &Selection, - custom_cursor_colors: bool, ) -> RenderableCellsIter<'b> { let selection = selection.span() .map(|span| span.to_range(grid.num_cols())); @@ -70,18 +75,21 @@ impl<'a> RenderableCellsIter<'a> { line: Line(0), column: Column(0), selection: selection, + config: config, + colors: colors, cursor_original: None, - }.initialize(custom_cursor_colors) + }.initialize() } - fn initialize(mut self, custom_cursor_colors: bool) -> Self { + fn initialize(mut self) -> Self { if self.cursor_is_visible() { - self.cursor_original = Some(IndexedCell { + self.cursor_original = Some(Indexed { line: self.cursor.line, column: self.cursor.col, inner: self.grid[self.cursor] }); - if custom_cursor_colors { + + if self.config.custom_cursor_colors() { let cell = &mut self.grid[self.cursor]; cell.fg = Color::Named(NamedColor::CursorForeground); cell.bg = Color::Named(NamedColor::CursorBackground); @@ -112,23 +120,17 @@ impl<'a> Drop for RenderableCellsIter<'a> { } } -pub struct IndexedCell { +pub struct RenderableCell { pub line: Line, pub column: Column, - pub inner: Cell -} - -impl Deref for IndexedCell { - type Target = Cell; - - #[inline] - fn deref(&self) -> &Cell { - &self.inner - } + pub c: char, + pub fg: Rgb, + pub bg: Rgb, + pub flags: cell::Flags, } impl<'a> Iterator for RenderableCellsIter<'a> { - type Item = IndexedCell; + type Item = RenderableCell; /// Gets the next renderable cell /// @@ -159,22 +161,50 @@ impl<'a> Iterator for RenderableCellsIter<'a> { // fg, bg are dependent on INVERSE flag let invert = cell.flags.contains(cell::INVERSE) || selected; - let (fg, bg) = if invert { (&cell.bg, &cell.fg) } else { (&cell.fg, &cell.bg) }; - return Some(IndexedCell { + // Get Rgb value for foreground + let fg = match *fg { + Color::Spec(rgb) => rgb, + Color::Named(ansi) => { + if self.config.draw_bold_text_with_bright_colors() && cell.bold() { + self.colors[ansi.to_bright()] + } else { + self.colors[ansi] + } + }, + Color::Indexed(idx) => { + let idx = if self.config.draw_bold_text_with_bright_colors() + && cell.bold() + && idx < 8 + { + idx + 8 + } else { + idx + }; + + self.colors[idx] + } + }; + + // Get Rgb value for background + let bg = match *bg { + Color::Spec(rgb) => rgb, + Color::Named(ansi) => self.colors[ansi], + Color::Indexed(idx) => self.colors[idx], + }; + + return Some(RenderableCell { line: line, column: column, - inner: Cell { - flags: cell.flags, - c: cell.c, - fg: *fg, - bg: *bg, - } + flags: cell.flags, + c: cell.c, + fg: fg, + bg: bg, }) } @@ -461,8 +491,6 @@ pub struct Term { pub visual_bell: VisualBell, - custom_cursor_colors: bool, - /// Saved cursor from main grid cursor_save: Cursor, @@ -470,6 +498,9 @@ pub struct Term { cursor_save_alt: Cursor, semantic_escape_chars: String, + + /// Colors used for rendering + colors: color::List, } /// Terminal size info @@ -514,6 +545,7 @@ impl SizeInfo { } } + impl Term { #[inline] pub fn get_next_title(&mut self) -> Option<String> { @@ -554,14 +586,14 @@ impl Term { scroll_region: scroll_region, size_info: size, empty_cell: template, - custom_cursor_colors: config.custom_cursor_colors(), + colors: color::List::from(config.colors()), semantic_escape_chars: config.selection().semantic_escape_chars.clone(), } } pub fn update_config(&mut self, config: &Config) { - self.custom_cursor_colors = config.custom_cursor_colors(); self.semantic_escape_chars = config.selection().semantic_escape_chars.clone(); + self.colors.fill_named(config.colors()); self.visual_bell.update_config(config); } @@ -772,13 +804,18 @@ impl Term { /// A renderable cell is any cell which has content other than the default /// background color. Cells with an alternate background color are /// considered renderable as are cells with any text content. - pub fn renderable_cells(&mut self, selection: &Selection) -> RenderableCellsIter { + pub fn renderable_cells<'b>( + &'b mut self, + config: &'b Config, + selection: &'b Selection + ) -> RenderableCellsIter { RenderableCellsIter::new( &mut self.grid, &self.cursor.point, + &self.colors, self.mode, + config, selection, - self.custom_cursor_colors ) } |