diff --git a/src/color.rs b/src/color.rs index 9e19c2c..dc1871a 100644 --- a/src/color.rs +++ b/src/color.rs @@ -73,4 +73,12 @@ impl ColorModel { cell.attrs.background.as_ref().or(Some(&self.bg_color)) } } + + pub fn cell_bg<'a>(&'a self, cell: &'a Cell) -> Option<&'a Color> { + if !cell.attrs.reverse { + cell.attrs.background.as_ref() + } else { + cell.attrs.foreground.as_ref().or(Some(&self.fg_color)) + } + } } diff --git a/src/render/mod.rs b/src/render/mod.rs index dc2cd59..abd3904 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -12,7 +12,7 @@ use ui_model; pub fn render( ctx: &cairo::Context, - font_ctx: &context::Context, + font_ctx: &context::Context, ui_model: &ui_model::UiModel, color_model: &color::ColorModel, ) { @@ -23,7 +23,11 @@ pub fn render( ); ctx.paint(); - let &CellMetrics {line_height, char_width, ..} = font_ctx.cell_metrics(); + let &CellMetrics { + line_height, + char_width, + .. + } = font_ctx.cell_metrics(); let mut line_y = 0.0; let ascent = font_ctx.ascent(); @@ -31,21 +35,34 @@ pub fn render( let mut line_x = 0.0; for i in 0..line.line.len() { - let (bg, fg) = color_model.cell_colors(&line.line[i]); - - // FIXME: draw background for all item length - if let Some(bg) = bg { - ctx.set_source_rgb(bg.0, bg.1, bg.2); - ctx.rectangle(line_x, line_y, char_width, line_height); - ctx.fill(); - } if let Some(item) = line.item_line[i].as_ref() { + let (bg, fg) = color_model.cell_colors(&line.line[i]); + + if let Some(bg) = bg { + ctx.set_source_rgb(bg.0, bg.1, bg.2); + ctx.rectangle( + line_x, + line_y, + char_width * line.item_len(i) as f64, + line_height, + ); + ctx.fill(); + } + if let Some(ref glyphs) = item.glyphs { ctx.move_to(line_x, line_y + ascent); ctx.set_source_rgb(fg.0, fg.1, fg.2); ctx.show_glyph_string(item.font(), glyphs); } + + } else if !line.is_binded_to_item(i) { + let bg = color_model.cell_bg(&line.line[i]); + if let Some(bg) = bg { + ctx.set_source_rgb(bg.0, bg.1, bg.2); + ctx.rectangle(line_x, line_y, char_width, line_height); + ctx.fill(); + } } line_x += char_width; } diff --git a/src/ui_model/line.rs b/src/ui_model/line.rs index d7894c9..36b316e 100644 --- a/src/ui_model/line.rs +++ b/src/ui_model/line.rs @@ -53,7 +53,7 @@ pub struct Line { // [Item1, Item2, None, None, Item3] // Item2 take 3 cells and renders as one pub item_line: Box<[Option]>, - cell_to_item: Box<[i32]>, + pub cell_to_item: Box<[i32]>, pub dirty_line: bool, } @@ -219,6 +219,25 @@ impl Line { fn cell_to_item(&self, cell_idx: usize) -> i32 { self.cell_to_item[cell_idx] } + + pub fn item_len(&self, mut item_idx: usize) -> usize { + let mut len = 1; + item_idx += 1; + + while item_idx < self.item_line.len() && self.is_binded_to_item(item_idx) && + self.item_line[item_idx].is_none() + { + item_idx += 1; + len += 1; + } + + len + } + + #[inline] + pub fn is_binded_to_item(&self, cell_idx: usize) -> bool { + self.cell_to_item[cell_idx] >= 0 + } } impl Index for Line { @@ -304,6 +323,7 @@ struct StyleAttr<'c> { italic: bool, bold: bool, foreground: Option<&'c color::Color>, + background: Option<&'c color::Color>, empty: bool, start_idx: usize, @@ -316,6 +336,7 @@ impl<'c> StyleAttr<'c> { italic: false, bold: false, foreground: None, + background: None, empty: true, start_idx: 0, @@ -333,6 +354,7 @@ impl<'c> StyleAttr<'c> { italic: cell.attrs.italic, bold: cell.attrs.bold, foreground: color_model.cell_fg(cell), + background: color_model.cell_bg(cell), empty: false, start_idx, @@ -383,6 +405,14 @@ impl<'c> StyleAttr<'c> { pango::Attribute::new_foreground(r, g, b).unwrap(), ); } + + if let Some(bg) = self.background { + let (r, g, b) = bg.to_u16(); + self.insert_attr( + attr_list, + pango::Attribute::new_background(r, g, b).unwrap(), + ); + } } #[inline] @@ -396,7 +426,8 @@ impl<'c> StyleAttr<'c> { impl<'c> PartialEq for StyleAttr<'c> { fn eq(&self, other: &Self) -> bool { self.italic == other.italic && self.bold == other.bold && - self.foreground == other.foreground && self.empty == other.empty + self.foreground == other.foreground && self.empty == other.empty && + self.background == other.background } }