From 15302ea96b07862024953c886c9782d64776c7db Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 16 May 2026 20:07:58 +0300 Subject: [PATCH] Add support for multiline rendering --- src/font.rs | 33 ++++++++++++++++++++------------- src/main.rs | 8 ++++---- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/font.rs b/src/font.rs index 3958a8a..d82d325 100644 --- a/src/font.rs +++ b/src/font.rs @@ -2,9 +2,9 @@ use embedded_hal::delay::DelayNs; use esp_hal::DriverMode; use rusttype::{Font, Point, PositionedGlyph, Scale}; -use alloc::string::String; use alloc::vec; use alloc::vec::Vec; +use alloc::{borrow::ToOwned, string::String}; use crate::display::{self, Display, Position, Rgb565}; @@ -63,23 +63,30 @@ impl<'a> FontRenderer<'a> { h_align: HorizontalAlignment, v_align: VerticalAlignment, ) { - let data = self.prepare(text.into()); + let text = text.into(); + let rows = text.split("\n").collect::>(); - let x = match h_align { - HorizontalAlignment::RightToLeft => position.x - data.pixel_width as i16, - HorizontalAlignment::Center => position.x - (data.pixel_width as i16 / 2), - HorizontalAlignment::LeftToRight => position.x, - }; - let y = match v_align { - VerticalAlignment::BottomToTop => position.y - self.height as i16, - VerticalAlignment::Center => position.y - (self.height as i16 / 2), + 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), }; - self.raw_render(display, data, Position { x, y }); + for (i, row) in rows.iter().enumerate() { + let data = self.prepare((*row).to_owned()); + + let x = match h_align { + HorizontalAlignment::RightToLeft => position.x - data.pixel_width as i16, + HorizontalAlignment::Center => position.x - (data.pixel_width as i16 / 2), + HorizontalAlignment::LeftToRight => position.x, + }; + let y = start_y + (self.height * i as u32) as i16; + + 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 .font .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, display: &mut Display<'d, DM, Delay>, data: RawRenderData<'a>, diff --git a/src/main.rs b/src/main.rs index 2dda463..c1fcb21 100644 --- a/src/main.rs +++ b/src/main.rs @@ -113,10 +113,10 @@ fn main() -> ! { font_renderer.render( &mut display, - "Hello World!", - Position::new(120, 120), - HorizontalAlignment::Center, - VerticalAlignment::Center, + "Hello\nWorld!", + Position::new(0, 0), + HorizontalAlignment::LeftToRight, + VerticalAlignment::TopToBottom, ); let sim_rst = Output::new(peripherals.GPIO15, Level::High, OutputConfig::default());