mod buf;
mod canvas;
mod rec;
use core::marker::PhantomData;
use core::mem;
use zerocopy::{AsBytes, FromBytes};
pub use self::rec::{Rec, ReuseError};
pub use self::canvas::{Canvas, CanvasReuseError, Layout};
pub struct Pixel<P: ?Sized>(PhantomData<P>);
pub trait AsPixel {
fn pixel() -> Pixel<Self>;
}
pub mod pixels {
use zerocopy::{AsBytes, FromBytes};
pub(crate) const MAX_ALIGN: usize = 16;
#[derive(Clone, Copy, AsBytes, FromBytes)]
#[repr(align(16))]
#[repr(C)]
pub struct MaxAligned(pub [u8; 16]);
macro_rules! constant_pixels {
($(($name:ident, $type:ty)),*) => {
$(pub const $name: crate::Pixel<$type> = crate::Pixel(::core::marker::PhantomData);
impl crate::AsPixel for $type {
fn pixel() -> crate::Pixel<Self> {
$name
}
}
)*
}
}
constant_pixels!(
(I8, i8),
(U8, u8),
(I16, i16),
(U16, u16),
(I32, i32),
(U32, u32),
(RGB, [u8; 3]),
(RGBA, [u8; 4]),
(MAX, MaxAligned)
);
}
impl<P: AsBytes + FromBytes> Pixel<P> {
pub fn for_type() -> Option<Self> {
if mem::align_of::<P>() <= pixels::MAX_ALIGN {
Some(Pixel(PhantomData))
} else {
None
}
}
}
impl<P> Pixel<P> {
pub fn align(self) -> usize {
mem::align_of::<P>()
}
pub fn size(self) -> usize {
mem::size_of::<P>()
}
}
impl<P> Clone for Pixel<P> {
fn clone(&self) -> Self {
Pixel(PhantomData)
}
}
impl<P> Copy for Pixel<P> { }