use crate::graphics::*;
const ASCII_ART_CHARSET: &[char] = &[
' ', '.', '\'', '`', '^', '"', ',', ':', ';', 'I', 'l', '!', 'i', '>', '<', '~', '+', '_', '-', '?', ']', '[', '}', '{', '1', ')', '(', '|',
'\\', '/', 't', 'f', 'j', 'r', 'x', 'n', 'u', 'v', 'c', 'z', 'X', 'Y', 'U', 'J', 'C', 'L', 'Q', '0', 'O', 'Z', 'm', 'w', 'q', 'p', 'd', 'b', 'k',
'h', 'a', 'o', '*', '#', 'M', 'W', '&', '8', '%', 'B', '@', '$',
];
fn render<T>(surface: &mut Surface, img: &Image, x: i32, y: i32, rap: u32, f: T)
where
T: Fn(Pixel) -> Color,
{
let w = img.width();
let h = img.height();
let mut img_y = 0u32;
let mut p_y = y;
while img_y < h {
let mut p_x = x;
let mut img_x = 0u32;
while img_x < w {
let pixel = if rap == 1 {
img.pixel(img_x, img_y).unwrap_or_default()
} else {
img.compute_square_average_color(img_x, img_y, rap)
};
let ascii_char = ASCII_ART_CHARSET[(pixel.luminance() as usize * (ASCII_ART_CHARSET.len() - 1)) / 255];
let ch = Character::new(ascii_char, f(pixel), Color::Black, CharFlags::None);
surface.write_char(p_x, p_y, ch);
surface.write_char(p_x + 1, p_y, ch);
img_x += rap;
p_x += 2;
}
img_y += rap;
p_y += 1;
}
}
#[inline(always)]
pub(crate) fn size(img: &Image) -> Size {
Size::new(img.width() * 2, img.height())
}
#[inline(always)]
pub(crate) fn paint(surface: &mut Surface, img: &Image, x: i32, y: i32, render_options: &RenderOptions) {
let rap = render_options.scale as u32;
match render_options.color_schema {
ColorSchema::Auto => {
#[cfg(feature = "TRUE_COLORS")]
{
render(surface, img, x, y, rap, |p| p.as_rgb_color())
}
#[cfg(not(feature = "TRUE_COLORS"))]
{
render(surface, img, x, y, rap, |p| p.as_color16())
}
}
ColorSchema::Color16 => render(surface, img, x, y, rap, |p| p.as_color16()),
#[cfg(feature = "TRUE_COLORS")]
ColorSchema::TrueColors => render(surface, img, x, y, rap, |p| p.as_rgb_color()),
ColorSchema::GrayScale4 => render(surface, img, x, y, rap, |p| p.as_grayscale4()),
#[cfg(feature = "TRUE_COLORS")]
ColorSchema::GrayScaleTrueColors => render(surface, img, x, y, rap, |p| p.as_grayscale()),
ColorSchema::BlackAndWhite => render(surface, img, x, y, rap, |_| Color::White),
}
}