1use crate::rasterizer_scanline_aa::Scanline;
8
9#[derive(Debug, Clone, Copy, Default)]
15pub struct BinSpan {
16 pub x: i32,
17 pub len: i32,
18}
19
20pub struct ScanlineBin {
28 last_x: i32,
29 y_val: i32,
30 spans: Vec<BinSpan>,
31 cur_span: usize,
32}
33
34impl ScanlineBin {
35 pub fn new() -> Self {
36 Self {
37 last_x: 0x7FFF_FFF0,
38 y_val: 0,
39 spans: Vec::new(),
40 cur_span: 0,
41 }
42 }
43
44 pub fn reset(&mut self, _min_x: i32, max_x: i32) {
46 let max_len = (max_x + 3) as usize;
47 if max_len > self.spans.len() {
48 self.spans.resize(max_len, BinSpan::default());
49 }
50 self.last_x = 0x7FFF_FFF0;
51 self.cur_span = 0;
52 }
53
54 pub fn begin(&self) -> &[BinSpan] {
56 &self.spans[1..=self.cur_span]
57 }
58}
59
60impl Scanline for ScanlineBin {
61 fn reset_spans(&mut self) {
62 self.last_x = 0x7FFF_FFF0;
63 self.cur_span = 0;
64 }
65
66 fn add_cell(&mut self, x: i32, _cover: u32) {
67 if x == self.last_x + 1 {
68 self.spans[self.cur_span].len += 1;
69 } else {
70 self.cur_span += 1;
71 self.spans[self.cur_span].x = x;
72 self.spans[self.cur_span].len = 1;
73 }
74 self.last_x = x;
75 }
76
77 fn add_span(&mut self, x: i32, len: u32, _cover: u32) {
78 if x == self.last_x + 1 {
79 self.spans[self.cur_span].len += len as i32;
80 } else {
81 self.cur_span += 1;
82 self.spans[self.cur_span].x = x;
83 self.spans[self.cur_span].len = len as i32;
84 }
85 self.last_x = x + len as i32 - 1;
86 }
87
88 fn finalize(&mut self, y: i32) {
89 self.y_val = y;
90 }
91
92 fn num_spans(&self) -> u32 {
93 self.cur_span as u32
94 }
95
96 fn y(&self) -> i32 {
97 self.y_val
98 }
99}
100
101impl Default for ScanlineBin {
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_new() {
117 let sl = ScanlineBin::new();
118 assert_eq!(sl.num_spans(), 0);
119 }
120
121 #[test]
122 fn test_add_cell() {
123 let mut sl = ScanlineBin::new();
124 sl.reset(0, 100);
125 sl.add_cell(10, 255);
126 assert_eq!(sl.num_spans(), 1);
127 let spans = sl.begin();
128 assert_eq!(spans[0].x, 10);
129 assert_eq!(spans[0].len, 1);
130 }
131
132 #[test]
133 fn test_adjacent_cells_merge() {
134 let mut sl = ScanlineBin::new();
135 sl.reset(0, 100);
136 sl.add_cell(10, 255);
137 sl.add_cell(11, 128);
138 sl.add_cell(12, 64);
139 assert_eq!(sl.num_spans(), 1);
140 let spans = sl.begin();
141 assert_eq!(spans[0].x, 10);
142 assert_eq!(spans[0].len, 3);
143 }
144
145 #[test]
146 fn test_add_span() {
147 let mut sl = ScanlineBin::new();
148 sl.reset(0, 100);
149 sl.add_span(5, 10, 255);
150 assert_eq!(sl.num_spans(), 1);
151 let spans = sl.begin();
152 assert_eq!(spans[0].x, 5);
153 assert_eq!(spans[0].len, 10);
154 }
155
156 #[test]
157 fn test_separate_spans() {
158 let mut sl = ScanlineBin::new();
159 sl.reset(0, 100);
160 sl.add_cell(10, 255);
161 sl.add_cell(20, 255);
162 assert_eq!(sl.num_spans(), 2);
163 }
164
165 #[test]
166 fn test_reset_spans() {
167 let mut sl = ScanlineBin::new();
168 sl.reset(0, 100);
169 sl.add_cell(10, 255);
170 sl.reset_spans();
171 assert_eq!(sl.num_spans(), 0);
172 }
173}