1use crate::cell::{Cell, Flags};
2use crate::text_buffer::TextBuffer;
3use embedded_graphics::{
4 mono_font::{
5 iso_8859_1::{FONT_9X18 as FONT, FONT_9X18_BOLD as FONT_BOLD},
6 MonoTextStyleBuilder,
7 },
8 pixelcolor::Rgb888,
9 prelude::{DrawTarget, Drawable, Point, Size},
10 text::{Baseline, Text, TextStyle},
11};
12
13const CHAR_SIZE: Size = FONT.character_size;
14
15pub struct TextOnGraphic<D>
22where
23 D: DrawTarget,
24{
25 width: u32,
26 height: u32,
27 graphic: D,
28}
29
30impl<D> TextOnGraphic<D>
31where
32 D: DrawTarget,
33{
34 pub fn new(graphic: D, width: u32, height: u32) -> Self {
36 TextOnGraphic {
37 width,
38 height,
39 graphic,
40 }
41 }
42}
43
44impl<D> TextBuffer for TextOnGraphic<D>
45where
46 D: DrawTarget<Color = Rgb888>,
47{
48 #[inline]
49 fn width(&self) -> usize {
50 (self.width / CHAR_SIZE.width) as usize
51 }
52
53 #[inline]
54 fn height(&self) -> usize {
55 (self.height / CHAR_SIZE.height) as usize
56 }
57
58 fn read(&self, _row: usize, _col: usize) -> Cell {
59 unimplemented!("reading char from graphic is unsupported")
60 }
61
62 #[inline]
63 fn write(&mut self, row: usize, col: usize, cell: Cell) {
64 if row >= self.height() || col >= self.width() {
65 return;
66 }
67 let mut utf8_buf = [0u8; 8];
68 let s = cell.c.encode_utf8(&mut utf8_buf);
69 let (fg, bg) = if cell.flags.contains(Flags::INVERSE) {
70 (cell.bg, cell.fg)
71 } else {
72 (cell.fg, cell.bg)
73 };
74 let mut style = MonoTextStyleBuilder::new()
75 .text_color(fg.to_rgb())
76 .background_color(bg.to_rgb());
77 if cell.flags.contains(Flags::BOLD) {
78 style = style.font(&FONT_BOLD);
79 } else {
80 style = style.font(&FONT);
81 }
82 if cell.flags.contains(Flags::STRIKEOUT) {
83 style = style.strikethrough();
84 }
85 if cell.flags.contains(Flags::UNDERLINE) {
86 style = style.underline();
87 }
88 let text = Text::with_text_style(
89 s,
90 Point::new(
91 col as i32 * CHAR_SIZE.width as i32,
92 row as i32 * CHAR_SIZE.height as i32,
93 ),
94 style.build(),
95 TextStyle::with_baseline(Baseline::Top),
96 );
97 text.draw(&mut self.graphic).ok();
98 }
99}