#![allow(unused_variables)]
#[cfg(any(test, doc))]
use crate::NcRgb;
#[cfg(not(any(test, doc)))]
use libnotcurses_sys::NcRgb;
#[derive(Debug)]
pub struct Canvas {
pub h: u32,
pub w: u32,
pub buf: Vec<u8>,
}
impl Canvas {
pub fn new(h: u32, w: u32) -> Self {
let buf: Vec<u8> = vec![255; (h * w) as usize * 3];
Self { h, w, buf }
}
pub fn new_colored(h: u32, w: u32, color: NcRgb) -> Self {
let mut buf = Vec::<u8>::with_capacity((h * w * 3) as usize);
let (r, g, b) = Self::decompose_rgb(color);
#[allow(unused_parens)]
for _byte in (0..={ h * w }) {
buf.push(r);
buf.push(g);
buf.push(b);
}
Self { h, w, buf }
}
pub fn size_cartesian(&self) -> (f32, f32, f32, f32) {
(
self.s2c_y(self.h),
self.s2c_y(0),
self.s2c_x(0),
self.s2c_x(self.w),
)
}
pub const fn size_screen(&self) -> (u32, u32, u32, u32) {
(0, self.h, 0, self.w)
}
pub fn set_pixel(&mut self, y: f32, x: f32, color: NcRgb) {
let (r, g, b) = Self::decompose_rgb(color);
let (y, x) = self.c2s(y, x);
let idx = (x * 3 + y * 3 * self.w) as usize;
self.buf[idx] = r;
self.buf[idx + 1] = g;
self.buf[idx + 2] = b;
}
pub fn set_pixel2(&mut self, y: u32, x: u32, color: NcRgb) {
let (r, g, b) = Self::decompose_rgb(color);
let idx = (x * 3 + y * 3 * self.w) as usize;
self.buf[idx] = r;
self.buf[idx + 1] = g;
self.buf[idx + 2] = b;
}
#[inline]
pub fn s2c(&self, y: u32, x: u32) -> (f32, f32) {
let cart_y = (y as f32 * -1.) + self.h as f32 / 2.;
let cart_x = x as f32 - self.w as f32 / 2.;
(cart_y, cart_x)
}
pub fn s2c_y(&self, y: u32) -> f32 {
(y as f32 * -1.) + self.h as f32 / 2.
}
pub fn s2c_x(&self, x: u32) -> f32 {
x as f32 - self.w as f32 / 2.
}
#[inline]
pub fn c2s(&self, y: f32, x: f32) -> (u32, u32) {
let screen_y = (self.h as f32 / 2. - y) as u32;
let screen_x = (self.w as f32 / 2. + x) as u32;
(screen_y, screen_x)
}
fn decompose_rgb(color: NcRgb) -> (u8, u8, u8) {
let r = ((color.0 & 0xFF0000) >> 16) as u8;
let g = ((color.0 & 0xFF00) >> 8) as u8;
let b = (color.0 & 0xFF) as u8;
(r, g, b)
}
}
#[cfg(test)]
mod test {
#[test]
fn cartesian_to_screen() {
let c = super::Canvas::new(30, 40);
assert_eq!(c.c2s(0., 0.), (15, 20)); assert_eq!(c.c2s(15., 20.), (0, 40)); assert_eq!(c.c2s(-15., -20.), (30, 0)); }
#[test]
fn screen_to_cartesian() {
let c = super::Canvas::new(30, 40);
assert_eq!(c.s2c(15, 20), (0., 0.)); assert_eq!(c.s2c(0, 40), (15., 20.)); assert_eq!(c.s2c(30, 0), (-15., -20.)); }
}