This library uses font-rs and stb_truetype to render truetype fonts und print them to screen.
Include font_render as dependency in your Cargo.toml:
[dependencies]
font_render = {git = "https://github.com/Rust-Mikrocontroller-Praktikum-2017/font_render.git"}and link it to your crate through extern crate font_render.
Now you can create a Lcd::text_writer method in src/lcd/mod.rs:
use font_render;
pub struct Writer<'a> {
lcd: &'a mut Lcd,
text_writer: font_render::TextWriter<'a>,
}
impl Lcd {
...
pub fn text_writer(&mut self) -> Result<Writer, font_render::Error> {
Ok(Writer {
lcd: self,
text_writer: font_render::TextWriter::default(),
})
}
}The text_writer method returns a new Writer struct that uses a default TextWriter. The default is using the bold Roboto Mono font with size 11 and wrapping at 480 pixels (display width). If you want to use your own parameters, you can use the new method instead of default.
In order to print strings, we add the following methods to our new Writer struct:
impl<'a> Writer<'a> {
pub fn print_char(&mut self, c: char) {
let &mut Self { ref mut text_writer, ref mut lcd} = self;
text_writer.print_char(c, |coords, value| {
let color = ((value as u16) << 8) | 0xff;
lcd.print_point_color_at(coords.x as u16, coords.y as u16, color);
});
}
pub fn print_str(&mut self, s: &str) {
for c in s.chars() {
self.print_char(c);
}
}
}Now we can print characters and strings to the LCD. The text_writer.print_char method takes a closure that is passed the pixel coordinates and the transparency value. From this value, we calculate a color and print it to screen using lcd.print_point_color_at.
Fonts only look good with transparency support, so we change our color format to AL88 (one byte alpha, one byte luminance):
// in src/lcd/init.rs near line 116
ltdc.l2pfcr.update(|r| r.set_pf(0b111)); // set_pixel_format to AL88So we change the 0b011 (for ARGB1555) to 0b111 (for AL88).
Unfortunately this means that we can't really display colors anymore. To solve this, you could switch to a 4 byte color format such as ARGB888 (0b000), but this means that you have to rewrite the LCD methods (including print_point_at and print_point_color_at). Pull requests welcome!
To support Rust's writeln macro, we can implement the core::fmt::Write trait:
use core::fmt;
impl<'a> fmt::Write for Writer<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.print_str(s);
Ok(())
}
}Now we can print from our main:
use core::fmt::Write;
let mut text_writer = lcd.text_writer().unwrap();
text_writer.print_str("Hello World!\n");
writeln!(&mut text_writer, "Using formatting macros {} {} {:?}", 42, 3.14, &[1,2,3,4]);Note that you can't use the lcd struct directly as long as the Writer instance exists. To drop it earlier, you can put it into an additional block:
{
let mut text_writer = lcd.text_writer().unwrap();
// text_writer is valid here, but lcd is not
}
// lcd is valid againThis doesn't work in --release mode currently due to linker errors.