tpaint/
buffer.rs

1use std::iter::once;
2
3pub struct Buffer {
4	start_x: usize,
5	start_y: usize,
6	grid: Vec<Vec<char>>,
7}
8
9impl Buffer {
10	pub fn new() -> Self {
11		Self {
12			start_x: 0,
13			start_y: 0,
14			grid: Vec::new(),
15		}
16	}
17
18	pub fn new_frame(&mut self) {
19		self.start_x = 0;
20		self.start_y = 0;
21		self.grid.clear();
22	}
23
24	pub fn new_frame_bounded(&mut self, start_x: usize, start_y: usize) {
25		self.start_x = start_x;
26		self.start_y = start_y;
27		self.grid.clear();
28	}
29
30	pub fn get_point(&self, x: usize, y: usize) -> char {
31		let x = x - self.start_x;
32		let y = y - self.start_y;
33		*self.grid.get(y).and_then(|y| y.get(x)).unwrap_or(&' ')
34	}
35
36	pub fn render_point(&mut self, x: usize, y: usize, c: char) {
37		let x = x - self.start_x;
38		let y = y - self.start_y;
39
40		if self.grid.len() < y + 1 {
41			self.grid.resize(y + 1, Vec::new());
42		}
43		let row = &mut self.grid[y];
44		if row.len() < x + 1 {
45			row.resize(x + 1, ' ');
46		}
47		row[x] = c;
48	}
49
50	pub fn into_inner(self) -> Vec<Vec<char>> { self.grid }
51
52	pub fn output(&self, width: usize) -> Vec<String> {
53		self.grid
54			.iter()
55			.map(|line| {
56				line.iter()
57					.copied()
58					.chain(once(' ').cycle())
59					.take(width)
60					.collect::<String>()
61			})
62			.collect::<Vec<_>>()
63	}
64}