Skip to content

Commit

Permalink
Merge pull request #172 from mfontanini/sixel-sizing
Browse files Browse the repository at this point in the history
Use pixels per column/row to resize sixel images
  • Loading branch information
mfontanini authored Jan 25, 2024
2 parents faf25a1 + bfc14ca commit 7543434
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ fn run(mut cli: Cli) -> Result<(), Box<dyn std::error::Error>> {
let resources_path = path.parent().unwrap_or(Path::new("/"));
let mut options = make_builder_options(&config, &mode, force_default_theme);
let graphics_mode = select_graphics_mode(&cli, &config);
let printer = Rc::new(ImagePrinter::new(graphics_mode.clone(), config.defaults.terminal_font_size)?);
let printer = Rc::new(ImagePrinter::new(graphics_mode.clone())?);
let registry = ImageRegistry(printer.clone());
let resources = Resources::new(resources_path, registry.clone());
let typst = TypstRender::new(config.typst.ppi, registry);
Expand Down
13 changes: 9 additions & 4 deletions src/media/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ pub(crate) struct PrintOptions {
pub(crate) rows: u16,
pub(crate) cursor_position: CursorPosition,
pub(crate) z_index: i32,
// Width/height in pixels.
#[allow(dead_code)]
pub(crate) column_width: u16,
#[allow(dead_code)]
pub(crate) row_height: u16,
}

pub(crate) enum ImageResource {
Expand Down Expand Up @@ -69,13 +74,13 @@ impl Default for ImagePrinter {
}

impl ImagePrinter {
pub fn new(mode: GraphicsMode, #[allow(unused_variables)] font_size: u8) -> Result<Self, CreatePrinterError> {
pub fn new(mode: GraphicsMode) -> Result<Self, CreatePrinterError> {
let printer = match mode {
GraphicsMode::Kitty { mode, inside_tmux } => Self::new_kitty(mode, inside_tmux)?,
GraphicsMode::Iterm2 => Self::new_iterm(),
GraphicsMode::AsciiBlocks => Self::new_ascii(),
#[cfg(feature = "sixel")]
GraphicsMode::Sixel => Self::new_sixel(font_size)?,
GraphicsMode::Sixel => Self::new_sixel()?,
};
Ok(printer)
}
Expand All @@ -93,8 +98,8 @@ impl ImagePrinter {
}

#[cfg(feature = "sixel")]
fn new_sixel(font_size: u8) -> Result<Self, CreatePrinterError> {
Ok(Self::Sixel(super::sixel::SixelPrinter::new(font_size)?))
fn new_sixel() -> Result<Self, CreatePrinterError> {
Ok(Self::Sixel(super::sixel::SixelPrinter::new()?))
}
}

Expand Down
11 changes: 5 additions & 6 deletions src/media/sixel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ impl ResourceProperties for SixelResource {

pub struct SixelPrinter {
encoder: Encoder,
font_size: u32,
}

impl SixelPrinter {
pub(crate) fn new(font_size: u8) -> Result<Self, CreatePrinterError> {
pub(crate) fn new() -> Result<Self, CreatePrinterError> {
let encoder =
Encoder::new().map_err(|e| CreatePrinterError::Other(format!("creating sixel encoder: {e:?}")))?;
encoder
.set_encode_policy(EncodePolicy::Fast)
.map_err(|e| CreatePrinterError::Other(format!("setting encoder policy: {e:?}")))?;
Ok(Self { encoder, font_size: font_size.into() })
Ok(Self { encoder })
}
}

Expand All @@ -54,9 +53,9 @@ impl PrintImage for SixelPrinter {
writer.flush()?;

// This check was taken from viuer: it seems to be a bug in xterm
let width = (self.font_size * options.columns as u32).min(1000);
let height = self.font_size * 2 * options.rows as u32;
let image = image.0.resize_exact(width, height, FilterType::Triangle);
let width = (options.column_width * options.columns).min(1000);
let height = options.row_height * options.rows;
let image = image.0.resize_exact(width as u32, height as u32, FilterType::Triangle);
let bytes = image.into_rgba8().into_raw();

let frame = QuickFrameBuilder::new()
Expand Down
15 changes: 11 additions & 4 deletions src/render/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,26 @@ where
}

fn render_image(&mut self, image: &Image, properties: &ImageProperties) -> RenderResult {
let starting_position =
CursorPosition { row: self.terminal.cursor_row, column: self.current_rect().start_column };
let rect = self.current_rect();
let starting_position = CursorPosition { row: self.terminal.cursor_row, column: rect.start_column };

let (width, height) = image.dimensions();
let (cursor_position, columns, rows) = match properties.size {
ImageSize::Scaled => {
let scale = scale_image(self.current_dimensions(), width, height, &starting_position);
let scale = scale_image(&rect.dimensions, width, height, &starting_position);
(CursorPosition { row: starting_position.row, column: scale.start_column }, scale.columns, scale.rows)
}
ImageSize::Specific(columns, rows) => (starting_position.clone(), columns, rows),
};

let options = PrintOptions { columns, rows, cursor_position, z_index: properties.z_index };
let options = PrintOptions {
columns,
rows,
cursor_position,
z_index: properties.z_index,
column_width: rect.dimensions.pixels_per_column() as u16,
row_height: rect.dimensions.pixels_per_row() as u16,
};
self.terminal.print_image(image, &options)?;
if properties.restore_cursor {
self.terminal.move_to(starting_position.column, starting_position.row)?;
Expand Down

0 comments on commit 7543434

Please sign in to comment.