Add support for multiline rendering

This commit is contained in:
Sofia 2026-05-16 20:07:58 +03:00
parent e06ce690cb
commit 15302ea96b
2 changed files with 24 additions and 17 deletions

View File

@ -2,9 +2,9 @@ use embedded_hal::delay::DelayNs;
use esp_hal::DriverMode; use esp_hal::DriverMode;
use rusttype::{Font, Point, PositionedGlyph, Scale}; use rusttype::{Font, Point, PositionedGlyph, Scale};
use alloc::string::String;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::{borrow::ToOwned, string::String};
use crate::display::{self, Display, Position, Rgb565}; use crate::display::{self, Display, Position, Rgb565};
@ -63,23 +63,30 @@ impl<'a> FontRenderer<'a> {
h_align: HorizontalAlignment, h_align: HorizontalAlignment,
v_align: VerticalAlignment, v_align: VerticalAlignment,
) { ) {
let data = self.prepare(text.into()); let text = text.into();
let rows = text.split("\n").collect::<Vec<&str>>();
let start_y = match v_align {
VerticalAlignment::TopToBottom => position.y,
VerticalAlignment::Center => position.y - (self.height as i16 * rows.len() as i16) / 2,
VerticalAlignment::BottomToTop => position.y - (self.height as i16 * rows.len() as i16),
};
for (i, row) in rows.iter().enumerate() {
let data = self.prepare((*row).to_owned());
let x = match h_align { let x = match h_align {
HorizontalAlignment::RightToLeft => position.x - data.pixel_width as i16, HorizontalAlignment::RightToLeft => position.x - data.pixel_width as i16,
HorizontalAlignment::Center => position.x - (data.pixel_width as i16 / 2), HorizontalAlignment::Center => position.x - (data.pixel_width as i16 / 2),
HorizontalAlignment::LeftToRight => position.x, HorizontalAlignment::LeftToRight => position.x,
}; };
let y = match v_align { let y = start_y + (self.height * i as u32) as i16;
VerticalAlignment::BottomToTop => position.y - self.height as i16,
VerticalAlignment::Center => position.y - (self.height as i16 / 2),
VerticalAlignment::TopToBottom => position.y,
};
self.raw_render(display, data, Position { x, y }); self.raw_render(display, data, Position { x, y });
} }
}
pub fn prepare(&self, text: String) -> RawRenderData<'a> { fn prepare(&self, text: String) -> RawRenderData<'a> {
let glyphs = self let glyphs = self
.font .font
.layout(&text, self.scale, self.offset) .layout(&text, self.scale, self.offset)
@ -100,7 +107,7 @@ impl<'a> FontRenderer<'a> {
} }
} }
pub fn raw_render<'d, DM: DriverMode, Delay: DelayNs>( fn raw_render<'d, DM: DriverMode, Delay: DelayNs>(
&self, &self,
display: &mut Display<'d, DM, Delay>, display: &mut Display<'d, DM, Delay>,
data: RawRenderData<'a>, data: RawRenderData<'a>,

View File

@ -113,10 +113,10 @@ fn main() -> ! {
font_renderer.render( font_renderer.render(
&mut display, &mut display,
"Hello World!", "Hello\nWorld!",
Position::new(120, 120), Position::new(0, 0),
HorizontalAlignment::Center, HorizontalAlignment::LeftToRight,
VerticalAlignment::Center, VerticalAlignment::TopToBottom,
); );
let sim_rst = Output::new(peripherals.GPIO15, Level::High, OutputConfig::default()); let sim_rst = Output::new(peripherals.GPIO15, Level::High, OutputConfig::default());