use crate::base::ARGB;
use super::System;
impl System {
pub fn draw_line(&mut self, mut x1: i32, mut y1: i32, x2: i32, y2: i32, color: ARGB) -> Result<(), String> {
let (dx, sx) = ((x2 - x1).abs(), (x2 - x1).signum());
let (dy, sy) = ((y2 - y1).abs(), (y2 - y1).signum());
let mut err = dx - dy;
let mut e2: i32;
let a = color.a as u32;
let na = 0x100 - a;
let color_mult_a: [u32; 3] = [(color.b as u32) * a, (color.g as u32) * a, (color.r as u32) * a];
let (w, h) = (self.width, self.height);
let buf = &mut self.buffer;
loop {
if (x1 >= 0) && (y1 >= 0) && (x1 < w) && (y1 < h) {
let offs = ((y1 * w + x1) << 2) as usize;
for c in 0..3 {
buf[offs + c] = ((color_mult_a[c] + (buf[offs + c] as u32) * na) >> 8) as u8;
}
}
if (x1 == x2) && (y1 == y2) {
break;
}
e2 = err << 1;
if e2 > -dy {
err -= dy;
x1 += sx;
}
if e2 < dx {
err += dx;
y1 += sy;
}
}
Ok(())
}
pub fn draw_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGB, fill: bool) -> Result<(), String> {
let (x1, x2, y1, y2) = (x1.min(x2), x1.max(x2), y1.min(y2), y1.max(y2));
if fill {
if (x1 < self.width) && (x2 >= 0) && (y1 < self.height) && (y2 >= 0) { let a = color.a as u32;
let na = 0x100 - a;
let color_mult_a: [u32; 3] = [(color.b as u32) * a, (color.g as u32) * a, (color.r as u32) * a];
let x1 = x1.max(0) as usize;
let y1 = y1.max(0) as usize;
let x2 = (x2 + 1).min(self.width) as usize;
let y2 = (y2 + 1).min(self.height) as usize;
let mut offs_row = (y1 * (self.width as usize) + x1) << 2;
let n_row_bytes = (self.width as usize) << 2;
let vb = &mut self.buffer;
for _y in y1..y2 {
let mut offs = offs_row;
for _x in x1..x2 {
for i in 0..3 {
vb[offs + i] = ((color_mult_a[i] + (vb[offs + i] as u32) * na) >> 8) as u8;
}
offs += 4;
}
offs_row += n_row_bytes;
};
}
} else {
let _ = self.draw_line(x1, y1, x2, y1, color);
let _ = self.draw_line(x2, y1, x2, y2, color);
let _ = self.draw_line(x2, y2, x1, y2, color);
let _ = self.draw_line(x1, y2, x1, y1, color);
}
Ok(())
}
pub fn shade(&mut self, shade: u8) -> Result<(), String> {
self.draw_rect(0, 0, self.width - 1, self.height - 1, ARGB{a: shade, r: 0, g: 0, b: 0}, true)
}
pub fn draw_frame(&mut self,
x: i32, y: i32, width: i32, height: i32, color_int: ARGB, color_ext: ARGB, thickness_binlog: i32) -> Result<(), String> {
let th: i32 = 1 << thickness_binlog;
for i in 1..=th {
let ni = th - i;
let color = ARGB {
a: (((color_ext.a as i32) * i + (color_int.a as i32) * ni) >> thickness_binlog) as u8,
r: (((color_ext.r as i32) * i + (color_int.r as i32) * ni) >> thickness_binlog) as u8,
g: (((color_ext.g as i32) * i + (color_int.g as i32) * ni) >> thickness_binlog) as u8,
b: (((color_ext.b as i32) * i + (color_int.b as i32) * ni) >> thickness_binlog) as u8
};
self.draw_rect(x-i, y-i, x+width+i-1, y+height+i-1, color, false)?;
}
Ok(())
}
}