1use crate::rasterizer_scanline_aa::Scanline;
8
9#[derive(Debug, Clone, Copy, Default)]
20pub struct PackedSpan {
21 pub x: i32,
22 pub len: i32,
23 pub cover_offset: usize,
24}
25
26pub struct ScanlineP8 {
35 last_x: i32,
36 y_val: i32,
37 covers: Vec<u8>,
38 cover_ptr: usize,
39 spans: Vec<PackedSpan>,
40 cur_span: usize,
41}
42
43impl ScanlineP8 {
44 pub fn new() -> Self {
45 Self {
46 last_x: 0x7FFF_FFF0,
47 y_val: 0,
48 covers: Vec::new(),
49 cover_ptr: 0,
50 spans: Vec::new(),
51 cur_span: 0,
52 }
53 }
54
55 pub fn reset(&mut self, _min_x: i32, max_x: i32) {
57 let max_len = (max_x + 3) as usize;
58 if max_len > self.spans.len() {
59 self.spans.resize(max_len, PackedSpan::default());
60 self.covers.resize(max_len, 0);
61 }
62 self.last_x = 0x7FFF_FFF0;
63 self.cover_ptr = 0;
64 self.cur_span = 0;
65 self.spans[0].len = 0;
66 }
67
68 pub fn begin(&self) -> &[PackedSpan] {
70 &self.spans[1..=self.cur_span]
71 }
72
73 pub fn covers(&self) -> &[u8] {
75 &self.covers
76 }
77}
78
79impl Scanline for ScanlineP8 {
80 fn reset_spans(&mut self) {
81 self.last_x = 0x7FFF_FFF0;
82 self.cover_ptr = 0;
83 self.cur_span = 0;
84 self.spans[0].len = 0;
85 }
86
87 fn add_cell(&mut self, x: i32, cover: u32) {
88 self.covers[self.cover_ptr] = cover as u8;
89 if x == self.last_x + 1 && self.spans[self.cur_span].len > 0 {
90 self.spans[self.cur_span].len += 1;
91 } else {
92 self.cur_span += 1;
93 self.spans[self.cur_span].cover_offset = self.cover_ptr;
94 self.spans[self.cur_span].x = x;
95 self.spans[self.cur_span].len = 1;
96 }
97 self.last_x = x;
98 self.cover_ptr += 1;
99 }
100
101 fn add_span(&mut self, x: i32, len: u32, cover: u32) {
102 if x == self.last_x + 1
103 && self.spans[self.cur_span].len < 0
104 && cover as u8 == self.covers[self.spans[self.cur_span].cover_offset]
105 {
106 self.spans[self.cur_span].len -= len as i32;
108 } else {
109 self.covers[self.cover_ptr] = cover as u8;
110 self.cur_span += 1;
111 self.spans[self.cur_span].cover_offset = self.cover_ptr;
112 self.cover_ptr += 1;
113 self.spans[self.cur_span].x = x;
114 self.spans[self.cur_span].len = -(len as i32);
115 }
116 self.last_x = x + len as i32 - 1;
117 }
118
119 fn finalize(&mut self, y: i32) {
120 self.y_val = y;
121 }
122
123 fn num_spans(&self) -> u32 {
124 self.cur_span as u32
125 }
126
127 fn y(&self) -> i32 {
128 self.y_val
129 }
130}
131
132impl Default for ScanlineP8 {
133 fn default() -> Self {
134 Self::new()
135 }
136}
137
138#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn test_new() {
148 let sl = ScanlineP8::new();
149 assert_eq!(sl.num_spans(), 0);
150 }
151
152 #[test]
153 fn test_add_cell() {
154 let mut sl = ScanlineP8::new();
155 sl.reset(0, 100);
156 sl.add_cell(10, 128);
157 assert_eq!(sl.num_spans(), 1);
158 let spans = sl.begin();
159 assert_eq!(spans[0].x, 10);
160 assert_eq!(spans[0].len, 1); assert_eq!(sl.covers()[spans[0].cover_offset], 128);
162 }
163
164 #[test]
165 fn test_adjacent_cells_form_per_pixel_span() {
166 let mut sl = ScanlineP8::new();
167 sl.reset(0, 100);
168 sl.add_cell(10, 100);
169 sl.add_cell(11, 200);
170 sl.add_cell(12, 150);
171 assert_eq!(sl.num_spans(), 1);
172 let spans = sl.begin();
173 assert_eq!(spans[0].len, 3); }
175
176 #[test]
177 fn test_add_span_creates_solid_span() {
178 let mut sl = ScanlineP8::new();
179 sl.reset(0, 100);
180 sl.add_span(5, 10, 255);
181 assert_eq!(sl.num_spans(), 1);
182 let spans = sl.begin();
183 assert_eq!(spans[0].x, 5);
184 assert_eq!(spans[0].len, -10); assert_eq!(sl.covers()[spans[0].cover_offset], 255);
186 }
187
188 #[test]
189 fn test_adjacent_solid_spans_merge() {
190 let mut sl = ScanlineP8::new();
191 sl.reset(0, 100);
192 sl.add_span(5, 10, 255);
193 sl.add_span(15, 5, 255); assert_eq!(sl.num_spans(), 1);
195 let spans = sl.begin();
196 assert_eq!(spans[0].len, -15); }
198
199 #[test]
200 fn test_adjacent_solid_spans_different_cover_no_merge() {
201 let mut sl = ScanlineP8::new();
202 sl.reset(0, 100);
203 sl.add_span(5, 10, 255);
204 sl.add_span(15, 5, 128); assert_eq!(sl.num_spans(), 2);
206 }
207
208 #[test]
209 fn test_cell_after_solid_span_new_span() {
210 let mut sl = ScanlineP8::new();
211 sl.reset(0, 100);
212 sl.add_span(5, 3, 200);
213 sl.add_cell(8, 100); assert_eq!(sl.num_spans(), 2);
215 }
216
217 #[test]
218 fn test_reset_spans() {
219 let mut sl = ScanlineP8::new();
220 sl.reset(0, 100);
221 sl.add_cell(10, 128);
222 sl.reset_spans();
223 assert_eq!(sl.num_spans(), 0);
224 }
225}