Skip to main content

matrix_gui/
fill_rect.rs

1#![allow(clippy::missing_safety_doc)]
2
3use embedded_graphics::{prelude::PixelColor, primitives::Rectangle};
4
5pub fn fill_with_color<COL: PixelColor>(rect: &Rectangle, color: COL) {
6    unsafe extern "Rust" {
7        fn _ll_fill_with_color(x: u32, y: u32, w: u32, h: u32, color: u32);
8    }
9
10    let color_as_u32 = color_to_u32(&color);
11
12    let top_left = rect.top_left;
13    let size = rect.size;
14    unsafe {
15        _ll_fill_with_color(
16            top_left.x as u32,
17            top_left.y as u32,
18            size.width,
19            size.height,
20            color_as_u32,
21        )
22    };
23}
24pub fn fill_with_buffer<C: PixelColor>(rect: &Rectangle, colors: &[C]) {
25    unsafe extern "Rust" {
26        fn _ll_fill_with_buffer(x: u32, y: u32, w: u32, h: u32, colors: *const u8);
27    }
28
29    let top_left = rect.top_left;
30    let size = rect.size;
31
32    unsafe {
33        _ll_fill_with_buffer(
34            top_left.x as u32,
35            top_left.y as u32,
36            size.width,
37            size.height,
38            colors.as_ptr() as *const u8,
39        )
40    };
41}
42
43fn color_to_u32<COL: PixelColor>(color: &COL) -> u32 {
44    let color_ptr = color as *const COL as *const u8;
45    let color_size = core::mem::size_of::<COL>();
46
47    match color_size {
48        1 => unsafe { *color_ptr as u32 },
49        2 => unsafe { *color_ptr.cast::<u16>() as u32 },
50        3 => {
51            let bytes = unsafe { core::ptr::read_unaligned(color_ptr.cast::<[u8; 3]>()) };
52            u32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]])
53        }
54        4 => unsafe { *color_ptr.cast::<u32>() },
55        _ => 0xFFFFFFFF,
56    }
57}
58
59pub unsafe trait ImplFillRect {
60    unsafe fn fill_with_color(x: u32, y: u32, w: u32, h: u32, color: u32);
61    unsafe fn fill_with_buffer(x: u32, y: u32, w: u32, h: u32, colors: *const u8);
62}
63
64#[macro_export]
65macro_rules! set_impl_fill_rect {
66    ($t: ty) => {
67        #[unsafe(no_mangle)]
68        unsafe fn _ll_fill_with_color(x: u32, y: u32, w: u32, h: u32, color: u32) {
69            unsafe { <$t as $crate::fill_rect::ImplFillRect>::fill_with_color(x, y, w, h, color) }
70        }
71        #[unsafe(no_mangle)]
72        unsafe fn _ll_fill_with_buffer(x: u32, y: u32, w: u32, h: u32, colors: *const u8) {
73            unsafe { <$t as $crate::fill_rect::ImplFillRect>::fill_with_buffer(x, y, w, h, colors) }
74        }
75    };
76}