diff options
Diffstat (limited to 'alacritty/src/display/mod.rs')
-rw-r--r-- | alacritty/src/display/mod.rs | 171 |
1 files changed, 165 insertions, 6 deletions
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 1fdc5ac1..5bd0a097 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -16,6 +16,7 @@ use glutin::window::CursorIcon; use glutin::Rect as DamageRect; use log::{debug, info}; use parking_lot::MutexGuard; +use serde::{Deserialize, Serialize}; use unicode_width::UnicodeWidthChar; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] use wayland_client::EventQueue; @@ -24,15 +25,13 @@ use crossfont::{self, Rasterize, Rasterizer}; use alacritty_terminal::ansi::NamedColor; use alacritty_terminal::config::MAX_SCROLLBACK_LINES; -use alacritty_terminal::event::{EventListener, OnResize}; -use alacritty_terminal::grid::Dimensions as _; +use alacritty_terminal::event::{EventListener, OnResize, WindowSize}; +use alacritty_terminal::grid::Dimensions as TermDimensions; use alacritty_terminal::index::{Column, Direction, Line, Point}; use alacritty_terminal::selection::{Selection, SelectionRange}; use alacritty_terminal::term::cell::Flags; use alacritty_terminal::term::color::Rgb; -use alacritty_terminal::term::{ - SizeInfo, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES, -}; +use alacritty_terminal::term::{Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES}; use crate::config::font::Font; #[cfg(not(windows))] @@ -135,6 +134,166 @@ impl From<glutin::ContextError> for Error { } } +/// Terminal size info. +#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)] +pub struct SizeInfo<T = f32> { + /// Terminal window width. + width: T, + + /// Terminal window height. + height: T, + + /// Width of individual cell. + cell_width: T, + + /// Height of individual cell. + cell_height: T, + + /// Horizontal window padding. + padding_x: T, + + /// Vertical window padding. + padding_y: T, + + /// Number of lines in the viewport. + screen_lines: usize, + + /// Number of columns in the viewport. + columns: usize, +} + +impl From<SizeInfo<f32>> for SizeInfo<u32> { + fn from(size_info: SizeInfo<f32>) -> Self { + Self { + width: size_info.width as u32, + height: size_info.height as u32, + cell_width: size_info.cell_width as u32, + cell_height: size_info.cell_height as u32, + padding_x: size_info.padding_x as u32, + padding_y: size_info.padding_y as u32, + screen_lines: size_info.screen_lines, + columns: size_info.screen_lines, + } + } +} + +impl From<SizeInfo<f32>> for WindowSize { + fn from(size_info: SizeInfo<f32>) -> Self { + Self { + num_cols: size_info.columns() as u16, + num_lines: size_info.screen_lines() as u16, + cell_width: size_info.cell_width() as u16, + cell_height: size_info.cell_width() as u16, + } + } +} + +impl<T: Clone + Copy> SizeInfo<T> { + #[inline] + pub fn width(&self) -> T { + self.width + } + + #[inline] + pub fn height(&self) -> T { + self.height + } + + #[inline] + pub fn cell_width(&self) -> T { + self.cell_width + } + + #[inline] + pub fn cell_height(&self) -> T { + self.cell_height + } + + #[inline] + pub fn padding_x(&self) -> T { + self.padding_x + } + + #[inline] + pub fn padding_y(&self) -> T { + self.padding_y + } +} + +impl SizeInfo<f32> { + #[allow(clippy::too_many_arguments)] + pub fn new( + width: f32, + height: f32, + cell_width: f32, + cell_height: f32, + mut padding_x: f32, + mut padding_y: f32, + dynamic_padding: bool, + ) -> SizeInfo { + if dynamic_padding { + padding_x = Self::dynamic_padding(padding_x.floor(), width, cell_width); + padding_y = Self::dynamic_padding(padding_y.floor(), height, cell_height); + } + + let lines = (height - 2. * padding_y) / cell_height; + let screen_lines = cmp::max(lines as usize, MIN_SCREEN_LINES); + + let columns = (width - 2. * padding_x) / cell_width; + let columns = cmp::max(columns as usize, MIN_COLUMNS); + + SizeInfo { + width, + height, + cell_width, + cell_height, + padding_x: padding_x.floor(), + padding_y: padding_y.floor(), + screen_lines, + columns, + } + } + + #[inline] + pub fn reserve_lines(&mut self, count: usize) { + self.screen_lines = cmp::max(self.screen_lines.saturating_sub(count), MIN_SCREEN_LINES); + } + + /// Check if coordinates are inside the terminal grid. + /// + /// The padding, message bar or search are not counted as part of the grid. + #[inline] + pub fn contains_point(&self, x: usize, y: usize) -> bool { + x <= (self.padding_x + self.columns as f32 * self.cell_width) as usize + && x > self.padding_x as usize + && y <= (self.padding_y + self.screen_lines as f32 * self.cell_height) as usize + && y > self.padding_y as usize + } + + /// Calculate padding to spread it evenly around the terminal content. + #[inline] + fn dynamic_padding(padding: f32, dimension: f32, cell_dimension: f32) -> f32 { + padding + ((dimension - 2. * padding) % cell_dimension) / 2. + } +} + +impl TermDimensions for SizeInfo { + #[inline] + fn columns(&self) -> usize { + self.columns + } + + #[inline] + fn screen_lines(&self) -> usize { + self.screen_lines + } + + #[inline] + fn total_lines(&self) -> usize { + self.screen_lines() + } +} + #[derive(Default, Clone, Debug, PartialEq)] pub struct DisplayUpdate { pub dirty: bool, @@ -456,7 +615,7 @@ impl Display { self.size_info.reserve_lines(message_bar_lines + search_lines); // Resize PTY. - pty_resize_handle.on_resize(&self.size_info); + pty_resize_handle.on_resize(self.size_info.into()); // Resize terminal. terminal.resize(self.size_info); |