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
#![no_std]
use core::convert::TryInto;
use embedded_graphics::{drawable::Pixel, pixelcolor::*, prelude::*, DrawTarget};
use uefi::proto::console::gop::*;
#[derive(Debug)]
pub struct Unsupported(());
pub struct UefiDisplay<'a> {
info: ModeInfo,
fb: FrameBuffer<'a>,
}
impl<'a> UefiDisplay<'a> {
pub fn new(info: ModeInfo, fb: FrameBuffer<'a>) -> Self {
Self { info, fb }
}
pub fn size(&self) -> Size {
let (width, height) = self.info.resolution();
Size::new(width.try_into().unwrap(), height.try_into().unwrap())
}
}
impl<'a, T: Into<Bgr888> + PixelColor> DrawTarget<T> for UefiDisplay<'a> {
type Error = Unsupported;
fn draw_pixel(&mut self, item: Pixel<T>) -> Result<(), Self::Error> {
let Pixel(point, color) = item;
let mut bytes = [0u8; 3];
match self.info.pixel_format() {
PixelFormat::RGB => {
bytes
.copy_from_slice(&Rgb888::from(color.into()).into_storage().to_be_bytes()[1..]);
}
PixelFormat::BGR => {
bytes.copy_from_slice(&color.into().into_storage().to_be_bytes()[1..]);
}
_ => return Err(Unsupported(())),
}
let Size { width, height } = <Self as DrawTarget<T>>::size(self);
let stride: u64 = self.info.stride().try_into().unwrap();
let (x, y) = (point.x as u64, point.y as u64);
if x < width.into() && y < height.into() {
let index: usize = (((y * stride) + x) * 4)
.try_into()
.expect("Framebuffer index overflowed usize");
unsafe { self.fb.write_value(index, bytes) };
}
Ok(())
}
fn size(&self) -> Size {
self.size()
}
}