aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs186
-rw-r--r--src/display.rs20
-rw-r--r--src/grid.rs15
-rw-r--r--src/renderer/mod.rs106
-rw-r--r--src/term/color.rs147
-rw-r--r--src/term/mod.rs105
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
)
}