add font.rs
This commit is contained in:
parent
28d06825ce
commit
8d9f1ffbe9
90
src/font.rs
Normal file
90
src/font.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use embedded_hal::delay::DelayNs;
|
||||||
|
use esp_hal::DriverMode;
|
||||||
|
use rusttype::{Font, Point, Scale};
|
||||||
|
|
||||||
|
use alloc::string::String;
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
use crate::display::{self, Display, Position, Rgb565};
|
||||||
|
|
||||||
|
static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf");
|
||||||
|
|
||||||
|
pub struct FontRenderer<'a> {
|
||||||
|
font: Font<'a>,
|
||||||
|
height: u32,
|
||||||
|
scale: Scale,
|
||||||
|
offset: Point<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FontRenderer<'a> {
|
||||||
|
pub fn create(size: u32) -> FontRenderer<'a> {
|
||||||
|
let font = Font::try_from_bytes(OPEN_SANS).unwrap();
|
||||||
|
let scale = Scale {
|
||||||
|
x: size as f32 * 2.,
|
||||||
|
y: size as f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
let v_metrics = font.v_metrics(scale);
|
||||||
|
let offset = rusttype::Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: v_metrics.ascent,
|
||||||
|
};
|
||||||
|
FontRenderer {
|
||||||
|
font,
|
||||||
|
height: size,
|
||||||
|
scale,
|
||||||
|
offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render<'d, T: Into<String>, DM: DriverMode, Delay: DelayNs>(
|
||||||
|
&self,
|
||||||
|
display: &mut Display<'d, DM, Delay>,
|
||||||
|
text: T,
|
||||||
|
pos: Position,
|
||||||
|
) {
|
||||||
|
let glyphs = self
|
||||||
|
.font
|
||||||
|
.layout(&text.into(), self.scale, self.offset)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let width = libm::ceil(
|
||||||
|
glyphs
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.map(|g| g.position().x as f32 + g.unpositioned().h_metrics().advance_width)
|
||||||
|
.next()
|
||||||
|
.unwrap_or(0.0) as f64,
|
||||||
|
) as usize;
|
||||||
|
|
||||||
|
let mut pixel_data = vec![Rgb565::white(); self.height as usize * width];
|
||||||
|
|
||||||
|
for g in glyphs {
|
||||||
|
if let Some(bb) = g.pixel_bounding_box() {
|
||||||
|
g.draw(|x, y, cov| {
|
||||||
|
let x = bb.min.x + x as i32;
|
||||||
|
let y = bb.min.y + y as i32;
|
||||||
|
if x >= 0 && y >= 0 && x < width as i32 && y < self.height as i32 {
|
||||||
|
let col = 255 - (255. * cov) as u8;
|
||||||
|
pixel_data[(x + y * width as i32) as usize] = Rgb565(col, col, col);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display.set_window(
|
||||||
|
pos,
|
||||||
|
Position {
|
||||||
|
x: pos.x + width as u16 - 1,
|
||||||
|
y: pos.y + self.height as u16 - 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
display.write(display::Writeable::Data(
|
||||||
|
&pixel_data
|
||||||
|
.iter()
|
||||||
|
.flat_map(|p| p.as_color().bytes)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/main.rs
62
src/main.rs
@ -22,7 +22,10 @@ use esp_hal::{
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use rusttype::Font;
|
use rusttype::Font;
|
||||||
|
|
||||||
use crate::display::{Color, Display, Position, Rgb565, SetAddressMode};
|
use crate::{
|
||||||
|
display::{Color, Display, Position, Rgb565, SetAddressMode},
|
||||||
|
font::FontRenderer,
|
||||||
|
};
|
||||||
use esp_alloc::HEAP;
|
use esp_alloc::HEAP;
|
||||||
|
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
@ -30,6 +33,7 @@ use alloc::vec;
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
|
mod font;
|
||||||
|
|
||||||
static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf");
|
static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf");
|
||||||
|
|
||||||
@ -106,65 +110,13 @@ fn main() -> ! {
|
|||||||
Rgb565::yellow().as_color(),
|
Rgb565::yellow().as_color(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let font = Font::try_from_bytes(OPEN_SANS).unwrap();
|
let font_renderer = FontRenderer::create(30);
|
||||||
let glyph = font.glyph('a');
|
|
||||||
const SCALE: u16 = 30;
|
|
||||||
let scale = rusttype::Scale {
|
|
||||||
x: SCALE as f32 * 2.,
|
|
||||||
y: SCALE as f32,
|
|
||||||
};
|
|
||||||
let v_metrics = font.v_metrics(scale);
|
|
||||||
let offset = rusttype::Point {
|
|
||||||
x: 0.0,
|
|
||||||
y: v_metrics.ascent,
|
|
||||||
};
|
|
||||||
let glyphs = font
|
|
||||||
.layout("Hello world", scale, offset)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let width = libm::ceil(
|
font_renderer.render(&mut display, "Hello World!", Position::new(0, 0));
|
||||||
glyphs
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.map(|g| g.position().x as f32 + g.unpositioned().h_metrics().advance_width)
|
|
||||||
.next()
|
|
||||||
.unwrap_or(0.0) as f64,
|
|
||||||
) as usize;
|
|
||||||
|
|
||||||
let mut pixel_data = vec![Rgb565::white(); SCALE as usize * width];
|
|
||||||
|
|
||||||
for g in glyphs {
|
|
||||||
if let Some(bb) = g.pixel_bounding_box() {
|
|
||||||
g.draw(|x, y, cov| {
|
|
||||||
let x = bb.min.x + x as i32;
|
|
||||||
let y = bb.min.y + y as i32;
|
|
||||||
if x >= 0 && y >= 0 && x < width as i32 && y < SCALE as i32 {
|
|
||||||
let col = 255 - (255. * cov) as u8;
|
|
||||||
pixel_data[(x + y * width as i32) as usize] = Rgb565(col, col, col);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
display.set_window(
|
|
||||||
Position { x: 0, y: 0 },
|
|
||||||
Position {
|
|
||||||
x: width as u16 - 1,
|
|
||||||
y: SCALE as u16 - 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
display.write(display::Writeable::Data(
|
|
||||||
&pixel_data
|
|
||||||
.iter()
|
|
||||||
.flat_map(|p| p.as_color().bytes)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
));
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let delay_start = Instant::now();
|
let delay_start = Instant::now();
|
||||||
|
|
||||||
log::info!("Hello world");
|
|
||||||
|
|
||||||
while delay_start.elapsed() < Duration::from_millis(100) {}
|
while delay_start.elapsed() < Duration::from_millis(100) {}
|
||||||
// test_delay.delay_millis(1);
|
// test_delay.delay_millis(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user