use {
super::zune_compat::Rgba,
crate::{
display::W,
errors::ProgramError,
},
crokey::crossterm::{
QueueableCommand,
style::{
Color,
Colors,
Print,
SetColors,
},
},
termimad::{
fill_bg,
coolor,
},
};
const UPPER_HALF_BLOCK: char = '▀';
pub struct DoubleLine {
img_width: usize,
pixels: Vec<Color>, true_colors: bool,
}
impl DoubleLine {
pub fn new(
img_width: usize,
true_colors: bool,
) -> Self {
Self {
img_width,
pixels: Vec::with_capacity(2 * img_width),
true_colors,
}
}
pub fn push(
&mut self,
rgba: Rgba<u8>,
) {
self.pixels.push(if self.true_colors {
Color::Rgb {
r: rgba[0],
g: rgba[1],
b: rgba[2],
}
} else {
Color::AnsiValue(
coolor::Rgb::new(rgba[0], rgba[1], rgba[2])
.to_ansi()
.code
)
});
}
pub fn is_empty(&self) -> bool {
self.pixels.is_empty()
}
pub fn is_full(&self) -> bool {
self.pixels.len() == 2 * self.img_width
}
pub fn write(
&mut self,
w: &mut W,
left_margin: usize,
right_margin: usize,
bg: Color,
) -> Result<(), ProgramError> {
debug_assert!(
self.pixels.len() == self.img_width || self.pixels.len() == 2 * self.img_width
);
let simple = self.pixels.len() < 2 * self.img_width;
fill_bg(w, left_margin, bg)?;
for i in 0..self.img_width {
let foreground_color = self.pixels[i];
let background_color = if simple {
bg
} else {
self.pixels[i + self.img_width]
};
w.queue(SetColors(Colors::new(foreground_color, background_color)))?;
w.queue(Print(UPPER_HALF_BLOCK))?;
}
fill_bg(w, right_margin, bg)?;
self.pixels.clear();
Ok(())
}
}