First implementation of font renderer.
This commit is contained in:
parent
acfba93c0b
commit
9594f01a4d
|
@ -28,6 +28,7 @@ mod logo;
|
|||
use printer::UsartPrinter;
|
||||
use st7735::gfx::{PrimitveGFX, GFX};
|
||||
use st7735::bitmaps::BitmapGFX;
|
||||
use st7735::fonts::FontRenderer;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
use st7735::gfx::PrimitveGFX;
|
||||
|
||||
pub struct FontGlpyh {
|
||||
pub bitmap_offset: usize, // Offset in glyph bitmap
|
||||
pub width: u8, // Size of glyph
|
||||
pub height: u8,
|
||||
pub x_advance: u8, // Distance to advance along x-axis
|
||||
pub x_offset: u8, // Distance to upper left coner from cursor pos
|
||||
pub y_offset: u8,
|
||||
}
|
||||
|
||||
|
||||
pub struct Font {
|
||||
pub bitmap: &'static [u8], // Glyph bitmaps, concatenated
|
||||
pub glyphs: &'static [FontGlpyh], // Array of glyph metadata
|
||||
pub first: u8, // Start of ASCII extend
|
||||
pub last: u8, // End of ASCII extend
|
||||
pub y_advance: u8, // Line height
|
||||
}
|
||||
|
||||
|
||||
pub trait FontRenderer: PrimitveGFX {
|
||||
fn draw_glyph(&mut self, x: u8, y: u8, glyph: &FontGlpyh, font: &Font, size: u8, color: u16) {
|
||||
if size == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Any clipping should be done by draw_rect
|
||||
|
||||
let x = x as i16;
|
||||
let y = y as i16;
|
||||
let size = size as i16;
|
||||
|
||||
let mut bo = glyph.bitmap_offset;
|
||||
let mut set_pixels: i16 = 0;
|
||||
let mut bits: u8 = 0;
|
||||
let mut bit: u8 = 0;
|
||||
|
||||
for cur_y in 0..(glyph.height as i16) {
|
||||
for cur_x in 0..(glyph.width as i16) {
|
||||
if bit == 0 {
|
||||
bits = font.bitmap[bo];
|
||||
bo += 1;
|
||||
bit = 0x80;
|
||||
}
|
||||
|
||||
if bit & bits != 0 {
|
||||
set_pixels += 1;
|
||||
} else if set_pixels > 0 {
|
||||
let start_x = (x + ((glyph.x_offset as i16) + cur_x - set_pixels) * size) as u8;
|
||||
let start_y = (y + ((glyph.y_offset as i16) + cur_y) * size) as u8;
|
||||
let w = (set_pixels * size) as u8;
|
||||
let h = size as u8;
|
||||
self.fill_rect(start_x, start_y, w, h, color);
|
||||
|
||||
set_pixels = 0;
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
|
||||
if set_pixels > 0 {
|
||||
let start_x = (x +
|
||||
((glyph.x_offset as i16) + (glyph.width as i16) -
|
||||
set_pixels) * size) as u8;
|
||||
let start_y = (y + ((glyph.y_offset as i16) + cur_y) * size) as u8;
|
||||
let w = (set_pixels * size) as u8;
|
||||
let h = size as u8;
|
||||
self.fill_rect(start_x, start_y, w, h, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_text(&mut self, x: u8, y: u8, text: &str, font: &Font, size: u8, color: u16) {
|
||||
let mut cursor_x = x;
|
||||
let mut cursor_y = y;
|
||||
|
||||
for text_char in text.chars() {
|
||||
let c = if text_char.is_ascii() {
|
||||
text_char as u8
|
||||
}
|
||||
else {
|
||||
'?' as u8
|
||||
};
|
||||
|
||||
if c == '\n' as u8 {
|
||||
cursor_x = x;
|
||||
cursor_y += font.y_advance * size;
|
||||
}
|
||||
else if c >= font.first && c <= font.last && c != '\r' as u8 {
|
||||
let pos = (c - font.first) as usize;
|
||||
let glyph = &font.glyphs[pos];
|
||||
self.draw_glyph(cursor_x, cursor_y, glyph, &font, size, color);
|
||||
cursor_x += glyph.x_advance * size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ mod commands;
|
|||
mod init;
|
||||
pub mod gfx;
|
||||
pub mod bitmaps;
|
||||
pub mod fonts;
|
||||
|
||||
use st7735::commands::*;
|
||||
|
||||
|
@ -591,6 +592,9 @@ impl<SPIAddr, GPIOAddr> bitmaps::BitmapGFX for St7735IO<SPIAddr, GPIOAddr>
|
|||
self.set_cs();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl<SPIAddr, GPIOAddr> fonts::FontRenderer for St7735IO<SPIAddr, GPIOAddr>
|
||||
where SPIAddr: Location,
|
||||
GPIOAddr: Location {}
|
||||
|
|
Loading…
Reference in New Issue