use crate::{
primitives::{Point, Size},
view::HorizontalTextAlignment,
};
#[derive(Debug, Clone, PartialEq)]
pub struct OwnedText<'a, const N: usize, F> {
pub origin: Point,
pub size: Size,
pub font: &'a F,
pub text: heapless::String<N>,
pub alignment: HorizontalTextAlignment,
}
#[cfg(feature = "embedded-graphics")]
mod embedded_graphics_impl {
use super::{OwnedText, Point};
use crate::font::FontLayout as _;
use crate::render::{AnimationDomain, EmbeddedGraphicsRender};
use crate::{pixel::Interpolate, view::WhitespaceWrap};
use embedded_graphics_core::Drawable;
use embedded_graphics::{
mono_font::{MonoFont, MonoTextStyle},
prelude::PixelColor,
};
use embedded_graphics_core::draw_target::DrawTarget;
impl<C: PixelColor, const N: usize> EmbeddedGraphicsRender<C> for OwnedText<'_, N, MonoFont<'_>> {
fn render(&self, render_target: &mut impl DrawTarget<Color = C>, style: &C, offset: Point) {
if self.size.area() == 0 {
return;
}
let origin = self.origin + offset;
let line_height = self.font.line_height() as i16;
let baseline = self.font.baseline() as i16;
let style = MonoTextStyle::new(self.font, *style);
let mut height = 0;
let wrap = WhitespaceWrap::new(&self.text, self.size.width, self.font);
for line in wrap {
let width = self.font.str_width(line);
let x = self.alignment.align(self.size.width as i16, width as i16);
let txt_start = origin + Point::new(x, height + baseline);
_ = embedded_graphics::text::Text::new(line, txt_start.into(), style)
.draw(render_target);
height += line_height;
if height >= self.size.height as i16 {
break;
}
}
}
fn join(source: Self, mut target: Self, config: &AnimationDomain) -> Self {
let x = i16::interpolate(source.origin.x, target.origin.x, config.factor);
let y = i16::interpolate(source.origin.y, target.origin.y, config.factor);
target.origin = Point::new(x, y);
target
}
}
}