use super::{draw_pixel_safe, draw_pixel_unsafe};
#[allow(unused_imports)]
use crate::extensions::*;
use crate::render::{BufferMetrics, BufferPointers};
#[inline]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_precision_loss)]
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_possible_wrap)]
pub fn draw_line<const SAFE: bool>(
buffer: &mut (impl BufferPointers + BufferMetrics),
start: (usize, usize),
end: (usize, usize),
color: u32,
thickness: isize,
) {
let mut start_x = start.0 as i16;
let mut start_y = start.1 as i16;
let end_x = end.0 as i16;
let end_y = end.1 as i16;
let difference_x: i16 = end_x - start_x;
let difference_y: i16 = end_y - start_y;
let sign_x = difference_x.sign();
let sign_y = difference_y.sign();
let abs_difference_x: i16 = difference_x.abs();
let abs_difference_y: i16 = difference_y.abs();
let radius = thickness as i16 / 2;
let radius_sq = radius * radius;
if abs_difference_x > abs_difference_y {
let mut error: i16 = abs_difference_x / 2;
while start_x != end_x {
start_x += sign_x;
error -= abs_difference_y;
if error < 0 {
start_y += sign_y;
error += abs_difference_x;
}
for dy in -radius..=radius {
for dx in -radius..=radius {
if dx * dx + dy * dy <= radius_sq {
let new_x = start_x + dx;
let new_y = start_y + dy;
if SAFE {
draw_pixel_safe(
buffer,
(new_x as usize, new_y as usize),
color,
);
} else {
draw_pixel_unsafe(
buffer,
(new_x as usize, new_y as usize),
color,
);
}
}
}
}
}
} else {
let mut error: i16 = abs_difference_y / 2;
while start_y != end_y {
start_y += sign_y;
error -= abs_difference_x;
if error < 0 {
start_x += sign_x;
error += abs_difference_y;
}
for dy in -radius..=radius {
for dx in -radius..=radius {
if dx * dx + dy * dy <= radius_sq {
let new_x = start_x + dx;
let new_y = start_y + dy;
if SAFE {
draw_pixel_safe(
buffer,
(new_x as usize, new_y as usize),
color,
);
} else {
draw_pixel_unsafe(
buffer,
(new_x as usize, new_y as usize),
color,
);
}
}
}
}
}
}
}
#[inline]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_precision_loss)]
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_possible_wrap)]
pub fn draw_line_straight<const SAFE: bool>(
buffer: &mut (impl BufferPointers + BufferMetrics),
start: (usize, usize),
length: usize,
vertical: bool,
color: u32,
thickness: isize,
) {
let (start_x, start_y) = (start.0 as isize, start.1 as isize);
let half_thickness = thickness / 2;
if vertical {
for y in start_y..start_y + length as isize {
for offset_x in -half_thickness..=half_thickness {
if SAFE {
draw_pixel_safe(
buffer,
((start_x + offset_x) as usize, y as usize),
color,
);
} else {
draw_pixel_unsafe(
buffer,
((start_x + offset_x) as usize, y as usize),
color,
);
}
}
}
} else {
for x in start_x..start_x + length as isize {
for offset_y in -half_thickness..=half_thickness {
if SAFE {
draw_pixel_safe(
buffer,
(x as usize, (start_y + offset_y) as usize),
color,
);
} else {
draw_pixel_unsafe(
buffer,
(x as usize, (start_y + offset_y) as usize),
color,
);
}
}
}
}
}