rocketsplash_rt/render/
cls_render_buffer.rs1use rocketsplash_formats::Rgb;
8
9use crate::TextStyle;
10
11#[derive(Clone, Debug)]
12pub struct RenderBuffer {
13 pub width: usize,
14 pub height: usize,
15 pub cells: Vec<RenderCell>,
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub struct RenderCell {
20 pub ch: char,
21 pub fg: Option<Rgb>,
22 pub bg: Option<Rgb>,
23 pub style: TextStyle,
24 pub opacity: u8,
25}
26
27impl RenderCell {
28 pub fn empty() -> Self {
29 Self {
30 ch: ' ',
31 fg: None,
32 bg: None,
33 style: TextStyle::empty(),
34 opacity: 0,
35 }
36 }
37
38 pub fn is_empty(&self) -> bool {
39 self.ch == ' ' && self.opacity == 0 && self.fg.is_none() && self.bg.is_none()
40 }
41}
42
43impl RenderBuffer {
44 pub fn new(width: usize, height: usize) -> Self {
45 let size = width.saturating_mul(height);
46 Self {
47 width,
48 height,
49 cells: vec![RenderCell::empty(); size],
50 }
51 }
52
53 pub fn cell(&self, x: usize, y: usize) -> Option<&RenderCell> {
54 self.index(x, y).and_then(|idx| self.cells.get(idx))
55 }
56
57 pub fn cell_mut(&mut self, x: usize, y: usize) -> Option<&mut RenderCell> {
58 self.index(x, y).and_then(|idx| self.cells.get_mut(idx))
59 }
60
61 fn index(&self, x: usize, y: usize) -> Option<usize> {
62 if x >= self.width || y >= self.height {
63 return None;
64 }
65 Some(y * self.width + x)
66 }
67}
68
69