aboutsummaryrefslogtreecommitdiff
path: root/evc/src/debug.rs
blob: a7a95450e3c47735e6b492464a9a2011eed27a27 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::{
    block::Block,
    format::ser::map_scalar8,
    frame::Frame,
    helpers::vector::Vec2,
    helpers::{matrix::Mat2, pixel::Pixel},
    view::View,
};

impl View<&mut Frame> {
    pub fn draw_box(&mut self, color: Pixel) {
        let w = self.size.x;
        let h = self.size.y;
        for x in 0..w {
            self[(x, 0)] = color;
            self[(x, h - 1)] = color;
        }
        for y in 0..h {
            self[(0, y)] = color;
            self[(w - 1, y)] = color;
        }
    }
}

impl Frame {
    pub fn draw_line(&mut self, start: Vec2<f32>, end: Vec2<f32>, color: Pixel) {
        let diff = end - start;
        let len = (diff.x * diff.x + diff.y * diff.y).sqrt();
        let normal = Vec2 {
            x: diff.x / len,
            y: diff.y / len,
        };
        let mut cursor = start.clone();
        let mut lc = 0.0;
        while lc < len {
            self.set(cursor.into(), color);
            lc += 0.5;
            cursor = cursor + normal.scale(0.5);
        }
    }
}

impl Pixel {
    pub const RED: Pixel = Pixel { r: 255, g: 0, b: 0 };
    pub const GREEN: Pixel = Pixel { r: 0, g: 255, b: 0 };
    pub const BLUE: Pixel = Pixel { r: 0, g: 0, b: 255 };
    pub const MAGENTA: Pixel = Pixel {
        r: 255,
        g: 0,
        b: 255,
    };
    pub const CYAN: Pixel = Pixel {
        r: 0,
        g: 255,
        b: 255,
    };
}

pub fn draw_debug(block: &Block, mut target: View<&mut Frame>) {
    match &block {
        Block::Literal(_) | Block::CompressedLiteral(_) => {
            target.draw_box(Pixel::GREEN);
        }
        Block::Split(box [a, b]) => {
            let [at, bt] = target.split_mut_unsafe();
            draw_debug(a, at);
            draw_debug(b, bt);
        }
        Block::Reference { translation } => {
            target.draw_box(Pixel::BLUE);
            target.frame.draw_line(
                target.center().into(),
                (target.center() + *translation).into(),
                Pixel::RED,
            )
        }
        Block::AdvancedReference(r) => {
            let mat = Mat2 {
                a: map_scalar8(r.transform.a),
                b: map_scalar8(r.transform.b),
                c: map_scalar8(r.transform.c),
                d: map_scalar8(r.transform.d),
            };
            let translation = Vec2 {
                x: map_scalar8(r.translation.x),
                y: map_scalar8(r.translation.y),
            };
            let halfsize = Into::<Vec2<f32>>::into(target.size).scale(0.5);
            let transform = |p| translation + mat.transform(p - halfsize) + halfsize;
            let (tl, tr, bl, br) = (
                transform(Vec2::<f32>::ZERO) + target.offset.into(),
                transform(target.size.x_only().into()) + target.offset.into(),
                transform(target.size.y_only().into()) + target.offset.into(),
                transform(target.size.into()) + target.offset.into(),
            );
            target.draw_box(Pixel::CYAN);
            target.frame.draw_line(tl, tr, Pixel::MAGENTA);
            target.frame.draw_line(tr, br, Pixel::MAGENTA);
            target.frame.draw_line(bl, br, Pixel::MAGENTA);
            target.frame.draw_line(tl, bl, Pixel::MAGENTA);
        }
    };
}