sark_grids/util/
canvas.rs1use crate::{GridPoint, GridShape, GridSize};
2use glam::UVec2;
3
4pub struct Canvas {
5 size: UVec2,
6 string: String,
7}
8
9impl Canvas {
10 pub fn new(size: impl GridSize) -> Canvas {
11 let string = str::repeat(".", size.tile_count());
12
13 Canvas {
14 size: size.to_uvec2(),
15 string,
16 }
17 }
18
19 pub fn put(&mut self, pos: impl GridPoint, glyph: char) {
20 let i = self.to_index(pos);
21 self.string
22 .replace_range(i..i + 1, std::str::from_utf8(&[glyph as u8]).unwrap());
23 }
24
25 pub fn put_bl(&mut self, pos: impl GridPoint, glyph: char) {
26 let i = self.to_index(pos.to_ivec2() - self.size.as_ivec2() / 2);
27 self.string
28 .replace_range(i..i + 1, std::str::from_utf8(&[glyph as u8]).unwrap());
29 }
30
31 fn to_index(&self, point: impl GridPoint) -> usize {
32 let p = point.to_ivec2() + self.size.as_ivec2() / 2;
33 p.as_index(self.size)
34 }
35
36 pub fn print(&self) {
37 let chars: Vec<_> = self.string.chars().collect();
38 for line in chars.chunks(self.size.x as usize).rev() {
39 println!("{}", String::from_iter(line.iter()));
40 }
41 }
42
43 pub fn put_shape(&mut self, shape: impl GridShape, glyph: char) {
44 for p in shape.iter() {
45 self.put(p, glyph);
46 }
47 }
48
49 pub fn clear(&mut self) {
50 self.string = str::repeat(".", self.size.tile_count());
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::Canvas;
57
58 #[test]
59 #[ignore]
60 fn odd() {
61 let mut canvas = Canvas::new([5, 5]);
62 canvas.put([-2, -2], '*');
63 canvas.put([-1, -1], '*');
64 canvas.put([0, 0], '*');
65 canvas.put([1, 1], '*');
66 canvas.put([2, 2], '*');
67
68 canvas.print();
69 }
70
71 #[test]
72 #[ignore]
73 fn even() {
74 let mut canvas = Canvas::new([6, 6]);
75 canvas.put([-3, -3], '*');
76 canvas.put([-2, -2], '*');
77 canvas.put([-1, -1], '*');
78 canvas.put([0, 0], '*');
79 canvas.put([1, 1], '*');
80 canvas.put([2, 2], '*');
81
82 canvas.print();
83 }
84}