ableos_userland/libraries/able_graphics_library/src/raw_pixel/arch/x86/mod.rs

90 lines
2.2 KiB
Rust

use embedded_graphics::{
pixelcolor::Rgb888,
prelude::{DrawTarget, IntoStorage, OriginDimensions, PixelColor, Point, Size},
primitives::{Line, Primitive, PrimitiveStyle},
Drawable, Pixel,
};
pub struct Display {
pub fb: *mut u32,
// Back buffer
pub bb: *mut u32,
pub size: Size,
pub color: Rgb888,
}
impl Display {
pub fn set_color(&mut self, color: Rgb888) {
self.color = color;
}
pub fn swap_buffers(&mut self) {
let size: usize = (self.size.height * self.size.width).try_into().unwrap();
unsafe {
let dst_ptr = self.fb;
let src_ptr = self.bb;
core::ptr::copy_nonoverlapping(src_ptr, dst_ptr, size);
}
}
pub fn line(
&mut self,
x1: i32,
y1: i32,
x2: i32,
y2: i32,
thickness: u32,
) -> Result<(), BlitOutOfBoundsError> {
let color = self.color;
let style = PrimitiveStyle::with_stroke(color, thickness);
Line::new(Point::new(x1, y1), Point::new(x2, y2))
.into_styled(style)
.draw(&mut *self)?;
Ok(())
}
}
unsafe impl Send for Display {}
impl DrawTarget for Display {
type Color = Rgb888;
type Error = BlitOutOfBoundsError;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for Pixel(pos, rgb) in pixels {
let pos_x = u32::try_from(pos.x).map_err(|_| BlitOutOfBoundsError)?;
let pos_y = u32::try_from(pos.y).map_err(|_| BlitOutOfBoundsError)?;
unsafe {
if pos_x >= self.size.width || pos_y >= self.size.height {
return Err(BlitOutOfBoundsError);
}
self.bb
.add(
(pos_y * self.size.width + pos_x)
.try_into()
.map_err(|_| BlitOutOfBoundsError)?,
)
.write_volatile(rgb.into_storage());
}
}
Ok(())
}
}
impl OriginDimensions for Display {
#[inline]
fn size(&self) -> Size {
self.size
}
}
#[derive(Debug)]
pub struct BlitOutOfBoundsError;