rpi_led_matrix/
font.rs

1use std::ffi::CString;
2use std::path::Path;
3
4use crate::ffi;
5
6/// The Rust handle for [`LedFont`].
7pub struct LedFont {
8    pub(crate) handle: *mut ffi::CLedFont,
9}
10
11impl LedFont {
12    /// Creates a new [`LedFont`] instance with the given bdf filepath, if it exists.
13    ///
14    /// # Errors
15    /// - If the given `bdf_file` path fails to convert to a string. This can
16    ///   occur when there is a null character mid way in the string.
17    /// - If the C++ library returns us a null pointer when loading the font.
18    pub fn new(bdf_file: &Path) -> Result<Self, &'static str> {
19        let string = match bdf_file.to_str() {
20            Some(s) => s,
21            None => return Err("Couldn't convert path to str"),
22        };
23        let string = if let Ok(string) = CString::new(string) {
24            string
25        } else {
26            return Err("Failed to convert path to CString");
27        };
28
29        let handle = unsafe { ffi::load_font(string.as_ptr()) };
30
31        if handle.is_null() {
32            Err("Couldn't load font")
33        } else {
34            Ok(Self { handle })
35        }
36    }
37}
38
39impl Drop for LedFont {
40    fn drop(&mut self) {
41        unsafe { ffi::delete_font(self.handle) }
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use super::*;
48    use crate::{LedColor, LedMatrix};
49    use std::{thread, time};
50
51    #[test]
52    #[serial_test::serial]
53    fn draw_text() {
54        let matrix = LedMatrix::new(None, None).unwrap();
55        let mut canvas = matrix.canvas();
56        let font = LedFont::new(Path::new("/usr/share/fonts/misc/10x20.bdf")).unwrap();
57        let color = LedColor {
58            red: 0,
59            green: 127,
60            blue: 0,
61        };
62        let (width, height) = canvas.canvas_size();
63        let text_width = 10 * 9;
64        let baseline = height / 2;
65
66        canvas = matrix.offscreen_canvas();
67        for x in 0..(2 * width) {
68            let x = x % (10 * 9);
69            canvas.clear();
70            canvas.draw_text(&font, "Mah boy! ", x, baseline, &color, 0, false);
71            canvas.draw_text(
72                &font,
73                "Mah boy! ",
74                x - text_width,
75                baseline,
76                &color,
77                0,
78                false,
79            );
80            canvas.draw_text(
81                &font,
82                "Mah boy! ",
83                x + text_width,
84                baseline,
85                &color,
86                0,
87                false,
88            );
89            canvas = matrix.swap(canvas);
90            thread::sleep(time::Duration::new(0, 50000000));
91        }
92    }
93}