summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-02-11 12:49:40 -0800
committerJoe Wilm <jwilm@users.noreply.github.com>2017-02-11 14:18:05 -0800
commit908ea5543a40b772d2336e2ce981aae61dc6b2d7 (patch)
tree65c265378a75e214a0bc05f74de8c50156cc8dee /src
parentd2e8a0cd103a4923d296136ac499ce026fdd625a (diff)
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')
-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.