prototty_render/
buffer.rs

1use super::{Blend, Coord, Frame, Rgb24, Size, ViewCell};
2
3#[derive(Debug, Clone)]
4pub struct BufferCell {
5    pub character: char,
6    pub bold: bool,
7    pub underline: bool,
8    pub foreground_colour: Rgb24,
9    pub background_colour: Rgb24,
10    foreground_depth: i8,
11    background_depth: i8,
12}
13
14impl BufferCell {
15    fn set_character(&mut self, character: char, depth: i8) {
16        if depth >= self.foreground_depth {
17            self.character = character;
18            self.foreground_depth = depth;
19        }
20    }
21    fn set_bold(&mut self, bold: bool, depth: i8) {
22        if depth >= self.foreground_depth {
23            self.bold = bold;
24            self.foreground_depth = depth;
25        }
26    }
27    fn set_underline(&mut self, underline: bool, depth: i8) {
28        if depth >= self.foreground_depth {
29            self.underline = underline;
30            self.foreground_depth = depth;
31        }
32    }
33    fn set_foreground_colour(&mut self, colour: Rgb24, depth: i8) {
34        if depth >= self.foreground_depth {
35            self.foreground_colour = colour;
36            self.foreground_depth = depth;
37        }
38    }
39    fn set_background_colour(&mut self, colour: Rgb24, depth: i8) {
40        if depth >= self.background_depth {
41            self.background_colour = colour;
42            self.background_depth = depth;
43        }
44    }
45}
46
47const BLACK: Rgb24 = Rgb24::new_grey(0);
48const BLANK_CELL: BufferCell = BufferCell {
49    character: ' ',
50    bold: false,
51    underline: false,
52    foreground_colour: BLACK,
53    background_colour: BLACK,
54    foreground_depth: 0,
55    background_depth: 0,
56};
57
58pub type BufferIter<'a> = grid_2d::GridIter<'a, BufferCell>;
59pub type BufferEnumerate<'a> = grid_2d::GridEnumerate<'a, BufferCell>;
60
61#[derive(Debug, Clone)]
62pub struct Buffer {
63    grid: grid_2d::Grid<BufferCell>,
64}
65
66impl Buffer {
67    pub fn new(size: Size) -> Self {
68        let grid = grid_2d::Grid::new_clone(size, BLANK_CELL);
69        Self { grid }
70    }
71
72    pub fn size(&self) -> Size {
73        self.grid.size()
74    }
75
76    pub fn resize(&mut self, size: Size) {
77        self.grid = grid_2d::Grid::new_clone(size, BLANK_CELL);
78    }
79
80    pub fn clear(&mut self) {
81        for cell in self.grid.iter_mut() {
82            *cell = BLANK_CELL;
83        }
84    }
85
86    pub fn enumerate(&self) -> BufferEnumerate {
87        self.grid.enumerate()
88    }
89
90    pub fn iter(&self) -> BufferIter {
91        self.grid.iter()
92    }
93}
94
95impl Frame for Buffer {
96    fn set_cell_absolute(&mut self, coord: Coord, depth: i8, view_cell: ViewCell) {
97        if let Some(cell) = self.grid.get_mut(coord) {
98            if cell.foreground_depth <= depth || cell.background_depth <= depth {
99                if let Some(character) = view_cell.character() {
100                    cell.set_character(character, depth);
101                }
102                if let Some(bold) = view_cell.bold() {
103                    cell.set_bold(bold, depth);
104                }
105                if let Some(underline) = view_cell.underline() {
106                    cell.set_underline(underline, depth);
107                }
108                if let Some(foreground) = view_cell.foreground() {
109                    cell.set_foreground_colour(foreground, depth);
110                }
111                if let Some(background) = view_cell.background() {
112                    cell.set_background_colour(background, depth);
113                }
114            }
115        }
116    }
117    fn blend_cell_background_absolute<B: Blend>(&mut self, coord: Coord, depth: i8, rgb24: Rgb24, alpha: u8, blend: B) {
118        if let Some(cell) = self.grid.get_mut(coord) {
119            if cell.background_depth <= depth {
120                let current_background_colour = cell.background_colour;
121                let blended_background_colour = blend.blend(current_background_colour, rgb24, alpha);
122                cell.background_colour = blended_background_colour;
123                cell.background_depth = depth;
124            }
125        }
126    }
127}