Commit 29a6b351 authored by Astro's avatar Astro
Browse files

l0dable: framebuffer text rendering works (inverted)

parent a614d38e
......@@ -36,6 +36,11 @@ fn main() {
.file("../c/l0dables/lib/hardware.c")
.file("../c/epicardium/api/caller.c")
.file("src/client.c")
.file("../c/lib/gfx/Fonts/font12.c")
.file("../c/lib/gfx/Fonts/font16.c")
.file("../c/lib/gfx/Fonts/font20.c")
.file("../c/lib/gfx/Fonts/font24.c")
.file("../c/lib/gfx/Fonts/font8.c")
.compile("card10");
println!("cargo:rerun-if-changed=src/client.rs");
......
use core::slice::from_raw_parts;
extern "C" {
static Font8: Font;
static Font12: Font;
static Font16: Font;
static Font20: Font;
static Font24: Font;
}
#[repr(C)]
pub struct Font {
table: *const u8,
pub w: u16,
pub h: u16,
}
impl Font {
pub fn font8() -> &'static Self {
unsafe { &Font8 }
}
pub fn font12() -> &'static Self {
unsafe { &Font12 }
}
pub fn font16() -> &'static Self {
unsafe { &Font16 }
}
pub fn font20() -> &'static Self {
unsafe { &Font20 }
}
pub fn font24() -> &'static Self {
unsafe { &Font24 }
}
fn bytes_per_row(&self) -> usize {
self.w as usize / 8 + 1
}
pub fn get_glyph(&self, c: char) -> Option<Glyph> {
let h = self.h as usize;
let bytes_per_row = self.bytes_per_row();
let table = unsafe {
from_raw_parts(self.table, ('~' as usize - (' ' as usize) - 1) * bytes_per_row * h)
};
let offset = (c as usize - (' ' as usize)) * bytes_per_row * h;
if offset < table.len() {
let table = &table[offset..(offset + bytes_per_row * h)];
Some(Glyph {
table,
bytes_per_row,
})
} else {
None
}
}
}
pub struct Glyph<'a> {
table: &'a [u8],
bytes_per_row: usize,
}
impl<'a> Glyph<'a> {
pub fn get_pixel(&self, x: usize, y: usize) -> bool {
let offset = x / 8 + y * self.bytes_per_row;
self.table[offset] & (1 << (7 - (x & 7))) != 0
}
}
......@@ -3,6 +3,11 @@ use core::ops::{Deref, DerefMut};
use crate::bindings::*;
use crate::{Color, Display};
mod font;
pub use font::*;
mod text;
pub use text::TextRenderer;
pub struct FrameBuffer<'d> {
_display: &'d Display,
buffer: disp_framebuffer,
......@@ -24,6 +29,13 @@ impl<'d> FrameBuffer<'d> {
epic_disp_framebuffer(&mut self.buffer);
}
}
pub fn text<'a, 'f>(&'a mut self, x: isize, y: isize, font: &'f Font, color: Color) -> TextRenderer<'a, 'd, 'f> {
TextRenderer {
framebuffer: self,
x, y, font, color,
}
}
}
impl<'d> Deref for FrameBuffer<'d> {
......
use core::fmt::Write;
use super::{FrameBuffer, Font};
use crate::{Color, Display};
pub struct TextRenderer<'a, 'd, 'f> {
pub framebuffer: &'a mut FrameBuffer<'d>,
pub x: isize,
pub y: isize,
pub font: &'f Font,
pub color: Color,
}
impl<'a, 'd, 'f> Write for TextRenderer<'a, 'd, 'f> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
for c in s.chars() {
self.write_char(c)?;
}
Ok(())
}
fn write_char(&mut self, c: char) -> core::fmt::Result {
match self.font.get_glyph(c) {
None => Ok(()),
Some(glyph) => {
for y in 0..self.font.h {
let y1 = self.y + y as isize;
if y1 >= 0 && y1 < Display::H as isize {
for x in 0..self.font.w {
let x1 = self.x + x as isize;
if x1 >= 0 && x1 < Display::W as isize {
if glyph.get_pixel(x as usize, y as usize) {
self.framebuffer[y1 as usize][x1 as usize] = self.color;
}
}
}
}
}
self.x += self.font.w as isize;
Ok(())
}
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment