diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.rs | 186 | ||||
-rw-r--r-- | src/display.rs | 20 | ||||
-rw-r--r-- | src/grid.rs | 15 | ||||
-rw-r--r-- | src/renderer/mod.rs | 106 | ||||
-rw-r--r-- | src/term/color.rs | 147 | ||||
-rw-r--r-- | src/term/mod.rs | 105 |
6 files changed, 289 insertions, 290 deletions
diff --git a/src/config.rs b/src/config.rs index 6daa0eb1..fafb61c2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,6 @@ use std::borrow::Cow; use std::{env, fmt}; use std::fs::{self, File}; use std::io::{self, Read, Write}; -use std::ops::{Index, IndexMut}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::mpsc; @@ -24,8 +23,6 @@ use notify::{Watcher as WatcherApi, RecommendedWatcher as FileWatcher, op}; use input::{Action, Binding, MouseBinding, KeyBinding}; use index::{Line, Column}; -use ansi; - /// Function that returns true for serde default fn true_bool() -> bool { true @@ -77,148 +74,6 @@ impl Default for Mouse { } } -/// 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 ColorList([Rgb; 260]); - -impl fmt::Debug for ColorList { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("ColorList[..]") - } -} - -impl Default for ColorList { - fn default() -> ColorList { - ColorList::from(Colors::default()) - } -} - -impl From<Colors> for ColorList { - fn from(colors: Colors) -> ColorList { - // Type inference fails without this annotation - let mut list: ColorList = unsafe { ::std::mem::uninitialized() }; - - list.fill_named(&colors); - list.fill_cube(); - list.fill_gray_ramp(); - - list - } -} - -impl ColorList { - 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 = 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 = 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 Index<ansi::NamedColor> for ColorList { - type Output = Rgb; - - #[inline] - fn index(&self, idx: ansi::NamedColor) -> &Self::Output { - &self.0[idx as usize] - } -} - -impl IndexMut<ansi::NamedColor> for ColorList { - #[inline] - fn index_mut(&mut self, idx: ansi::NamedColor) -> &mut Self::Output { - &mut self.0[idx as usize] - } -} - -impl Index<usize> for ColorList { - type Output = Rgb; - - #[inline] - fn index(&self, idx: usize) -> &Self::Output { - &self.0[idx] - } -} - -impl Index<u8> for ColorList { - type Output = Rgb; - - #[inline] - fn index(&self, idx: u8) -> &Self::Output { - &self.0[idx as usize] - } -} - -impl IndexMut<usize> for ColorList { - #[inline] - fn index_mut(&mut self, idx: usize) -> &mut Self::Output { - &mut self.0[idx] - } -} - /// VisulBellAnimations are modeled after a subset of CSS transitions and Robert /// Penner's Easing Functions. #[derive(Clone, Copy, Debug, Deserialize)] @@ -341,7 +196,7 @@ pub struct Config { draw_bold_text_with_bright_colors: bool, #[serde(default)] - colors: ColorList, + colors: Colors, /// Keybindings #[serde(default="default_key_bindings")] @@ -789,15 +644,6 @@ impl de::Deserialize for RawBinding { } } -impl de::Deserialize for ColorList { - fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> - where D: de::Deserializer - { - let named_colors = Colors::deserialize(deserializer)?; - Ok(ColorList::from(named_colors)) - } -} - impl de::Deserialize for MouseBinding { fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where D: de::Deserializer @@ -836,11 +682,11 @@ pub enum Error { #[derive(Debug, Deserialize)] pub struct Colors { - primary: PrimaryColors, + pub primary: PrimaryColors, #[serde(default="default_cursor_colors")] - cursor: PrimaryColors, - normal: AnsiColors, - bright: AnsiColors, + pub cursor: PrimaryColors, + pub normal: AnsiColors, + pub bright: AnsiColors, } fn default_cursor_colors() -> PrimaryColors { @@ -853,9 +699,9 @@ fn default_cursor_colors() -> PrimaryColors { #[derive(Debug, Deserialize)] pub struct PrimaryColors { #[serde(deserialize_with = "rgb_from_hex")] - background: Rgb, + pub background: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - foreground: Rgb, + pub foreground: Rgb, } impl Default for Colors { @@ -894,21 +740,21 @@ impl Default for Colors { #[derive(Debug, Deserialize)] pub struct AnsiColors { #[serde(deserialize_with = "rgb_from_hex")] - black: Rgb, + pub black: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - red: Rgb, + pub red: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - green: Rgb, + pub green: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - yellow: Rgb, + pub yellow: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - blue: Rgb, + pub blue: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - magenta: Rgb, + pub magenta: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - cyan: Rgb, + pub cyan: Rgb, #[serde(deserialize_with = "rgb_from_hex")] - white: Rgb, + pub white: Rgb, } /// Deserialize an Rgb from a hex string @@ -1076,7 +922,7 @@ impl Config { /// /// The ordering returned here is expected by the terminal. Colors are simply indexed in this /// array for performance. - pub fn color_list(&self) -> &ColorList { + pub fn colors(&self) -> &Colors { &self.colors } diff --git a/src/display.rs b/src/display.rs index 9bfe7339..5946b33b 100644 --- a/src/display.rs +++ b/src/display.rs @@ -19,7 +19,6 @@ use std::sync::mpsc; use parking_lot::{MutexGuard}; use Rgb; -use ansi::Color; use cli; use config::Config; use font::{self, Rasterize}; @@ -120,7 +119,6 @@ impl Display { } pub fn update_config(&mut self, config: &Config) { - self.renderer.update_config(config); self.render_timer = config.render_timer(); } @@ -151,7 +149,7 @@ impl Display { let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr, config.use_thin_strokes())?; // Create renderer - let mut renderer = QuadRenderer::new(config, size)?; + let mut renderer = QuadRenderer::new(size)?; // Initialize glyph cache let glyph_cache = { @@ -280,6 +278,9 @@ impl Display { { let glyph_cache = &mut self.glyph_cache; + let size_info = *terminal.size_info(); + let visual_bell_intensity = terminal.visual_bell.intensity(); + // Draw grid { let _sampler = self.meter.sampler(); @@ -289,23 +290,20 @@ impl Display { // // TODO I wonder if the renderable cells iter could avoid the // mutable borrow - let size_info = *terminal.size_info(); - self.renderer.with_api(config, &size_info, |mut api| { - api.set_visual_bell(terminal.visual_bell.intensity() as f32); - + self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| { api.clear(); // Draw the grid - api.render_cells(terminal.renderable_cells(selection), glyph_cache); + api.render_cells(terminal.renderable_cells(config, selection), glyph_cache); }); } // Draw render timer if self.render_timer { let timing = format!("{:.3} usec", self.meter.average()); - let color = Color::Spec(Rgb { r: 0xd5, g: 0x4e, b: 0x53 }); - self.renderer.with_api(config, terminal.size_info(), |mut api| { - api.render_string(&timing[..], glyph_cache, &color); + let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 }; + self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| { + api.render_string(&timing[..], glyph_cache, color); }); } } diff --git a/src/grid.rs b/src/grid.rs index c886807b..1c5b94c4 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -38,6 +38,21 @@ pub trait BidirectionalIterator: Iterator { fn prev(&mut self) -> Option<Self::Item>; } +pub struct Indexed<T> { + pub line: Line, + pub column: Column, + pub inner: T +} + +impl<T> Deref for Indexed<T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.inner + } +} + /// Represents the terminal display contents #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)] pub struct Grid<T> { diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 2d466f79..585bea10 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -28,9 +28,8 @@ use gl; use index::{Line, Column, RangeInclusive}; use notify::{Watcher as WatcherApi, RecommendedWatcher as Watcher, op}; -use ansi::{Color, NamedColor}; -use config::{Config, ColorList}; -use term::{self, cell, IndexedCell, Cell}; +use config::Config; +use term::{self, cell, RenderableCell}; use window::{Size, Pixels}; use Rgb; @@ -313,7 +312,6 @@ pub struct QuadRenderer { atlas: Vec<Atlas>, active_tex: GLuint, batch: Batch, - draw_bold_text_with_bright_colors: bool, rx: mpsc::Receiver<Msg>, } @@ -323,8 +321,8 @@ pub struct RenderApi<'a> { batch: &'a mut Batch, atlas: &'a mut Vec<Atlas>, program: &'a mut ShaderProgram, - colors: &'a ColorList, - visual_bell: f32, + config: &'a Config, + visual_bell_intensity: f32 } #[derive(Debug)] @@ -343,58 +341,26 @@ pub struct PackedVertex { pub struct Batch { tex: GLuint, instances: Vec<InstanceData>, - draw_bold_text_with_bright_colors: bool, } impl Batch { #[inline] - pub fn new(config: &Config) -> Batch { + pub fn new() -> Batch { Batch { tex: 0, instances: Vec::with_capacity(BATCH_MAX), - draw_bold_text_with_bright_colors: config.draw_bold_text_with_bright_colors(), } } pub fn add_item( &mut self, - cell: &IndexedCell, + cell: &RenderableCell, glyph: &Glyph, - colors: &ColorList ) { if self.is_empty() { self.tex = glyph.tex_id; } - let fg = match cell.fg { - Color::Spec(rgb) => rgb, - Color::Named(ansi) => { - if self.draw_bold_text_with_bright_colors && cell.bold() { - colors[ansi.to_bright()] - } else { - colors[ansi] - } - }, - Color::Indexed(idx) => { - let idx = if self.draw_bold_text_with_bright_colors - && cell.bold() - && idx < 8 - { - idx + 8 - } else { - idx - }; - - colors[idx] - } - }; - - let bg = match cell.bg { - Color::Spec(rgb) => rgb, - Color::Named(ansi) => colors[ansi], - Color::Indexed(idx) => colors[idx], - }; - self.instances.push(InstanceData { col: cell.column.0 as f32, row: cell.line.0 as f32, @@ -409,13 +375,13 @@ impl Batch { uv_width: glyph.uv_width, uv_height: glyph.uv_height, - r: fg.r as f32, - g: fg.g as f32, - b: fg.b as f32, + r: cell.fg.r as f32, + g: cell.fg.g as f32, + b: cell.fg.b as f32, - bg_r: bg.r as f32, - bg_g: bg.g as f32, - bg_b: bg.b as f32, + bg_r: cell.bg.r as f32, + bg_g: cell.bg.g as f32, + bg_b: cell.bg.b as f32, }); } @@ -456,7 +422,7 @@ const ATLAS_SIZE: i32 = 1024; impl QuadRenderer { // TODO should probably hand this a transform instead of width/height - pub fn new(config: &Config, size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> { + pub fn new(size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> { let program = ShaderProgram::new(size)?; let mut vao: GLuint = 0; @@ -600,9 +566,8 @@ impl QuadRenderer { vbo_instance: vbo_instance, atlas: Vec::new(), active_tex: 0, - batch: Batch::new(config), + batch: Batch::new(), rx: msg_rx, - draw_bold_text_with_bright_colors: config.draw_bold_text_with_bright_colors(), }; let atlas = Atlas::new(ATLAS_SIZE); @@ -611,14 +576,11 @@ impl QuadRenderer { Ok(renderer) } - pub fn update_config(&mut self, config: &Config) { - self.batch.draw_bold_text_with_bright_colors = config.draw_bold_text_with_bright_colors(); - } - pub fn with_api<F, T>( &mut self, config: &Config, props: &term::SizeInfo, + visual_bell_intensity: f64, func: F ) -> T where F: FnOnce(RenderApi) -> T @@ -637,6 +599,7 @@ impl QuadRenderer { unsafe { self.program.activate(); self.program.set_term_uniforms(props); + self.program.set_visual_bell(visual_bell_intensity as _); gl::BindVertexArray(self.vao); gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.ebo); @@ -649,8 +612,8 @@ impl QuadRenderer { batch: &mut self.batch, atlas: &mut self.atlas, program: &mut self.program, - colors: config.color_list(), - visual_bell: 0.0, + visual_bell_intensity: visual_bell_intensity as _, + config: config, }); unsafe { @@ -713,18 +676,13 @@ impl QuadRenderer { } impl<'a> RenderApi<'a> { - pub fn set_visual_bell(&mut self, visual_bell: f32) { - self.visual_bell = visual_bell; - self.program.set_visual_bell(visual_bell); - } - pub fn clear(&self) { - let color = self.colors[NamedColor::Background]; + let color = self.config.colors().primary.background; unsafe { gl::ClearColor( - (self.visual_bell + color.r as f32 / 255.0).min(1.0), - (self.visual_bell + color.g as f32 / 255.0).min(1.0), - (self.visual_bell + color.b as f32 / 255.0).min(1.0), + (self.visual_bell_intensity + color.r as f32 / 255.0).min(1.0), + (self.visual_bell_intensity + color.g as f32 / 255.0).min(1.0), + (self.visual_bell_intensity + color.b as f32 / 255.0).min(1.0), 1.0 ); gl::Clear(gl::COLOR_BUFFER_BIT); @@ -764,22 +722,20 @@ impl<'a> RenderApi<'a> { &mut self, string: &str, glyph_cache: &mut GlyphCache, - color: &Color, + color: Rgb, ) { let line = Line(23); let col = Column(0); let cells = string.chars() .enumerate() - .map(|(i, c)| IndexedCell { + .map(|(i, c)| RenderableCell { line: line, column: col + i, - inner: Cell { - c: c, - bg: *color, - fg: Color::Spec(Rgb { r: 0, g: 0, b: 0}), - flags: cell::Flags::empty(), - } + c: c, + bg: color, + fg: Rgb { r: 0, g: 0, b: 0 }, + flags: cell::Flags::empty(), }) .collect::<Vec<_>>(); @@ -787,13 +743,13 @@ impl<'a> RenderApi<'a> { } #[inline] - fn add_render_item(&mut self, cell: &IndexedCell, glyph: &Glyph) { + fn add_render_item(&mut self, cell: &RenderableCell, glyph: &Glyph) { // Flush batch if tex changing if !self.batch.is_empty() && self.batch.tex != glyph.tex_id { self.render_batch(); } - self.batch.add_item(cell, glyph, self.colors); + self.batch.add_item(cell, glyph); // Render batch and clear if it's full if self.batch.full() { @@ -806,7 +762,7 @@ impl<'a> RenderApi<'a> { cells: I, glyph_cache: &mut GlyphCache ) - where I: Iterator<Item=::term::IndexedCell> + where I: Iterator<Item=RenderableCell> { for cell in cells { // Get font key for cell 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 ) } |