mod.rs 3.71 KB
Newer Older
1 2
use crate::Display;
use card10_sys::*;
Astro's avatar
Astro committed
3
use core::mem::{transmute, uninitialized};
4
use core::ops::{Index, IndexMut};
Astro's avatar
Astro committed
5

Astro's avatar
Astro committed
6
use embedded_graphics::pixelcolor::{PixelColor, Rgb565};
7 8 9
use embedded_graphics::prelude::Pixel;
use embedded_graphics::Drawing;

10 11 12 13 14
mod font;
pub use font::*;
mod text;
pub use text::TextRenderer;

Astro's avatar
Astro committed
15
pub struct FrameBuffer<'d> {
16
    _display: &'d mut Display,
Astro's avatar
Astro committed
17 18 19 20
    buffer: disp_framebuffer,
}

impl<'d> FrameBuffer<'d> {
21
    pub fn uninitialized(display: &'d mut Display) -> Self {
Astro's avatar
Astro committed
22 23
        FrameBuffer {
            _display: display,
24
            buffer: unsafe { uninitialized() },
Astro's avatar
Astro committed
25 26 27 28 29 30 31 32
        }
    }

    pub fn send(&mut self) {
        unsafe {
            epic_disp_framebuffer(&mut self.buffer);
        }
    }
33

Astro's avatar
Astro committed
34 35 36
    pub fn clear(&mut self, color: RawColor) {
        for y in 0..Display::H {
            for x in 0..Display::W {
37 38
                let bytes: &mut RawColor =
                    unsafe { transmute(&mut self.buffer.fb[y as usize][x as usize]) };
Astro's avatar
Astro committed
39 40 41 42 43
                *bytes = color;
            }
        }
    }

44 45 46 47 48 49 50
    pub fn text<'a, 'f>(
        &'a mut self,
        x: isize,
        y: isize,
        font: &'f Font,
        color: RawColor,
    ) -> TextRenderer<'a, 'd, 'f> {
51 52
        TextRenderer {
            framebuffer: self,
53 54 55 56
            x,
            y,
            font,
            color,
57 58
        }
    }
Astro's avatar
Astro committed
59 60
}

61 62 63
impl<'d> Index<(u16, u16)> for FrameBuffer<'d> {
    type Output = RawColor;
    fn index(&self, (x, y): (u16, u16)) -> &Self::Output {
64 65
        let x = usize::from(Display::W as u16 - 1 - x);
        let y = usize::from(Display::H as u16 - 1 - y);
66
        unsafe { transmute(&self.buffer.fb[y][x]) }
67 68 69 70 71
    }
}

impl<'d> IndexMut<(u16, u16)> for FrameBuffer<'d> {
    fn index_mut(&mut self, (x, y): (u16, u16)) -> &mut Self::Output {
72 73
        let x = usize::from(Display::W as u16 - 1 - x);
        let y = usize::from(Display::H as u16 - 1 - y);
74
        unsafe { transmute(&mut self.buffer.fb[y][x]) }
Astro's avatar
Astro committed
75 76 77
    }
}

Astro's avatar
Astro committed
78
/// `embedded-graphics` support
Astro's avatar
Astro committed
79
impl<'d, C: PixelColor + Into<RawColor>> Drawing<C> for FrameBuffer<'d> {
80 81
    fn draw<T>(&mut self, item: T)
    where
Astro's avatar
Astro committed
82
        T: IntoIterator<Item = Pixel<C>>,
83
    {
Astro's avatar
Astro committed
84
        for Pixel(coord, color) in item {
85 86 87
            let x = coord[0] as u16;
            let y = coord[1] as u16;

88
            if x >= Display::W as u16 || y >= Display::H as u16 {
89 90
                continue;
            }
91
            // Swap bytes
Astro's avatar
Astro committed
92
            self[(x, y)] = color.into();
93 94 95 96
        }
    }
}

Astro's avatar
Astro committed
97
/// RGB565 with swapped bytes
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct RawColor([u8; 2]);

impl RawColor {
    pub fn red() -> Self {
        Self::rgb8(0xff, 0, 0)
    }

    pub fn blue() -> Self {
        Self::rgb8(0, 0, 0xff)
    }

    pub fn green() -> Self {
        Self::rgb8(0, 0xff, 0)
    }

    pub fn black() -> Self {
        Self::rgb8(0, 0, 0)
    }

    pub fn white() -> Self {
        Self::rgb8(0xff, 0xff, 0xff)
    }

    pub fn yellow() -> Self {
        Self::rgb8(0xff, 0xff, 0)
    }

Astro's avatar
Astro committed
127
    /// Construct from 0..255-triple
128 129 130 131
    pub fn rgb8(r8: u8, g8: u8, b8: u8) -> Self {
        let b1 = (r8 & 0xF8) | (g8 >> 5);
        let b2 = ((g8 & 0xFA) << 3) | (b8 >> 3);
        RawColor([b1, b2])
Astro's avatar
Astro committed
132
    }
133 134 135 136 137 138 139 140 141 142 143 144 145

    pub fn r8(&self) -> u8 {
        self.0[0] & 0xF8
    }

    pub fn g8(&self) -> u8 {
        ((self.0[0] & 0x7) << 5) |
        ((self.0[0] & 0xE) >> 3)
    }

    pub fn b8(&self) -> u8 {
        (self.0[1] & 0x1F) << 3
    }
Astro's avatar
Astro committed
146
}
Astro's avatar
Astro committed
147

Astro's avatar
Astro committed
148 149 150
impl PixelColor for RawColor {}

/// Most similar format, just byte-swapped
Astro's avatar
Astro committed
151 152 153 154 155 156
impl From<Rgb565> for RawColor {
    fn from(rgb: Rgb565) -> Self {
        let c = rgb.0;
        RawColor([(c >> 8) as u8, c as u8])
    }
}
Astro's avatar
Astro committed
157 158 159 160 161 162 163

/// Dummy implementation required for impl Drawable
impl From<u8> for RawColor {
    fn from(b: u8) -> Self {
        RawColor([0, b])
    }
}