clock_tui/clock_text/font/
bricks.rs

1
2use ratatui::{buffer::Buffer, style::Style};
3
4use crate::clock_text::point::Point;
5
6use super::Font;
7
8pub struct BricksFont {
9    pub size: u16,
10}
11
12impl BricksFont {
13    pub fn new(size: u16) -> Self {
14        Self { size }
15    }
16
17    /// each row is represented with a vector of numbers:
18    ///   the odd indexed items represent the lenght of "off",
19    ///   the even indexed items represent the lenght of "on".
20    /// For exmaple:
21    ///   vec![0, 6] is  "██████"
22    ///   vec![2, 2] is  "  ██"
23    ///   vec![0, 2, 2, 2] is  "██  ██"
24    fn draw_row(
25        start: Point,
26        row: Vec<u16>,
27        size: u16,
28        style: Style,
29        area_right: u16,
30        area_bottom: u16,
31        buf: &mut Buffer,
32    ) {
33        let mut p = start;
34        let mut on = false;
35        for len in row {
36            let len = len * size;
37            if p.0 > area_right {
38                break;
39            }
40
41            if on {
42                let s = std::cmp::min(len, area_right - p.0 + 1);
43                let line = "█".repeat(s as usize);
44                for r in 0..size {
45                    if p.1 > area_bottom {
46                        break;
47                    }
48                    buf.set_string(p.0, p.1 + r, line.as_str(), style);
49                }
50            }
51
52            p.0 += len;
53            on = !on;
54        }
55    }
56
57    fn get_char_matrix(c: char) -> Option<[Vec<u16>; 5]> {
58        match c {
59            '0' => Some([
60                vec![0, 6],
61                vec![0, 2, 2, 2],
62                vec![0, 2, 2, 2],
63                vec![0, 2, 2, 2],
64                vec![0, 6],
65            ]),
66            '1' => Some([vec![0, 4], vec![2, 2], vec![2, 2], vec![2, 2], vec![0, 6]]),
67            '2' => Some([vec![0, 6], vec![4, 2], vec![0, 6], vec![0, 2], vec![0, 6]]),
68            '3' => Some([vec![0, 6], vec![4, 2], vec![0, 6], vec![4, 2], vec![0, 6]]),
69            '4' => Some([
70                vec![0, 2, 2, 2],
71                vec![0, 2, 2, 2],
72                vec![0, 6],
73                vec![4, 2],
74                vec![4, 2],
75            ]),
76            '5' => Some([vec![0, 6], vec![0, 2], vec![0, 6], vec![4, 2], vec![0, 6]]),
77            '6' => Some([
78                vec![0, 6],
79                vec![0, 2],
80                vec![0, 6],
81                vec![0, 2, 2, 2],
82                vec![0, 6],
83            ]),
84            '7' => Some([vec![0, 6], vec![4, 2], vec![4, 2], vec![4, 2], vec![4, 2]]),
85            '8' => Some([
86                vec![0, 6],
87                vec![0, 2, 2, 2],
88                vec![0, 6],
89                vec![0, 2, 2, 2],
90                vec![0, 6],
91            ]),
92            '9' => Some([
93                vec![0, 6],
94                vec![0, 2, 2, 2],
95                vec![0, 6],
96                vec![4, 2],
97                vec![0, 6],
98            ]),
99            ':' => Some([vec![], vec![2, 2], vec![], vec![2, 2], vec![]]),
100            '.' => Some([vec![], vec![], vec![], vec![], vec![2, 2]]),
101            '-' => Some([vec![], vec![], vec![0, 6], vec![], vec![]]),
102            _ => None,
103        }
104    }
105}
106
107impl Font for BricksFont {
108    fn get_char(&self, _c: char) -> Option<&[Point]> {
109        None // We don't use points for BricksFont
110    }
111
112    fn get_char_width(&self) -> u16 {
113        6 * self.size
114    }
115
116    fn get_char_height(&self) -> u16 {
117        5 * self.size
118    }
119
120    fn draw_char(&self, c: char, x: u16, y: u16, style: Style, buf: &mut Buffer) {
121        if let Some(matrix) = Self::get_char_matrix(c) {
122            let mut start = Point(x, y);
123            let area_right = buf.area.right();
124            let area_bottom = buf.area.bottom();
125            for row in matrix {
126                Self::draw_row(start, row, self.size, style, area_right, area_bottom, buf);
127                start.1 += self.size;
128            }
129        }
130    }
131}