1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
use crate::Display;
use card10_sys::*;
use core::mem::{transmute, uninitialized};
use core::ops::{Index, IndexMut};

use embedded_graphics::pixelcolor::{PixelColor, Rgb565};
use embedded_graphics::prelude::Pixel;
use embedded_graphics::Drawing;

mod font;
pub use font::*;
mod text;
pub use text::TextRenderer;

pub struct FrameBuffer<'d> {
    _display: &'d mut Display,
    buffer: disp_framebuffer,
}

impl<'d> FrameBuffer<'d> {
    pub fn uninitialized(display: &'d mut Display) -> Self {
        FrameBuffer {
            _display: display,
            buffer: unsafe { uninitialized() },
        }
    }

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

    pub fn clear(&mut self, color: RawColor) {
        for y in 0..Display::H {
            for x in 0..Display::W {
                let bytes: &mut RawColor =
                    unsafe { transmute(&mut self.buffer.fb[y as usize][x as usize]) };
                *bytes = color;
            }
        }
    }

    pub fn text<'a, 'f>(
        &'a mut self,
        x: isize,
        y: isize,
        font: &'f Font,
        color: RawColor,
    ) -> TextRenderer<'a, 'd, 'f> {
        TextRenderer {
            framebuffer: self,
            x,
            y,
            font,
            color,
        }
    }
}

impl<'d> Index<(u16, u16)> for FrameBuffer<'d> {
    type Output = RawColor;
    fn index(&self, (x, y): (u16, u16)) -> &Self::Output {
        let x = usize::from(Display::W - 1 - x);
        let y = usize::from(Display::H - 1 - y);
        unsafe { transmute(&self.buffer.fb[y][x]) }
    }
}

impl<'d> IndexMut<(u16, u16)> for FrameBuffer<'d> {
    fn index_mut(&mut self, (x, y): (u16, u16)) -> &mut Self::Output {
        let x = usize::from(Display::W - 1 - x);
        let y = usize::from(Display::H - 1 - y);
        unsafe { transmute(&mut self.buffer.fb[y][x]) }
    }
}

/// `embedded-graphics` support
impl<'d, C: PixelColor + Into<RawColor>> Drawing<C> for FrameBuffer<'d> {
    fn draw<T>(&mut self, item: T)
    where
        T: IntoIterator<Item = Pixel<C>>,
    {
        for Pixel(coord, color) in item {
            let x = coord[0] as u16;
            let y = coord[1] as u16;

            if x >= Display::W || y >= Display::H {
                continue;
            }
            // Swap bytes
            self[(x, y)] = color.into();
        }
    }
}

/// RGB565 with swapped bytes
#[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)
    }

    /// Construct from 0..255-triple
    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])
    }

    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
    }
}

impl PixelColor for RawColor {}

/// Most similar format, just byte-swapped
impl From<Rgb565> for RawColor {
    fn from(rgb: Rgb565) -> Self {
        let c = rgb.0;
        RawColor([(c >> 8) as u8, c as u8])
    }
}

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