From bc319843621d24fce736db22c9c25083d30c1ef5 Mon Sep 17 00:00:00 2001 From: daa84 Date: Tue, 5 Sep 2017 17:03:20 +0300 Subject: [PATCH] Fix text coloring --- src/color.rs | 51 +++++++++++++++++++++++++++++++------------- src/shell.rs | 19 ++++++----------- src/ui_model/line.rs | 11 +++++++++- 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/color.rs b/src/color.rs index f7c868f..b2de55b 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,14 +1,15 @@ +use std; use gdk; use ui_model::Cell; -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Debug)] pub struct Color(pub f64, pub f64, pub f64); pub const COLOR_BLACK: Color = Color(0.0, 0.0, 0.0); pub const COLOR_WHITE: Color = Color(1.0, 1.0, 1.0); pub const COLOR_RED: Color = Color(1.0, 0.0, 0.0); -impl <'a> Into for &'a Color { +impl<'a> Into for &'a Color { fn into(self) -> gdk::RGBA { gdk::RGBA { red: self.0, @@ -19,6 +20,23 @@ impl <'a> Into for &'a Color { } } +impl Color { + pub fn from_indexed_color(indexed_color: u64) -> Color { + let r = ((indexed_color >> 16) & 0xff) as f64; + let g = ((indexed_color >> 8) & 0xff) as f64; + let b = (indexed_color & 0xff) as f64; + Color(r / 255.0, g / 255.0, b / 255.0) + } + + pub fn to_u16(&self) -> (u16, u16, u16) { + ( + (std::u16::MAX as f64 * self.0) as u16, + (std::u16::MAX as f64 * self.1) as u16, + (std::u16::MAX as f64 * self.2) as u16, + ) + } +} + pub struct ColorModel { pub bg_color: Color, pub fg_color: Color, @@ -27,7 +45,7 @@ pub struct ColorModel { impl ColorModel { pub fn new() -> Self { - ColorModel { + ColorModel { bg_color: COLOR_BLACK, fg_color: COLOR_WHITE, sp_color: COLOR_RED, @@ -35,21 +53,24 @@ impl ColorModel { } pub fn cell_colors<'a>(&'a self, cell: &'a Cell) -> (&'a Color, &'a Color) { - let bg = if let Some(ref bg) = cell.attrs.background { - bg + if !cell.attrs.reverse { + ( + cell.attrs.background.as_ref().unwrap_or(&self.bg_color), + cell.attrs.foreground.as_ref().unwrap_or(&self.fg_color), + ) } else { - &self.bg_color - }; - let fg = if let Some(ref fg) = cell.attrs.foreground { - fg - } else { - &self.fg_color - }; + ( + cell.attrs.foreground.as_ref().unwrap_or(&self.fg_color), + cell.attrs.background.as_ref().unwrap_or(&self.bg_color), + ) + } + } - if cell.attrs.reverse { - (fg, bg) + pub fn cell_fg<'a>(&'a self, cell: &'a Cell) -> Option<&'a Color> { + if !cell.attrs.reverse { + cell.attrs.foreground.as_ref() } else { - (bg, fg) + cell.attrs.background.as_ref().or(Some(&self.bg_color)) } } } diff --git a/src/shell.rs b/src/shell.rs index f6685f8..82712d0 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -985,13 +985,6 @@ fn request_window_resize(state: &mut State) { } } -fn split_color(indexed_color: u64) -> Color { - let r = ((indexed_color >> 16) & 0xff) as f64; - let g = ((indexed_color >> 8) & 0xff) as f64; - let b = (indexed_color & 0xff) as f64; - Color(r / 255.0, g / 255.0, b / 255.0) -} - fn try_nvim_resize(state: &Arc>) { let mut state_ref = state.borrow_mut(); @@ -1074,17 +1067,17 @@ impl RedrawEvents for State { match key { "foreground" => { if let Some(fg) = val.as_u64() { - model_attrs.foreground = Some(split_color(fg)); + model_attrs.foreground = Some(Color::from_indexed_color(fg)); } } "background" => { if let Some(bg) = val.as_u64() { - model_attrs.background = Some(split_color(bg)); + model_attrs.background = Some(Color::from_indexed_color(bg)); } } "special" => { if let Some(bg) = val.as_u64() { - model_attrs.special = Some(split_color(bg)); + model_attrs.special = Some(Color::from_indexed_color(bg)); } } "reverse" => model_attrs.reverse = true, @@ -1105,7 +1098,7 @@ impl RedrawEvents for State { fn on_update_bg(&mut self, bg: i64) -> RepaintMode { if bg >= 0 { - self.color_model.bg_color = split_color(bg as u64); + self.color_model.bg_color = Color::from_indexed_color(bg as u64); } else { self.color_model.bg_color = COLOR_BLACK; } @@ -1114,7 +1107,7 @@ impl RedrawEvents for State { fn on_update_fg(&mut self, fg: i64) -> RepaintMode { if fg >= 0 { - self.color_model.fg_color = split_color(fg as u64); + self.color_model.fg_color = Color::from_indexed_color(fg as u64); } else { self.color_model.fg_color = COLOR_WHITE; } @@ -1123,7 +1116,7 @@ impl RedrawEvents for State { fn on_update_sp(&mut self, sp: i64) -> RepaintMode { if sp >= 0 { - self.color_model.sp_color = split_color(sp as u64); + self.color_model.sp_color = Color::from_indexed_color(sp as u64); } else { self.color_model.sp_color = COLOR_RED; } diff --git a/src/ui_model/line.rs b/src/ui_model/line.rs index cff25bb..42a107c 100644 --- a/src/ui_model/line.rs +++ b/src/ui_model/line.rs @@ -314,12 +314,21 @@ fn insert_attrs( attr.set_end_index(end_idx); attr_list.insert(attr); } + if cell.attrs.bold { let mut attr = pango::Attribute::new_weight(pango::Weight::Bold).unwrap(); attr.set_start_index(start_idx); attr.set_end_index(end_idx); attr_list.insert(attr); } + + if let Some(fg) = color_model.cell_fg(cell) { + let (r, g, b) = fg.to_u16(); + let mut attr = pango::Attribute::new_foreground(r, g, b).unwrap(); + attr.set_start_index(start_idx); + attr.set_end_index(end_idx); + attr_list.insert(attr); + } } #[cfg(test)] @@ -333,7 +342,7 @@ mod tests { line[1].ch = 'b'; line[2].ch = 'c'; - let styled_line = StyledLine::from(&line); + let styled_line = StyledLine::from(&line, &color::ColorModel::new()); assert_eq!("abc", styled_line.line_str); assert_eq!(3, styled_line.cell_to_byte.len()); assert_eq!(0, styled_line.cell_to_byte[0]);