broot/image/
double_line.rs1use {
2 super::zune_compat::Rgba,
3 crate::{
4 display::W,
5 errors::ProgramError,
6 },
7 ansi_colours,
8 crokey::crossterm::{
9 QueueableCommand,
10 style::{
11 Color,
12 Colors,
13 Print,
14 SetColors,
15 },
16 },
17 termimad::fill_bg,
18};
19
20const UPPER_HALF_BLOCK: char = '▀';
21
22pub struct DoubleLine {
29 img_width: usize,
30 pixels: Vec<Color>, true_colors: bool,
32}
33
34impl DoubleLine {
35 pub fn new(
36 img_width: usize,
37 true_colors: bool,
38 ) -> Self {
39 Self {
40 img_width,
41 pixels: Vec::with_capacity(2 * img_width),
42 true_colors,
43 }
44 }
45 pub fn push(
46 &mut self,
47 rgba: Rgba<u8>,
48 ) {
49 self.pixels.push(if self.true_colors {
50 Color::Rgb {
51 r: rgba[0],
52 g: rgba[1],
53 b: rgba[2],
54 }
55 } else {
56 Color::AnsiValue(ansi_colours::ansi256_from_rgb((rgba[0], rgba[1], rgba[2])))
57 });
58 }
59 pub fn is_empty(&self) -> bool {
60 self.pixels.is_empty()
61 }
62 pub fn is_full(&self) -> bool {
63 self.pixels.len() == 2 * self.img_width
64 }
65 pub fn write(
66 &mut self,
67 w: &mut W,
68 left_margin: usize,
69 right_margin: usize,
70 bg: Color,
71 ) -> Result<(), ProgramError> {
72 debug_assert!(
73 self.pixels.len() == self.img_width || self.pixels.len() == 2 * self.img_width
74 );
75 let simple = self.pixels.len() < 2 * self.img_width;
77 fill_bg(w, left_margin, bg)?;
78 for i in 0..self.img_width {
79 let foreground_color = self.pixels[i];
80 let background_color = if simple {
81 bg
82 } else {
83 self.pixels[i + self.img_width]
84 };
85 w.queue(SetColors(Colors::new(foreground_color, background_color)))?;
86 w.queue(Print(UPPER_HALF_BLOCK))?;
87 }
88 fill_bg(w, right_margin, bg)?;
89 self.pixels.clear();
90 Ok(())
91 }
92}