diff --git a/src/font.rs b/src/font.rs index 1785783..006e64f 100644 --- a/src/font.rs +++ b/src/font.rs @@ -1,10 +1,11 @@ +use alloc::string::ToString; use embedded_hal::delay::DelayNs; use esp_hal::DriverMode; use rusttype::{Font, Point, PositionedGlyph, Scale}; -use alloc::vec; use alloc::vec::Vec; use alloc::{borrow::ToOwned, string::String}; +use alloc::{format, vec}; use crate::display::{self, Display, Position, Rgb565}; @@ -66,9 +67,46 @@ impl<'a> FontRenderer<'a> { v_align: VerticalAlignment, bg: Rgb565, fg: Rgb565, + wrap_text: bool, ) { let text = text.into(); - let rows = text.split("\n").collect::>(); + let mut rows = text.split("\n").map(|v| v.to_string()).collect::>(); + + if wrap_text { + let mut i = 0; + while i < rows.len() { + let row = &rows[i]; + let mut parts = row.split(" ").into_iter(); + + let mut replaced = String::new(); + let mut overflow: Option = None; + replaced += parts.next().unwrap(); + while let Some(part) = parts.next() { + let data = self.prepare(format!("{} {}", replaced, part)); + log::info!("text: {}, width: {}", replaced, data.pixel_width); + if data.pixel_width > 240 { + overflow = Some(part.to_owned()); + break; + } + replaced += &format!(" {}", part); + } + while let Some(part) = parts.next() { + if let Some(overflowed) = overflow { + overflow = Some(format!("{} {}", overflowed, part)); + } else { + overflow = Some(part.to_owned()) + } + } + + rows[i] = replaced; + if let Some(overflow) = overflow { + rows.insert(i + 1, overflow); + } + i += 1; + } + } + + log::info!("{:?}", rows); let start_y = match v_align { VerticalAlignment::TopToBottom => position.y, diff --git a/src/main.rs b/src/main.rs index d62f670..17279b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -155,6 +155,7 @@ fn main() -> ! { font::VerticalAlignment::Center, Rgb565::black(), Rgb565::white(), + false, ); at_commands.init(); diff --git a/src/state.rs b/src/state.rs index 32ff0e4..635f691 100644 --- a/src/state.rs +++ b/src/state.rs @@ -14,6 +14,7 @@ pub struct TextSettings { pub v_align: VerticalAlignment, pub fg: Rgb565, pub bg: Rgb565, + pub wrap: bool, } impl Default for TextSettings { @@ -23,10 +24,39 @@ impl Default for TextSettings { v_align: VerticalAlignment::TopToBottom, fg: Rgb565::white(), bg: Rgb565::black(), + wrap: false, } } } +impl TextSettings { + pub fn with_horizontal_align(self, align: HorizontalAlignment) -> TextSettings { + TextSettings { + h_align: align, + ..self + } + } + + pub fn with_vertical_align(self, align: VerticalAlignment) -> TextSettings { + TextSettings { + v_align: align, + ..self + } + } + + pub fn with_fg(self, color: Rgb565) -> TextSettings { + TextSettings { fg: color, ..self } + } + + pub fn with_bg(self, color: Rgb565) -> TextSettings { + TextSettings { bg: color, ..self } + } + + pub fn with_wrap(self, wrap: bool) -> TextSettings { + TextSettings { wrap, ..self } + } +} + #[derive(PartialEq, Eq, Clone)] pub enum DrawCommands { Clear(Color), @@ -108,6 +138,7 @@ impl<'a> StateManager<'a> { text_settings.v_align, text_settings.bg, text_settings.fg, + text_settings.wrap, ) } } diff --git a/src/states.rs b/src/states.rs index 66e7d2b..731a2fc 100644 --- a/src/states.rs +++ b/src/states.rs @@ -465,7 +465,7 @@ impl State for ReadMessageState { data.draw_text( self.message.text.clone(), Position::new(0, 30), - TextSettings::default(), + TextSettings::default().with_wrap(true), ); } }