prototty_render/
buffer.rs1use 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}