aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/display')
-rw-r--r--alacritty/src/display/color.rs199
-rw-r--r--alacritty/src/display/content.rs13
-rw-r--r--alacritty/src/display/cursor.rs4
-rw-r--r--alacritty/src/display/hint.rs2
-rw-r--r--alacritty/src/display/mod.rs21
5 files changed, 213 insertions, 26 deletions
diff --git a/alacritty/src/display/color.rs b/alacritty/src/display/color.rs
index f742ee84..669bf502 100644
--- a/alacritty/src/display/color.rs
+++ b/alacritty/src/display/color.rs
@@ -1,9 +1,14 @@
-use std::ops::{Index, IndexMut};
+use std::fmt::{self, Display, Formatter};
+use std::ops::{Add, Deref, Index, IndexMut, Mul};
+use std::str::FromStr;
use log::trace;
+use serde::de::{Error as SerdeError, Visitor};
+use serde::{Deserialize, Deserializer};
-use alacritty_terminal::ansi::NamedColor;
-use alacritty_terminal::term::color::{Rgb, COUNT};
+use alacritty_config_derive::SerdeReplace;
+use alacritty_terminal::term::color::COUNT;
+use alacritty_terminal::vte::ansi::{NamedColor, Rgb as VteRgb};
use crate::config::color::Colors;
@@ -165,3 +170,191 @@ impl IndexMut<NamedColor> for List {
&mut self.0[idx as usize]
}
}
+
+#[derive(SerdeReplace, Debug, Eq, PartialEq, Copy, Clone, Default)]
+pub struct Rgb(pub VteRgb);
+
+impl Rgb {
+ #[inline]
+ pub const fn new(r: u8, g: u8, b: u8) -> Self {
+ Self(VteRgb { r, g, b })
+ }
+
+ #[inline]
+ pub fn as_tuple(self) -> (u8, u8, u8) {
+ (self.0.r, self.0.g, self.0.b)
+ }
+}
+
+impl From<VteRgb> for Rgb {
+ fn from(value: VteRgb) -> Self {
+ Self(value)
+ }
+}
+
+impl Deref for Rgb {
+ type Target = VteRgb;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl Mul<f32> for Rgb {
+ type Output = Rgb;
+
+ fn mul(self, rhs: f32) -> Self::Output {
+ Rgb(self.0 * rhs)
+ }
+}
+
+impl Add<Rgb> for Rgb {
+ type Output = Rgb;
+
+ fn add(self, rhs: Rgb) -> Self::Output {
+ Rgb(self.0 + rhs.0)
+ }
+}
+
+/// Deserialize an Rgb from a hex string.
+///
+/// This is *not* the deserialize impl for Rgb since we want a symmetric
+/// serialize/deserialize impl for ref tests.
+impl<'de> Deserialize<'de> for Rgb {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct RgbVisitor;
+
+ // Used for deserializing reftests.
+ #[derive(Deserialize)]
+ struct RgbDerivedDeser {
+ r: u8,
+ g: u8,
+ b: u8,
+ }
+
+ impl<'a> Visitor<'a> for RgbVisitor {
+ type Value = Rgb;
+
+ fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_str("hex color like #ff00ff")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Rgb, E>
+ where
+ E: serde::de::Error,
+ {
+ Rgb::from_str(value).map_err(|_| {
+ E::custom(format!(
+ "failed to parse rgb color {value}; expected hex color like #ff00ff"
+ ))
+ })
+ }
+ }
+
+ // Return an error if the syntax is incorrect.
+ let value = toml::Value::deserialize(deserializer)?;
+
+ // Attempt to deserialize from struct form.
+ if let Ok(RgbDerivedDeser { r, g, b }) = RgbDerivedDeser::deserialize(value.clone()) {
+ return Ok(Rgb::new(r, g, b));
+ }
+
+ // Deserialize from hex notation (either 0xff00ff or #ff00ff).
+ value.deserialize_str(RgbVisitor).map_err(D::Error::custom)
+ }
+}
+
+impl Display for Rgb {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
+ }
+}
+
+impl FromStr for Rgb {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Rgb, ()> {
+ let chars = if s.starts_with("0x") && s.len() == 8 {
+ &s[2..]
+ } else if s.starts_with('#') && s.len() == 7 {
+ &s[1..]
+ } else {
+ return Err(());
+ };
+
+ match u32::from_str_radix(chars, 16) {
+ Ok(mut color) => {
+ let b = (color & 0xff) as u8;
+ color >>= 8;
+ let g = (color & 0xff) as u8;
+ color >>= 8;
+ let r = color as u8;
+ Ok(Rgb::new(r, g, b))
+ },
+ Err(_) => Err(()),
+ }
+ }
+}
+
+/// RGB color optionally referencing the cell's foreground or background.
+#[derive(SerdeReplace, Copy, Clone, Debug, PartialEq, Eq)]
+pub enum CellRgb {
+ CellForeground,
+ CellBackground,
+ Rgb(Rgb),
+}
+
+impl CellRgb {
+ pub fn color(self, foreground: Rgb, background: Rgb) -> Rgb {
+ match self {
+ Self::CellForeground => foreground,
+ Self::CellBackground => background,
+ Self::Rgb(rgb) => rgb,
+ }
+ }
+}
+
+impl Default for CellRgb {
+ fn default() -> Self {
+ Self::Rgb(Rgb::default())
+ }
+}
+
+impl<'de> Deserialize<'de> for CellRgb {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ const EXPECTING: &str = "CellForeground, CellBackground, or hex color like #ff00ff";
+
+ struct CellRgbVisitor;
+ impl<'a> Visitor<'a> for CellRgbVisitor {
+ type Value = CellRgb;
+
+ fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_str(EXPECTING)
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<CellRgb, E>
+ where
+ E: serde::de::Error,
+ {
+ // Attempt to deserialize as enum constants.
+ match value {
+ "CellForeground" => return Ok(CellRgb::CellForeground),
+ "CellBackground" => return Ok(CellRgb::CellBackground),
+ _ => (),
+ }
+
+ Rgb::from_str(value).map(CellRgb::Rgb).map_err(|_| {
+ E::custom(format!("failed to parse color {value}; expected {EXPECTING}"))
+ })
+ }
+ }
+
+ deserializer.deserialize_str(CellRgbVisitor).map_err(D::Error::custom)
+ }
+}
diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs
index ba716154..30439fc0 100644
--- a/alacritty/src/display/content.rs
+++ b/alacritty/src/display/content.rs
@@ -2,18 +2,17 @@ use std::borrow::Cow;
use std::ops::Deref;
use std::{cmp, mem};
-use alacritty_terminal::ansi::{Color, CursorShape, NamedColor};
use alacritty_terminal::event::EventListener;
use alacritty_terminal::grid::{Dimensions, Indexed};
use alacritty_terminal::index::{Column, Line, Point};
use alacritty_terminal::selection::SelectionRange;
use alacritty_terminal::term::cell::{Cell, Flags, Hyperlink};
-use alacritty_terminal::term::color::{CellRgb, Rgb};
use alacritty_terminal::term::search::{Match, RegexSearch};
use alacritty_terminal::term::{self, RenderableContent as TerminalContent, Term, TermMode};
+use alacritty_terminal::vte::ansi::{Color, CursorShape, NamedColor};
use crate::config::UiConfig;
-use crate::display::color::{List, DIM_FACTOR};
+use crate::display::color::{CellRgb, List, Rgb, DIM_FACTOR};
use crate::display::hint::{self, HintState};
use crate::display::{Display, SizeInfo};
use crate::event::SearchState;
@@ -55,7 +54,7 @@ impl<'a> RenderableContent<'a> {
|| display.ime.preedit().is_some()
{
CursorShape::Hidden
- } else if !term.is_focused && config.terminal_config.cursor.unfocused_hollow {
+ } else if !term.is_focused && config.cursor.unfocused_hollow {
CursorShape::HollowBlock
} else {
terminal_content.cursor.shape
@@ -102,7 +101,7 @@ impl<'a> RenderableContent<'a> {
/// Get the RGB value for a color index.
pub fn color(&self, color: usize) -> Rgb {
- self.terminal_content.colors[color].unwrap_or(self.colors[color])
+ self.terminal_content.colors[color].map(Rgb).unwrap_or(self.colors[color])
}
pub fn selection_range(&self) -> Option<SelectionRange> {
@@ -117,8 +116,8 @@ impl<'a> RenderableContent<'a> {
} else {
self.config.colors.cursor
};
- let cursor_color =
- self.terminal_content.colors[NamedColor::Cursor].map_or(color.background, CellRgb::Rgb);
+ let cursor_color = self.terminal_content.colors[NamedColor::Cursor]
+ .map_or(color.background, |c| CellRgb::Rgb(Rgb(c)));
let text_color = color.foreground;
let insufficient_contrast = (!matches!(cursor_color, CellRgb::Rgb(_))
diff --git a/alacritty/src/display/cursor.rs b/alacritty/src/display/cursor.rs
index 8a4cc729..65933ccc 100644
--- a/alacritty/src/display/cursor.rs
+++ b/alacritty/src/display/cursor.rs
@@ -1,8 +1,8 @@
//! Convert a cursor into an iterator of rects.
-use alacritty_terminal::ansi::CursorShape;
-use alacritty_terminal::term::color::Rgb;
+use alacritty_terminal::vte::ansi::CursorShape;
+use crate::display::color::Rgb;
use crate::display::content::RenderableCursor;
use crate::display::SizeInfo;
use crate::renderer::rects::RenderRect;
diff --git a/alacritty/src/display/hint.rs b/alacritty/src/display/hint.rs
index f508d10c..bd09a881 100644
--- a/alacritty/src/display/hint.rs
+++ b/alacritty/src/display/hint.rs
@@ -590,9 +590,9 @@ impl<'a, T> Iterator for HintPostProcessor<'a, T> {
#[cfg(test)]
mod tests {
- use alacritty_terminal::ansi::Handler;
use alacritty_terminal::index::{Column, Line};
use alacritty_terminal::term::test::mock_term;
+ use alacritty_terminal::vte::ansi::Handler;
use super::*;
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs
index dfe2809f..1d993af8 100644
--- a/alacritty/src/display/mod.rs
+++ b/alacritty/src/display/mod.rs
@@ -23,23 +23,22 @@ use winit::window::CursorIcon;
use crossfont::{self, Rasterize, Rasterizer};
use unicode_width::UnicodeWidthChar;
-use alacritty_terminal::ansi::{CursorShape, NamedColor};
-use alacritty_terminal::config::MAX_SCROLLBACK_LINES;
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::{self, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES};
+use alacritty_terminal::vte::ansi::{CursorShape, NamedColor};
use crate::config::font::Font;
+use crate::config::scrolling::MAX_SCROLLBACK_LINES;
use crate::config::window::Dimensions;
#[cfg(not(windows))]
use crate::config::window::StartupMode;
use crate::config::UiConfig;
use crate::display::bell::VisualBell;
-use crate::display::color::List;
+use crate::display::color::{List, Rgb};
use crate::display::content::{RenderableContent, RenderableCursor};
use crate::display::cursor::IntoRects;
use crate::display::damage::RenderDamageIterator;
@@ -53,13 +52,13 @@ use crate::renderer::{self, GlyphCache, Renderer};
use crate::scheduler::{Scheduler, TimerId, Topic};
use crate::string::{ShortenDirection, StrShortener};
+pub mod color;
pub mod content;
pub mod cursor;
pub mod hint;
pub mod window;
mod bell;
-mod color;
mod damage;
mod meter;
@@ -862,7 +861,7 @@ impl Display {
};
// Draw cursor.
- rects.extend(cursor.rects(&size_info, config.terminal_config.cursor.thickness()));
+ rects.extend(cursor.rects(&size_info, config.cursor.thickness()));
// Push visual bell after url/underline/strikeout rects.
let visual_bell_intensity = self.visual_bell.intensity();
@@ -900,9 +899,7 @@ impl Display {
let fg = config.colors.footer_bar_foreground();
let shape = CursorShape::Underline;
let cursor = RenderableCursor::new(Point::new(line, column), shape, fg, false);
- rects.extend(
- cursor.rects(&size_info, config.terminal_config.cursor.thickness()),
- );
+ rects.extend(cursor.rects(&size_info, config.cursor.thickness()));
}
Some(Point::new(line, column))
@@ -1144,9 +1141,7 @@ impl Display {
let cursor_point = Point::new(point.line, cursor_column);
let cursor =
RenderableCursor::new(cursor_point, CursorShape::HollowBlock, fg, is_wide);
- rects.extend(
- cursor.rects(&self.size_info, config.terminal_config.cursor.thickness()),
- );
+ rects.extend(cursor.rects(&self.size_info, config.cursor.thickness()));
cursor_point
},
_ => end,
@@ -1622,7 +1617,7 @@ fn window_size(
) -> PhysicalSize<u32> {
let padding = config.window.padding(scale_factor);
- let grid_width = cell_width * dimensions.columns.0.max(MIN_COLUMNS) as f32;
+ let grid_width = cell_width * dimensions.columns.max(MIN_COLUMNS) as f32;
let grid_height = cell_height * dimensions.lines.max(MIN_SCREEN_LINES) as f32;
let width = (padding.0).mul_add(2., grid_width).floor();