pixel_sort/render/
draw_line.rs1use crate::VrellisCanvas;
2use image::{GrayImage, Luma, LumaA};
3use imageproc::drawing::{draw_antialiased_line_segment_mut, draw_line_segment_mut, BresenhamLinePixelIter};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
7pub enum VrellisAlgorithm {
8 NonRendered,
10 ThinLine,
12 AntiAliased,
14}
15
16impl Default for VrellisAlgorithm {
17 fn default() -> Self {
18 Self::AntiAliased
19 }
20}
21
22impl VrellisAlgorithm {
23 pub fn line_score(&self, img: &GrayImage, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) -> f32 {
24 let line = BresenhamLinePixelIter::<Luma<u8>>::new(img, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32));
25 let mut sum = 0.0;
26 for p in line {
27 let s = unsafe { *p.0.get_unchecked(0) };
28 sum += match reversed {
29 true => s as f32,
30 false => (255 - s) as f32,
31 }
32 }
33 return sum;
34 }
35 pub fn draw_line(&self, img: &mut GrayImage, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) {
36 let pixel = match reversed {
37 true => Luma([0]),
38 false => Luma([255]),
39 };
40 match self {
41 VrellisAlgorithm::NonRendered => (),
42 VrellisAlgorithm::ThinLine => draw_line_segment_mut(img, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32), pixel),
43 VrellisAlgorithm::AntiAliased => draw_antialiased_line_segment_mut(
44 img,
45 (x1 as i32, x2 as i32),
46 (y1 as i32, y2 as i32),
47 pixel,
48 |a, b, c| unsafe {
49 let a = *a.0.get_unchecked(0) as f32;
50 let b = *b.0.get_unchecked(0) as f32;
51 let mix = a + c * (b - a);
52 Luma([mix.round() as u8])
53 },
54 ),
55 }
56 }
57}
58
59#[allow(dead_code)]
60impl VrellisCanvas {
61 pub(in crate::render) fn draw_canvas_line(&mut self, x1: u32, x2: u32, y1: u32, y2: u32, reversed: bool) {
62 let pixel = match reversed {
63 true => LumaA([255, 255]),
64 false => LumaA([0, 255]),
65 };
66 draw_line_segment_mut(&mut self.current_image, (x1 as f32, x2 as f32), (y1 as f32, y2 as f32), pixel)
67 }
68}