1use crate::rasterizer_scanline_aa::Scanline;
8
9#[derive(Debug, Clone, Copy, Default)]
11struct SpanData {
12 x: i32,
13 len: i32,
14 covers_offset: usize,
15}
16
17#[derive(Debug, Clone, Copy, Default)]
19struct ScanlineData {
20 y: i32,
21 num_spans: u32,
22 start_span: usize,
23}
24
25pub struct ScanlineStorageAa {
30 spans: Vec<SpanData>,
31 covers: Vec<u8>,
32 scanlines: Vec<ScanlineData>,
33 min_x: i32,
34 min_y: i32,
35 max_x: i32,
36 max_y: i32,
37 cur_scanline: usize,
38}
39
40impl ScanlineStorageAa {
41 pub fn new() -> Self {
42 Self {
43 spans: Vec::new(),
44 covers: Vec::new(),
45 scanlines: Vec::new(),
46 min_x: i32::MAX,
47 min_y: i32::MAX,
48 max_x: i32::MIN,
49 max_y: i32::MIN,
50 cur_scanline: 0,
51 }
52 }
53
54 pub fn prepare(&mut self) {
56 self.spans.clear();
57 self.covers.clear();
58 self.scanlines.clear();
59 self.min_x = i32::MAX;
60 self.min_y = i32::MAX;
61 self.max_x = i32::MIN;
62 self.max_y = i32::MIN;
63 self.cur_scanline = 0;
64 }
65
66 pub fn render_scanline_u8(&mut self, sl: &crate::scanline_u::ScanlineU8) {
68 let y = sl.y();
69 if y < self.min_y {
70 self.min_y = y;
71 }
72 if y > self.max_y {
73 self.max_y = y;
74 }
75
76 let start_span = self.spans.len();
77 let mut num_spans = 0u32;
78
79 let spans = sl.begin();
80 let covers_buf = sl.covers();
81
82 for sp in spans {
83 let x = sp.x;
84 let len = sp.len;
85 if len > 0 {
86 let xe = x + len - 1;
88 if x < self.min_x {
89 self.min_x = x;
90 }
91 if xe > self.max_x {
92 self.max_x = xe;
93 }
94 let covers_offset = self.covers.len();
95 self.covers
96 .extend_from_slice(&covers_buf[sp.cover_offset..sp.cover_offset + len as usize]);
97 self.spans.push(SpanData {
98 x,
99 len,
100 covers_offset,
101 });
102 }
103 num_spans += 1;
104 }
105
106 self.scanlines.push(ScanlineData {
107 y,
108 num_spans,
109 start_span,
110 });
111 }
112
113 pub fn render_scanline_p8(&mut self, sl: &crate::scanline_p::ScanlineP8) {
115 let y = sl.y();
116 if y < self.min_y {
117 self.min_y = y;
118 }
119 if y > self.max_y {
120 self.max_y = y;
121 }
122
123 let start_span = self.spans.len();
124 let mut num_spans = 0u32;
125
126 let spans = sl.begin();
127 let covers_buf = sl.covers();
128
129 for sp in spans {
130 let x = sp.x;
131 let len = sp.len;
132 let abs_len = len.unsigned_abs() as i32;
133 let xe = x + abs_len - 1;
134 if x < self.min_x {
135 self.min_x = x;
136 }
137 if xe > self.max_x {
138 self.max_x = xe;
139 }
140 let covers_offset = self.covers.len();
141 if len < 0 {
142 self.covers.push(covers_buf[sp.cover_offset]);
144 } else {
145 self.covers
147 .extend_from_slice(&covers_buf[sp.cover_offset..sp.cover_offset + len as usize]);
148 }
149 self.spans.push(SpanData {
150 x,
151 len,
152 covers_offset,
153 });
154 num_spans += 1;
155 }
156
157 self.scanlines.push(ScanlineData {
158 y,
159 num_spans,
160 start_span,
161 });
162 }
163
164 pub fn rewind_scanlines(&mut self) -> bool {
166 self.cur_scanline = 0;
167 !self.scanlines.is_empty()
168 }
169
170 pub fn sweep_scanline<SL: Scanline>(&mut self, sl: &mut SL) -> bool {
173 sl.reset_spans();
174 loop {
175 if self.cur_scanline >= self.scanlines.len() {
176 return false;
177 }
178 let sld = self.scanlines[self.cur_scanline];
179 let num_spans = sld.num_spans;
180 self.cur_scanline += 1;
181
182 if num_spans == 0 {
183 continue;
184 }
185
186 for i in 0..num_spans as usize {
187 let sp = self.spans[sld.start_span + i];
188 if sp.len < 0 {
189 sl.add_span(sp.x, (-sp.len) as u32, self.covers[sp.covers_offset] as u32);
191 } else if sp.len > 0 {
192 for j in 0..sp.len as usize {
194 sl.add_cell(sp.x + j as i32, self.covers[sp.covers_offset + j] as u32);
195 }
196 }
197 }
198 sl.finalize(sld.y);
199 return true;
200 }
201 }
202
203 pub fn min_x(&self) -> i32 {
204 self.min_x
205 }
206 pub fn min_y(&self) -> i32 {
207 self.min_y
208 }
209 pub fn max_x(&self) -> i32 {
210 self.max_x
211 }
212 pub fn max_y(&self) -> i32 {
213 self.max_y
214 }
215
216 pub fn num_scanlines(&self) -> usize {
217 self.scanlines.len()
218 }
219
220 pub fn scanline_y(&self, idx: usize) -> i32 {
226 self.scanlines[idx].y
227 }
228
229 pub fn scanline_num_spans(&self, idx: usize) -> u32 {
231 self.scanlines[idx].num_spans
232 }
233
234 fn span_covers(&self, sp: &SpanData) -> &[u8] {
236 if sp.len < 0 {
237 &self.covers[sp.covers_offset..sp.covers_offset + 1]
238 } else {
239 &self.covers[sp.covers_offset..sp.covers_offset + sp.len as usize]
240 }
241 }
242
243 pub fn embedded_spans(
246 &self,
247 sl_idx: usize,
248 ) -> impl Iterator<Item = EmbeddedSpan<'_>> + '_ {
249 let sld = &self.scanlines[sl_idx];
250 let spans = &self.spans[sld.start_span..sld.start_span + sld.num_spans as usize];
251 spans.iter().map(move |sp| EmbeddedSpan {
252 x: sp.x,
253 len: sp.len,
254 covers: self.span_covers(sp),
255 })
256 }
257}
258
259impl Default for ScanlineStorageAa {
260 fn default() -> Self {
261 Self::new()
262 }
263}
264
265#[derive(Debug, Clone, Copy)]
267pub struct EmbeddedSpan<'a> {
268 pub x: i32,
269 pub len: i32,
270 pub covers: &'a [u8],
271}
272
273impl<'a> EmbeddedSpan<'a> {
274 pub fn abs_len(&self) -> i32 {
276 self.len.abs()
277 }
278
279 pub fn x_end(&self) -> i32 {
281 self.x + self.abs_len()
282 }
283
284 pub fn cover_at(&self, i: usize) -> u8 {
286 if self.len < 0 {
287 self.covers[0] } else {
289 self.covers[i]
290 }
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use super::*;
297 use crate::scanline_u::ScanlineU8;
298
299 #[test]
300 fn test_empty_storage() {
301 let storage = ScanlineStorageAa::new();
302 assert_eq!(storage.num_scanlines(), 0);
303 }
304
305 #[test]
306 fn test_store_and_replay() {
307 let mut storage = ScanlineStorageAa::new();
308 storage.prepare();
309
310 let mut sl = ScanlineU8::new();
312 sl.reset(0, 100);
313 sl.add_cell(10, 128);
314 sl.add_cell(11, 255);
315 sl.add_cell(12, 64);
316 sl.finalize(5);
317 storage.render_scanline_u8(&sl);
318
319 assert_eq!(storage.num_scanlines(), 1);
320 assert_eq!(storage.min_x(), 10);
321 assert_eq!(storage.max_x(), 12);
322 assert_eq!(storage.min_y(), 5);
323 assert_eq!(storage.max_y(), 5);
324
325 assert!(storage.rewind_scanlines());
327 let mut sl2 = ScanlineU8::new();
328 sl2.reset(0, 100);
329 assert!(storage.sweep_scanline(&mut sl2));
330 assert_eq!(sl2.y(), 5);
331 assert_eq!(sl2.num_spans(), 1);
332
333 let spans = sl2.begin();
335 let covers = sl2.covers();
336 assert_eq!(spans[0].x, 10);
337 assert_eq!(spans[0].len, 3);
338 assert_eq!(covers[spans[0].cover_offset], 128);
339 assert_eq!(covers[spans[0].cover_offset + 1], 255);
340 assert_eq!(covers[spans[0].cover_offset + 2], 64);
341 }
342
343 #[test]
344 fn test_multiple_scanlines() {
345 let mut storage = ScanlineStorageAa::new();
346 storage.prepare();
347
348 let mut sl = ScanlineU8::new();
349 sl.reset(0, 100);
350 sl.add_cell(5, 200);
351 sl.finalize(0);
352 storage.render_scanline_u8(&sl);
353
354 sl.reset_spans();
355 sl.add_cell(10, 100);
356 sl.finalize(1);
357 storage.render_scanline_u8(&sl);
358
359 assert_eq!(storage.num_scanlines(), 2);
360 assert_eq!(storage.min_y(), 0);
361 assert_eq!(storage.max_y(), 1);
362
363 assert!(storage.rewind_scanlines());
365 let mut sl2 = ScanlineU8::new();
366 sl2.reset(0, 100);
367 assert!(storage.sweep_scanline(&mut sl2));
368 assert_eq!(sl2.y(), 0);
369 assert!(storage.sweep_scanline(&mut sl2));
370 assert_eq!(sl2.y(), 1);
371 assert!(!storage.sweep_scanline(&mut sl2));
372 }
373
374 #[test]
375 fn test_prepare_clears() {
376 let mut storage = ScanlineStorageAa::new();
377
378 let mut sl = ScanlineU8::new();
379 sl.reset(0, 100);
380 sl.add_cell(5, 200);
381 sl.finalize(0);
382 storage.render_scanline_u8(&sl);
383
384 storage.prepare();
385 assert_eq!(storage.num_scanlines(), 0);
386 }
387
388 #[test]
389 fn test_embedded_spans() {
390 let mut storage = ScanlineStorageAa::new();
391 storage.prepare();
392
393 let mut sl = ScanlineU8::new();
394 sl.reset(0, 100);
395 sl.add_cell(10, 128);
396 sl.add_cell(11, 255);
397 sl.add_cell(20, 64);
398 sl.finalize(5);
399 storage.render_scanline_u8(&sl);
400
401 let spans: Vec<_> = storage.embedded_spans(0).collect();
402 assert_eq!(spans.len(), 2);
403 assert_eq!(spans[0].x, 10);
404 assert_eq!(spans[0].len, 2);
405 assert_eq!(spans[0].cover_at(0), 128);
406 assert_eq!(spans[0].cover_at(1), 255);
407 assert_eq!(spans[1].x, 20);
408 assert_eq!(spans[1].len, 1);
409 assert_eq!(spans[1].cover_at(0), 64);
410 }
411}