#[cfg_attr(not(target_arch="avr"), derive(Debug))]
#[cfg_attr(target_arch="avr", derive(ufmt::derive::uDebug))]
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct Monochromatic(bool);
#[cfg_attr(not(target_arch="avr"), derive(Debug))]
#[cfg_attr(target_arch="avr", derive(ufmt::derive::uDebug))]
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct Grey(u8);
#[cfg_attr(not(target_arch="avr"), derive(Debug))]
#[cfg_attr(target_arch="avr", derive(ufmt::derive::uDebug))]
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct Rgb4bit(u16);
#[cfg_attr(not(target_arch="avr"), derive(Debug))]
#[cfg_attr(target_arch="avr", derive(ufmt::derive::uDebug))]
#[derive(Copy,Clone,Eq,PartialEq)]
pub struct Rgb8bit(u8,u8,u8);
impl Monochromatic {
pub const BLACK : Self = Monochromatic(false);
pub const WHITE : Self = Monochromatic(true);
pub fn is_set(&self) -> bool {
self.0
}
pub fn as_bit(&self) -> u8 {
match self.0 {
true => 0b00000001,
false => 0b00000000
}
}
}
impl Grey {
pub const BLACK : Self = Grey(0);
pub const WHITE : Self = Grey(255);
pub const GREY25PC : Self = Grey(64);
pub const GREY50PC : Self = Grey(128);
pub const GREY75PC : Self = Grey(192);
pub const fn percent(percentage: u16) -> Self {
assert!(percentage <= 100);
Grey(((256u16 * percentage) / 100u16) as u8)
}
pub const fn eightbit(value: u8) -> Self {
Grey(value)
}
pub const fn fourbit(value: u8) -> Self {
Grey(value << 4)
}
pub fn get_value(&self) -> u8 {
self.0
}
pub fn get_value4bit(&self) -> u8 {
self.0 >> 4
}
}
impl Rgb4bit {
pub const BLACK : Self = Rgb4bit(0x0000);
pub const WHITE : Self = Rgb4bit(0x0fff);
}
impl Rgb8bit {
pub const BLACK : Self = Rgb8bit(0,0,0);
pub const WHITE : Self = Rgb8bit(255,255,255);
}
impl From<Grey> for Monochromatic {
fn from(g: Grey) -> Self {
Monochromatic(g.0 > 127)
}
}
impl From<Monochromatic> for Grey {
fn from(m: Monochromatic) -> Self {
if m.is_set() {
Grey::WHITE
} else {
Grey::BLACK
}
}
}
impl From<Rgb8bit> for Grey {
fn from(rgb: Rgb8bit) -> Self {
Grey((((rgb.0 as u16) + (rgb.1 as u16) + (rgb.2 as u16)) / 3u16) as u8)
}
}
impl From<Rgb8bit> for Rgb4bit {
fn from(rgb: Rgb8bit) -> Self {
Rgb4bit(
((((rgb.0 & 0xf0) >> 4) as u16) << 8) |
((((rgb.1 & 0xf0) >> 4) as u16) << 4) |
((((rgb.2 & 0xf0) >> 4) as u16) << 0)
)
}
}
impl From<Rgb4bit> for Rgb8bit {
fn from(rgb: Rgb4bit) -> Self {
Rgb8bit((((rgb.0 & 0x0f00) >> 8) as u8) << 4,
(((rgb.0 & 0x00f0) >> 4) as u8) << 4,
(((rgb.0 & 0x000f) >> 0) as u8) << 4)
}
}
#[cfg(test)]
mod tests {
use avrox_display::gfx::pixels::{Grey, Monochromatic, Rgb4bit, Rgb8bit};
#[test]
fn test_pixel_conversions() {
let colour = Rgb8bit(0xff,0x00,0xaa);
let smallercolour : Rgb4bit = colour.into();
assert_eq!(smallercolour, Rgb4bit(0x0f0a));
let greyscale : Grey = colour.into();
assert_eq!(greyscale, Grey(141));
let monochrome : Monochromatic = greyscale.into();
assert_eq!(monochrome, Monochromatic(true));
println!("Colour = {:?}", colour);
println!("4b Colour = {:?}", smallercolour);
println!("Greyscale = {:?}", greyscale);
println!("Monochrome = {:?}", monochrome);
}
}