use crate::graphics::*;
fn render(surface: &mut Surface, img: &Image, x: i32, y: i32, lmin: u8, rap: u32, f: fn(p: 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 mut pattern = 0u8;
let mut total_r = 0u32;
let mut total_g = 0u32;
let mut total_b = 0u32;
let mut total_a = 0u32;
let mut pixel_count = 0u32;
for (i, (dx, dy)) in [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2), (0, 3), (1, 3)].iter().enumerate() {
let sample_x = img_x + dx * rap;
let sample_y = img_y + dy * rap;
if sample_x < w && sample_y < h {
let pixel = if rap == 1 {
img.pixel(sample_x, sample_y).unwrap_or_default()
} else {
img.compute_square_average_color(sample_x, sample_y, rap)
};
total_r += pixel.red as u32;
total_g += pixel.green as u32;
total_b += pixel.blue as u32;
total_a += pixel.alpha as u32;
pixel_count += 1;
let luminance = pixel.luminance();
if luminance > lmin {
pattern |= 1 << i;
}
}
}
let braille_char = char::from_u32(0x2800 + pattern as u32).unwrap_or('\u{2800}');
let foreground = if pixel_count > 0 {
let avg_r = (total_r / pixel_count) as u8;
let avg_g = (total_g / pixel_count) as u8;
let avg_b = (total_b / pixel_count) as u8;
let avg_a = (total_a / pixel_count) as u8;
let avg_pixel = Pixel::new(avg_r, avg_g, avg_b, avg_a);
f(avg_pixel)
} else {
Color::Black
};
let ch = Character::new(braille_char, foreground, Color::Black, CharFlags::None);
surface.write_char(p_x, p_y, ch);
img_x += 2 * rap; p_x += 1;
}
img_y += 4 * rap; p_y += 1;
}
}
#[inline(always)]
pub(crate) fn size(img: &Image) -> Size {
Size::new((img.width() + 1) >> 1, (img.height() + 3) >> 2)
}
#[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;
let lmin = render_options.luminance_threshold;
match render_options.color_schema {
ColorSchema::Auto => {
#[cfg(feature = "TRUE_COLORS")]
{
render(surface, img, x, y, lmin, rap, |p| p.as_rgb_color())
}
#[cfg(not(feature = "TRUE_COLORS"))]
{
render(surface, img, x, y, lmin, rap, |p| p.as_color16())
}
}
ColorSchema::Color16 => render(surface, img, x, y, lmin, rap, |p| p.as_color16()),
#[cfg(feature = "TRUE_COLORS")]
ColorSchema::TrueColors => render(surface, img, x, y, lmin, rap, |p| p.as_rgb_color()),
ColorSchema::GrayScale4 => render(surface, img, x, y, lmin, rap, |p| p.as_grayscale4()),
#[cfg(feature = "TRUE_COLORS")]
ColorSchema::GrayScaleTrueColors => render(surface, img, x, y, lmin, rap, |p| p.as_grayscale()),
ColorSchema::BlackAndWhite => render(surface, img, x, y, lmin, rap, |_| Color::White),
}
}