diff --git a/term/src/terminalstate/image.rs b/term/src/terminalstate/image.rs index db66783cc..947cf85e9 100644 --- a/term/src/terminalstate/image.rs +++ b/term/src/terminalstate/image.rs @@ -40,7 +40,7 @@ pub struct ImageAttachParams { pub columns: Option, pub rows: Option, - pub image_id: u32, + pub image_id: Option, pub placement_id: Option, pub style: ImageAttachStyle, diff --git a/term/src/terminalstate/iterm.rs b/term/src/terminalstate/iterm.rs index a3331b566..9770880bf 100644 --- a/term/src/terminalstate/iterm.rs +++ b/term/src/terminalstate/iterm.rs @@ -136,7 +136,7 @@ impl TerminalState { rows: None, data: image_data, style: ImageAttachStyle::Iterm, - image_id: 0, + image_id: None, placement_id: None, do_not_move_cursor: false, }); diff --git a/term/src/terminalstate/kitty.rs b/term/src/terminalstate/kitty.rs index 1845f52a4..5f927f83c 100644 --- a/term/src/terminalstate/kitty.rs +++ b/term/src/terminalstate/kitty.rs @@ -124,7 +124,7 @@ impl TerminalState { z_index: placement.z_index.unwrap_or(0), columns: placement.columns.map(|x| x as usize), rows: placement.rows.map(|x| x as usize), - image_id, + image_id: Some(image_id), placement_id: placement.placement_id, do_not_move_cursor: placement.do_not_move_cursor, }); diff --git a/term/src/terminalstate/sixel.rs b/term/src/terminalstate/sixel.rs index 26186451a..c08d041e4 100644 --- a/term/src/terminalstate/sixel.rs +++ b/term/src/terminalstate/sixel.rs @@ -121,7 +121,7 @@ impl TerminalState { data: image_data, style: ImageAttachStyle::Sixel, z_index: 0, - image_id: 0, + image_id: None, placement_id: None, do_not_move_cursor: false, }); diff --git a/termwiz/src/image.rs b/termwiz/src/image.rs index 390fabb07..b6cc8d185 100644 --- a/termwiz/src/image.rs +++ b/termwiz/src/image.rs @@ -90,7 +90,7 @@ pub struct ImageCell { display_offset_x: u32, display_offset_y: u32, - image_id: u32, + image_id: Option, placement_id: Option, } @@ -100,7 +100,7 @@ impl ImageCell { bottom_right: TextureCoordinate, data: Arc, ) -> Self { - Self::with_z_index(top_left, bottom_right, data, 0, 0, 0, 0, None) + Self::with_z_index(top_left, bottom_right, data, 0, 0, 0, None, None) } pub fn with_z_index( @@ -110,7 +110,7 @@ impl ImageCell { z_index: i32, display_offset_x: u32, display_offset_y: u32, - image_id: u32, + image_id: Option, placement_id: Option, ) -> Self { Self { @@ -126,7 +126,11 @@ impl ImageCell { } pub fn matches_placement(&self, image_id: u32, placement_id: Option) -> bool { - self.image_id == image_id && self.placement_id == placement_id + self.image_id == Some(image_id) && self.placement_id == placement_id + } + + pub fn has_placement_id(&self) -> bool { + self.placement_id.is_some() } pub fn top_left(&self) -> TextureCoordinate { diff --git a/termwiz/src/surface/line.rs b/termwiz/src/surface/line.rs index 38f5eda88..6aa5bc20a 100644 --- a/termwiz/src/surface/line.rs +++ b/termwiz/src/surface/line.rs @@ -405,6 +405,27 @@ impl Line { /// Similarly, when we assign a cell, we need to blank out those /// occluded successor cells. pub fn set_cell(&mut self, idx: usize, cell: Cell) -> &Cell { + self.set_cell_impl(idx, cell, false) + } + + pub fn set_cell_clearing_image_placements(&mut self, idx: usize, cell: Cell) -> &Cell { + self.set_cell_impl(idx, cell, true) + } + + fn raw_set_cell(&mut self, idx: usize, mut cell: Cell, clear: bool) { + if !clear { + if let Some(images) = self.cells[idx].attrs().images() { + for image in images { + if image.has_placement_id() { + cell.attrs_mut().attach_image(Box::new(image)); + } + } + } + } + self.cells[idx] = cell; + } + + fn set_cell_impl(&mut self, idx: usize, cell: Cell, clear: bool) -> &Cell { let width = cell.width(); // if the line isn't wide enough, pad it out with the default attributes. @@ -428,10 +449,10 @@ impl Line { // For double-wide or wider chars, ensure that the cells that // are overlapped by this one are blanked out. for i in 1..=width.saturating_sub(1) { - self.cells[idx + i] = Cell::new(' ', cell.attrs().clone()); + self.raw_set_cell(idx + i, Cell::new(' ', cell.attrs().clone()), clear); } - self.cells[idx] = cell; + self.raw_set_cell(idx, cell, clear); &self.cells[idx] } @@ -529,7 +550,7 @@ impl Line { pub fn fill_range(&mut self, cols: Range, cell: &Cell) { for x in cols { // FIXME: we can skip the look-back for second and subsequent iterations - self.set_cell(x, cell.clone()); + self.set_cell_impl(x, cell.clone(), true); } self.prune_trailing_blanks(); }