1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use image::Rgb;
use rusttype::Scale;

use crate::{
    geometry::Rectangle,
    visualization::{Canvas, Image},
    words::FontProvider,
};

pub struct CanvasRenderer {}

impl CanvasRenderer {
    pub fn render(
        font_provider: &FontProvider,
        viewport: &Rectangle,
        canvas: &Canvas,
        bg_color: Rgb<u8>,
    ) -> Image {
        let mut img = Image::new(viewport.x2(), viewport.y2(), Some(bg_color));

        for word in canvas.list() {
            if cfg!(debug_assertions) {
                println!(
                    "Drawing word '{}' at [{}, {}]",
                    word.text, word.pos.0, word.pos.1
                );
            }

            let scale = Scale::uniform(word.size as f32);
            let Ok(font) = font_provider.get_font(&word.font_name) else {
                panic!("Font not found: {}", word.font_name);
            };
            img.draw_text(
                (word.pos.0 as i32, word.pos.1 as i32),
                &word.text,
                font,
                scale,
                word.color,
                &word.orientation,
            );
            if cfg!(debug_assertions) {
                let r = font
                    .get_bounding_box(word, scale)
                    .displace(word.pos.0 as isize, word.pos.1 as isize)
                    .unwrap();

                img.draw_rect(
                    r.pos().0 as i32,
                    r.pos().1 as i32,
                    r.size().0,
                    r.size().1,
                    Rgb([255, 0, 0]),
                );
            }
        }

        img
    }

    pub fn save(
        font_provider: &FontProvider,
        viewport: &Rectangle,
        canvas: &Canvas,
        filename: &str,
        bg_color: Rgb<u8>,
    ) {
        let img = Self::render(font_provider, viewport, canvas, bg_color);
        img.save(filename).unwrap();
    }
}