//! Convert a cursor into an iterator of rects. use alacritty_terminal::ansi::CursorShape; use alacritty_terminal::term::color::Rgb; use alacritty_terminal::term::SizeInfo; use crate::display::content::RenderableCursor; use crate::renderer::rects::RenderRect; use std::vec::Vec; /// Trait for conversion into the iterator. pub trait IntoRects { /// Consume the cursor for an iterator of rects. fn rects(self, size_info: &SizeInfo, thickness: f32) -> Vec; } impl IntoRects for RenderableCursor { fn rects(self, size_info: &SizeInfo, thickness: f32) -> Vec { let point = self.point(); let x = point.column.0 as f32 * size_info.cell_width() + size_info.padding_x(); let y = point.line as f32 * size_info.cell_height() + size_info.padding_y(); let mut width = size_info.cell_width(); let height = size_info.cell_height(); let thickness = (thickness * width as f32).round().max(1.); if self.is_wide() { width *= 2.; } let mut crosshairs = if self.cursor_crosshairs().enable { crosshair(x, y, size_info, self.cursor_crosshairs().color, self.cursor_crosshairs().opacity.as_f32()) } else { vec![] }; let mut shape = match self.shape() { CursorShape::Beam => beam(x, y, height, thickness, self.color()), CursorShape::Underline => underline(x, y, width, height, thickness, self.color()), CursorShape::HollowBlock => hollow(x, y, width, height, thickness, self.color()), CursorShape::Hidden => vec![], _ => vec![], }; shape.append(&mut crosshairs); shape } } fn crosshair(x: f32, y: f32, size_info: &SizeInfo, color: Rgb, opacity: f32) -> Vec { let width = size_info.cell_width(); let height = size_info.cell_height(); let yskip = 0.; let xskip = 0.; vec![ RenderRect::new(x, 0., width, y + size_info.cell_height(), color, opacity), RenderRect::new( x, y + size_info.cell_height() * (yskip + 1.), width, size_info.height(), color, opacity), RenderRect::new(0., y, x - (size_info.cell_width() * xskip), height, color, opacity), RenderRect::new(x + size_info.cell_width() * (xskip + 1.), y, size_info.width(), height, color, opacity) ] } /// Create an iterator yielding a single beam rect. fn beam(x: f32, y: f32, height: f32, thickness: f32, color: Rgb) -> Vec { vec![RenderRect::new(x, y, thickness, height, color, 1.)] } /// Create an iterator yielding a single underline rect. fn underline(x: f32, y: f32, width: f32, height: f32, thickness: f32, color: Rgb) -> Vec { let y = y + height - thickness; vec![RenderRect::new(x, y, width, thickness, color, 1.)] } /// Create an iterator yielding a rect for each side of the hollow block cursor. fn hollow(x: f32, y: f32, width: f32, height: f32, thickness: f32, color: Rgb) -> Vec { let top_line = RenderRect::new(x, y, width, thickness, color, 1.); let vertical_y = y + thickness; let vertical_height = height - 2. * thickness; let left_line = RenderRect::new(x, vertical_y, thickness, vertical_height, color, 1.); let bottom_y = y + height - thickness; let bottom_line = RenderRect::new(x, bottom_y, width, thickness, color, 1.); let right_x = x + width - thickness; let right_line = RenderRect::new(right_x, vertical_y, thickness, vertical_height, color, 1.); vec![top_line, bottom_line, left_line, right_line] }