1use crate::rasterizer_scanline_aa::Scanline;
8
9#[derive(Debug, Clone, Copy, Default)]
18pub struct ScanlineSpan {
19 pub x: i32,
20 pub len: i32,
21 pub cover_offset: usize,
22}
23
24pub struct ScanlineU8 {
40 min_x: i32,
41 last_x: i32,
42 y_val: i32,
43 covers: Vec<u8>,
44 spans: Vec<ScanlineSpan>,
45 cur_span: usize, }
47
48impl ScanlineU8 {
49 pub fn new() -> Self {
50 Self {
51 min_x: 0,
52 last_x: 0x7FFF_FFF0,
53 y_val: 0,
54 covers: Vec::new(),
55 spans: Vec::new(),
56 cur_span: 0,
57 }
58 }
59
60 pub fn reset(&mut self, min_x: i32, max_x: i32) {
62 let max_len = (max_x - min_x + 2) as usize;
63 if max_len > self.spans.len() {
64 self.spans.resize(max_len, ScanlineSpan::default());
65 self.covers.resize(max_len, 0);
66 }
67 self.last_x = 0x7FFF_FFF0;
68 self.min_x = min_x;
69 self.cur_span = 0;
70 }
71
72 pub fn begin(&self) -> &[ScanlineSpan] {
75 &self.spans[1..=self.cur_span]
76 }
77
78 pub fn covers(&self) -> &[u8] {
80 &self.covers
81 }
82}
83
84impl Scanline for ScanlineU8 {
85 fn reset_spans(&mut self) {
86 self.last_x = 0x7FFF_FFF0;
87 self.cur_span = 0;
88 }
89
90 fn add_cell(&mut self, x: i32, cover: u32) {
91 let xi = (x - self.min_x) as usize;
92 self.covers[xi] = cover as u8;
93 if xi as i32 == self.last_x + 1 {
94 self.spans[self.cur_span].len += 1;
95 } else {
96 self.cur_span += 1;
97 self.spans[self.cur_span].x = x;
98 self.spans[self.cur_span].len = 1;
99 self.spans[self.cur_span].cover_offset = xi;
100 }
101 self.last_x = xi as i32;
102 }
103
104 fn add_span(&mut self, x: i32, len: u32, cover: u32) {
105 let xi = (x - self.min_x) as usize;
106 for i in 0..len as usize {
108 self.covers[xi + i] = cover as u8;
109 }
110 if xi as i32 == self.last_x + 1 {
111 self.spans[self.cur_span].len += len as i32;
112 } else {
113 self.cur_span += 1;
114 self.spans[self.cur_span].x = x;
115 self.spans[self.cur_span].len = len as i32;
116 self.spans[self.cur_span].cover_offset = xi;
117 }
118 self.last_x = xi as i32 + len as i32 - 1;
119 }
120
121 fn finalize(&mut self, y: i32) {
122 self.y_val = y;
123 }
124
125 fn num_spans(&self) -> u32 {
126 self.cur_span as u32
127 }
128
129 fn y(&self) -> i32 {
130 self.y_val
131 }
132}
133
134impl Default for ScanlineU8 {
135 fn default() -> Self {
136 Self::new()
137 }
138}
139
140#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_new() {
150 let sl = ScanlineU8::new();
151 assert_eq!(sl.num_spans(), 0);
152 assert_eq!(sl.y(), 0);
153 }
154
155 #[test]
156 fn test_reset_and_add_cell() {
157 let mut sl = ScanlineU8::new();
158 sl.reset(0, 100);
159 sl.add_cell(10, 128);
160 assert_eq!(sl.num_spans(), 1);
161 let spans = sl.begin();
162 assert_eq!(spans[0].x, 10);
163 assert_eq!(spans[0].len, 1);
164 assert_eq!(sl.covers()[spans[0].cover_offset], 128);
165 }
166
167 #[test]
168 fn test_adjacent_cells_merge() {
169 let mut sl = ScanlineU8::new();
170 sl.reset(0, 100);
171 sl.add_cell(10, 100);
172 sl.add_cell(11, 200);
173 sl.add_cell(12, 150);
174 assert_eq!(sl.num_spans(), 1);
176 let spans = sl.begin();
177 assert_eq!(spans[0].x, 10);
178 assert_eq!(spans[0].len, 3);
179 assert_eq!(sl.covers()[spans[0].cover_offset], 100);
180 assert_eq!(sl.covers()[spans[0].cover_offset + 1], 200);
181 assert_eq!(sl.covers()[spans[0].cover_offset + 2], 150);
182 }
183
184 #[test]
185 fn test_non_adjacent_cells_separate_spans() {
186 let mut sl = ScanlineU8::new();
187 sl.reset(0, 100);
188 sl.add_cell(10, 100);
189 sl.add_cell(20, 200);
190 assert_eq!(sl.num_spans(), 2);
191 let spans = sl.begin();
192 assert_eq!(spans[0].x, 10);
193 assert_eq!(spans[1].x, 20);
194 }
195
196 #[test]
197 fn test_add_span() {
198 let mut sl = ScanlineU8::new();
199 sl.reset(0, 100);
200 sl.add_span(5, 10, 255);
201 assert_eq!(sl.num_spans(), 1);
202 let spans = sl.begin();
203 assert_eq!(spans[0].x, 5);
204 assert_eq!(spans[0].len, 10);
205 for i in 0..10 {
207 assert_eq!(sl.covers()[spans[0].cover_offset + i], 255);
208 }
209 }
210
211 #[test]
212 fn test_finalize() {
213 let mut sl = ScanlineU8::new();
214 sl.reset(0, 100);
215 sl.add_cell(10, 128);
216 sl.finalize(42);
217 assert_eq!(sl.y(), 42);
218 }
219
220 #[test]
221 fn test_reset_spans() {
222 let mut sl = ScanlineU8::new();
223 sl.reset(0, 100);
224 sl.add_cell(10, 128);
225 assert_eq!(sl.num_spans(), 1);
226 sl.reset_spans();
227 assert_eq!(sl.num_spans(), 0);
228 }
229
230 #[test]
231 fn test_span_then_adjacent_cell() {
232 let mut sl = ScanlineU8::new();
233 sl.reset(0, 100);
234 sl.add_span(5, 3, 200);
235 sl.add_cell(8, 100); assert_eq!(sl.num_spans(), 1);
237 let spans = sl.begin();
238 assert_eq!(spans[0].len, 4);
239 }
240
241 #[test]
242 fn test_with_min_x_offset() {
243 let mut sl = ScanlineU8::new();
244 sl.reset(50, 150);
245 sl.add_cell(60, 128);
246 sl.add_cell(61, 64);
247 assert_eq!(sl.num_spans(), 1);
248 let spans = sl.begin();
249 assert_eq!(spans[0].x, 60);
250 assert_eq!(spans[0].len, 2);
251 assert_eq!(sl.covers()[spans[0].cover_offset], 128);
252 assert_eq!(sl.covers()[spans[0].cover_offset + 1], 64);
253 }
254}