use crate::VrellisCanvas;
use image::{GrayImage, Luma, LumaA};
use imageproc::drawing::{draw_antialiased_line_segment_mut, draw_line_segment_mut, BresenhamLinePixelIter};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub enum VrellisAlgorithm {
NonRendered,
ThinLine,
AntiAliased,
}
impl Default for VrellisAlgorithm {
fn default() -> Self {
Self::AntiAliased
}
}
impl VrellisAlgorithm {
pub fn line_score(&self, img: &GrayImage, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) -> f32 {
let line = BresenhamLinePixelIter::<Luma<u8>>::new(img, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32));
let mut sum = 0.0;
for p in line {
let s = unsafe { *p.0.get_unchecked(0) };
sum += match reversed {
true => s as f32,
false => (255 - s) as f32,
}
}
return sum;
}
pub fn draw_line(&self, img: &mut GrayImage, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) {
let pixel = match reversed {
true => Luma([0]),
false => Luma([255]),
};
match self {
VrellisAlgorithm::NonRendered => (),
VrellisAlgorithm::ThinLine => draw_line_segment_mut(img, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32), pixel),
VrellisAlgorithm::AntiAliased => draw_antialiased_line_segment_mut(
img,
(x1 as i32, x2 as i32),
(y1 as i32, y2 as i32),
pixel,
|a, b, c| unsafe {
let a = *a.0.get_unchecked(0) as f32;
let b = *b.0.get_unchecked(0) as f32;
let mix = a + c * (b - a);
Luma([mix.round() as u8])
},
),
}
}
}
#[allow(dead_code)]
impl VrellisCanvas {
pub(in crate::render) fn draw_canvas_line(&mut self, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) {
let pixel = match reversed {
true => LumaA([255, 255]),
false => LumaA([0, 255]),
};
draw_line_segment_mut(&mut self.current_image, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32), pixel)
}
}