diff options
Diffstat (limited to 'alacritty_terminal/src/renderer/rects.rs')
-rw-r--r-- | alacritty_terminal/src/renderer/rects.rs | 91 |
1 files changed, 38 insertions, 53 deletions
diff --git a/alacritty_terminal/src/renderer/rects.rs b/alacritty_terminal/src/renderer/rects.rs index a2844c02..72139e3d 100644 --- a/alacritty_terminal/src/renderer/rects.rs +++ b/alacritty_terminal/src/renderer/rects.rs @@ -21,29 +21,31 @@ use crate::term::color::Rgb; use crate::term::{RenderableCell, SizeInfo}; #[derive(Debug, Copy, Clone)] -pub struct Rect<T> { - pub x: T, - pub y: T, - pub width: T, - pub height: T, +pub struct RenderRect { + pub x: f32, + pub y: f32, + pub width: f32, + pub height: f32, + pub color: Rgb, } -impl<T> Rect<T> { - pub fn new(x: T, y: T, width: T, height: T) -> Self { - Rect { x, y, width, height } +impl RenderRect { + pub fn new(x: f32, y: f32, width: f32, height: f32, color: Rgb) -> Self { + RenderRect { x, y, width, height, color } } } -struct Line { - rect: Rect<f32>, +struct RenderLine { start: Point, + end: Point, color: Rgb, } -impl Line { - /// Create a line that starts on the left of `cell` and is one cell wide - fn from_cell(cell: &RenderableCell, flag: Flags, metrics: &Metrics, size: &SizeInfo) -> Line { - let cell_x = cell.column.0 as f32 * size.cell_width; +impl RenderLine { + fn into_rect(self, flag: Flags, metrics: &Metrics, size: &SizeInfo) -> RenderRect { + let start_x = self.start.col.0 as f32 * size.cell_width; + let end_x = (self.end.col.0 + 1) as f32 * size.cell_width; + let width = end_x - start_x; let (position, mut height) = match flag { Flags::UNDERLINE => (metrics.underline_position, metrics.underline_thickness), @@ -54,48 +56,42 @@ impl Line { // Make sure lines are always visible height = height.max(1.); - let cell_bottom = (cell.line.0 as f32 + 1.) * size.cell_height; - let baseline = cell_bottom + metrics.descent; + let line_bottom = (self.start.line.0 as f32 + 1.) * size.cell_height; + let baseline = line_bottom + metrics.descent; let mut y = baseline - position - height / 2.; - let max_y = cell_bottom - height; + let max_y = line_bottom - height; if y > max_y { y = max_y; } - let rect = Rect::new(cell_x + size.padding_x, y + size.padding_y, size.cell_width, height); - - Self { start: cell.into(), color: cell.fg, rect } - } - - fn update_end(&mut self, end: Point, size: &SizeInfo) { - self.rect.width = (end.col + 1 - self.start.col).0 as f32 * size.cell_width; + RenderRect::new(start_x + size.padding_x, y + size.padding_y, width, height, self.color) } } -/// Rects for underline, strikeout and more. +/// Lines for underline and strikeout. #[derive(Default)] -pub struct Rects { - inner: HashMap<Flags, Vec<Line>>, +pub struct RenderLines { + inner: HashMap<Flags, Vec<RenderLine>>, } -impl Rects { +impl RenderLines { pub fn new() -> Self { Self::default() } - /// Convert the stored rects to rectangles for the renderer. - pub fn rects(&self) -> Vec<(Rect<f32>, Rgb)> { + pub fn into_rects(self, metrics: &Metrics, size: &SizeInfo) -> Vec<RenderRect> { self.inner - .iter() - .map(|(_, lines)| lines) + .into_iter() + .map(|(flag, lines)| -> Vec<RenderRect> { + lines.into_iter().map(|line| line.into_rect(flag, &metrics, &size)).collect() + }) .flatten() - .map(|line| (line.rect, line.color)) .collect() } /// Update the stored lines with the next cell info. - pub fn update_lines(&mut self, cell: &RenderableCell, size: &SizeInfo, metrics: &Metrics) { + pub fn update(&mut self, cell: &RenderableCell) { for flag in &[Flags::UNDERLINE, Flags::STRIKEOUT] { if !cell.flags.contains(*flag) { continue; @@ -103,35 +99,24 @@ impl Rects { // Check if there's an active line if let Some(line) = self.inner.get_mut(flag).and_then(|lines| lines.last_mut()) { - if cell.line == line.start.line && cell.fg == line.color { + if cell.line == line.start.line + && cell.fg == line.color + && cell.column == line.end.col + 1 + { // Update the length of the line - line.update_end(cell.into(), size); - + line.end = cell.into(); continue; } } // Start new line if there currently is none - let rect = Line::from_cell(cell, *flag, metrics, size); + let line = RenderLine { start: cell.into(), end: cell.into(), color: cell.fg }; match self.inner.get_mut(flag) { - Some(lines) => lines.push(rect), + Some(lines) => lines.push(line), None => { - self.inner.insert(*flag, vec![rect]); + self.inner.insert(*flag, vec![line]); }, } } } - - // Add a rectangle - pub fn push(&mut self, rect: Rect<f32>, color: Rgb) { - let line = Line { start: Point::default(), color, rect }; - - // Flag `HIDDEN` for hashmap index is arbitrary - match self.inner.get_mut(&Flags::HIDDEN) { - Some(lines) => lines.push(line), - None => { - self.inner.insert(Flags::HIDDEN, vec![line]); - }, - } - } } |