From 0fd3793a963015e8f91021e35dbb2169d15c3211 Mon Sep 17 00:00:00 2001 From: Ayose Date: Wed, 10 Mar 2021 20:21:36 +0000 Subject: Add Sixel support Fixes #910 --- alacritty_terminal/src/graphics/mod.rs | 146 +++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 alacritty_terminal/src/graphics/mod.rs (limited to 'alacritty_terminal/src/graphics/mod.rs') diff --git a/alacritty_terminal/src/graphics/mod.rs b/alacritty_terminal/src/graphics/mod.rs new file mode 100644 index 00000000..30424c2b --- /dev/null +++ b/alacritty_terminal/src/graphics/mod.rs @@ -0,0 +1,146 @@ +//! This module implements the logic to manage graphic items included in a +//! `Grid` instance. + +pub mod sixel; + +use std::mem; +use std::sync::{Arc, Weak}; + +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; + +use crate::term::color::Rgb; + +/// Max allowed dimensions (width, height) for the graphic, in pixels. +pub const MAX_GRAPHIC_DIMENSIONS: (usize, usize) = (4096, 4096); + +/// Unique identifier for every graphic added to a grid. +#[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Debug, Copy, Hash, PartialOrd, Ord)] +pub struct GraphicId(u64); + +/// Reference to a texture stored in the display. +/// +/// When all references to a single texture are removed, its identifier is +/// added to the remove queue. +#[derive(Clone, Debug)] +pub struct TextureRef { + /// Graphic identifier. + pub id: GraphicId, + + /// Queue to track removed references. + pub remove_queue: Weak>>, +} + +impl PartialEq for TextureRef { + fn eq(&self, t: &Self) -> bool { + // Ignore remove_queue. + self.id == t.id + } +} + +impl Eq for TextureRef {} + +impl Drop for TextureRef { + fn drop(&mut self) { + if let Some(remove_queue) = self.remove_queue.upgrade() { + remove_queue.lock().push(self.id); + } + } +} + +/// Graphic data stored in a single cell. +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct GraphicCell { + /// Texture to draw the graphic in this cell. + pub texture: Arc, + + /// Offset in the x direction. + pub offset_x: u16, + + /// Offset in the y direction. + pub offset_y: u16, +} + +impl GraphicCell { + /// Graphic identifier of the texture in this cell. + #[inline] + pub fn graphic_id(&self) -> GraphicId { + self.texture.id + } +} + +/// Specifies the format of the pixel data. +#[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Debug, Copy)] +pub enum ColorType { + /// 3 bytes per pixel (red, green, blue). + Rgb, + + /// 4 bytes per pixel (red, green, blue, alpha). + Rgba, +} + +/// Defines a single graphic read from the PTY. +#[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Debug)] +pub struct GraphicData { + /// Graphics identifier. + pub id: GraphicId, + + /// Width, in pixels, of the graphic. + pub width: usize, + + /// Height, in pixels, of the graphic. + pub height: usize, + + /// Color type of the pixels. + pub color_type: ColorType, + + /// Pixels data. + pub pixels: Vec, +} + +/// Queues to add or to remove the textures in the display. +pub struct UpdateQueues { + /// Graphics read from the PTY. + pub pending: Vec, + + /// Graphics removed from the grid. + pub remove_queue: Vec, +} + +/// Track changes in the grid to add or to remove graphics. +#[derive(Clone, Debug, Default)] +pub struct Graphics { + /// Last generated identifier. + pub last_id: u64, + + /// New graphics, received from the PTY. + pub pending: Vec, + + /// Graphics removed from the grid. + pub remove_queue: Arc>>, + + /// Shared palette for Sixel graphics. + pub sixel_shared_palette: Option>, +} + +impl Graphics { + /// Generate a new graphic identifier. + pub fn next_id(&mut self) -> GraphicId { + self.last_id += 1; + GraphicId(self.last_id) + } + + /// Get queues to update graphics in the grid. + /// + /// If all queues are empty, it returns `None`. + pub fn take_queues(&mut self) -> Option { + let mut remove_queue = self.remove_queue.lock(); + if remove_queue.is_empty() && self.pending.is_empty() { + return None; + } + + let remove_queue = mem::take(&mut *remove_queue); + + Some(UpdateQueues { pending: mem::take(&mut self.pending), remove_queue }) + } +} -- cgit From c5b7304e93d94c0dee4b07f2741b07b6a9cef5e1 Mon Sep 17 00:00:00 2001 From: Ayose Date: Mon, 31 May 2021 20:53:23 +0100 Subject: Define MAX_GRAPHIC_DIMENSIONS as a 2-elements array. --- alacritty_terminal/src/graphics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'alacritty_terminal/src/graphics/mod.rs') diff --git a/alacritty_terminal/src/graphics/mod.rs b/alacritty_terminal/src/graphics/mod.rs index 30424c2b..a285228f 100644 --- a/alacritty_terminal/src/graphics/mod.rs +++ b/alacritty_terminal/src/graphics/mod.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; use crate::term::color::Rgb; /// Max allowed dimensions (width, height) for the graphic, in pixels. -pub const MAX_GRAPHIC_DIMENSIONS: (usize, usize) = (4096, 4096); +pub const MAX_GRAPHIC_DIMENSIONS: [usize; 2] = [4096, 4096]; /// Unique identifier for every graphic added to a grid. #[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Debug, Copy, Hash, PartialOrd, Ord)] -- cgit