agg_rust/
scanline_storage_bin.rs1use crate::rasterizer_scanline_aa::Scanline;
8
9#[derive(Debug, Clone, Copy, Default)]
11struct SpanData {
12 x: i32,
13 len: i32,
14}
15
16#[derive(Debug, Clone, Copy, Default)]
18struct ScanlineData {
19 y: i32,
20 num_spans: u32,
21 start_span: usize,
22}
23
24pub struct ScanlineStorageBin {
29 spans: Vec<SpanData>,
30 scanlines: Vec<ScanlineData>,
31 min_x: i32,
32 min_y: i32,
33 max_x: i32,
34 max_y: i32,
35 cur_scanline: usize,
36}
37
38impl ScanlineStorageBin {
39 pub fn new() -> Self {
40 Self {
41 spans: Vec::new(),
42 scanlines: Vec::new(),
43 min_x: i32::MAX,
44 min_y: i32::MAX,
45 max_x: i32::MIN,
46 max_y: i32::MIN,
47 cur_scanline: 0,
48 }
49 }
50
51 pub fn prepare(&mut self) {
53 self.spans.clear();
54 self.scanlines.clear();
55 self.min_x = i32::MAX;
56 self.min_y = i32::MAX;
57 self.max_x = i32::MIN;
58 self.max_y = i32::MIN;
59 self.cur_scanline = 0;
60 }
61
62 pub fn render_scanline_bin(&mut self, sl: &crate::scanline_bin::ScanlineBin) {
64 let y = sl.y();
65 if y < self.min_y {
66 self.min_y = y;
67 }
68 if y > self.max_y {
69 self.max_y = y;
70 }
71
72 let start_span = self.spans.len();
73 let mut num_spans = 0u32;
74
75 let spans = sl.begin();
76 for sp in spans {
77 let x = sp.x;
78 let len = sp.len;
79 let xe = x + len - 1;
80 if x < self.min_x {
81 self.min_x = x;
82 }
83 if xe > self.max_x {
84 self.max_x = xe;
85 }
86 self.spans.push(SpanData { x, len });
87 num_spans += 1;
88 }
89
90 self.scanlines.push(ScanlineData {
91 y,
92 num_spans,
93 start_span,
94 });
95 }
96
97 pub fn render_scanline_u8(&mut self, sl: &crate::scanline_u::ScanlineU8) {
99 let y = sl.y();
100 if y < self.min_y {
101 self.min_y = y;
102 }
103 if y > self.max_y {
104 self.max_y = y;
105 }
106
107 let start_span = self.spans.len();
108 let mut num_spans = 0u32;
109
110 let spans = sl.begin();
111 for sp in spans {
112 let x = sp.x;
113 let len = sp.len;
114 let xe = x + len - 1;
115 if x < self.min_x {
116 self.min_x = x;
117 }
118 if xe > self.max_x {
119 self.max_x = xe;
120 }
121 self.spans.push(SpanData { x, len });
122 num_spans += 1;
123 }
124
125 self.scanlines.push(ScanlineData {
126 y,
127 num_spans,
128 start_span,
129 });
130 }
131
132 pub fn rewind_scanlines(&mut self) -> bool {
134 self.cur_scanline = 0;
135 !self.scanlines.is_empty()
136 }
137
138 pub fn sweep_scanline<SL: Scanline>(&mut self, sl: &mut SL) -> bool {
140 sl.reset_spans();
141 loop {
142 if self.cur_scanline >= self.scanlines.len() {
143 return false;
144 }
145 let sld = self.scanlines[self.cur_scanline];
146 let num_spans = sld.num_spans;
147 self.cur_scanline += 1;
148
149 if num_spans == 0 {
150 continue;
151 }
152
153 for i in 0..num_spans as usize {
154 let sp = self.spans[sld.start_span + i];
155 sl.add_span(sp.x, sp.len as u32, 255); }
157 sl.finalize(sld.y);
158 return true;
159 }
160 }
161
162 pub fn min_x(&self) -> i32 {
163 self.min_x
164 }
165 pub fn min_y(&self) -> i32 {
166 self.min_y
167 }
168 pub fn max_x(&self) -> i32 {
169 self.max_x
170 }
171 pub fn max_y(&self) -> i32 {
172 self.max_y
173 }
174
175 pub fn num_scanlines(&self) -> usize {
176 self.scanlines.len()
177 }
178
179 pub fn scanline_y(&self, idx: usize) -> i32 {
181 self.scanlines[idx].y
182 }
183
184 pub fn scanline_num_spans(&self, idx: usize) -> u32 {
186 self.scanlines[idx].num_spans
187 }
188
189 pub fn embedded_spans(&self, sl_idx: usize) -> impl Iterator<Item = EmbeddedBinSpan> + '_ {
191 let sld = &self.scanlines[sl_idx];
192 let spans = &self.spans[sld.start_span..sld.start_span + sld.num_spans as usize];
193 spans.iter().map(|sp| EmbeddedBinSpan {
194 x: sp.x,
195 len: sp.len,
196 })
197 }
198}
199
200impl Default for ScanlineStorageBin {
201 fn default() -> Self {
202 Self::new()
203 }
204}
205
206#[derive(Debug, Clone, Copy)]
208pub struct EmbeddedBinSpan {
209 pub x: i32,
210 pub len: i32,
211}
212
213impl EmbeddedBinSpan {
214 pub fn x_end(&self) -> i32 {
216 self.x + self.len
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223 use crate::scanline_bin::ScanlineBin;
224
225 #[test]
226 fn test_empty_storage() {
227 let storage = ScanlineStorageBin::new();
228 assert_eq!(storage.num_scanlines(), 0);
229 }
230
231 #[test]
232 fn test_store_and_replay() {
233 let mut storage = ScanlineStorageBin::new();
234 storage.prepare();
235
236 let mut sl = ScanlineBin::new();
237 sl.reset(0, 100);
238 sl.add_span(10, 5, 255);
239 sl.finalize(3);
240 storage.render_scanline_bin(&sl);
241
242 assert_eq!(storage.num_scanlines(), 1);
243 assert_eq!(storage.min_x(), 10);
244 assert_eq!(storage.max_x(), 14);
245
246 assert!(storage.rewind_scanlines());
247 let mut sl2 = ScanlineBin::new();
248 sl2.reset(0, 100);
249 assert!(storage.sweep_scanline(&mut sl2));
250 assert_eq!(sl2.y(), 3);
251 assert_eq!(sl2.num_spans(), 1);
252 let spans = sl2.begin();
253 assert_eq!(spans[0].x, 10);
254 assert_eq!(spans[0].len, 5);
255 }
256
257 #[test]
258 fn test_multiple_scanlines() {
259 let mut storage = ScanlineStorageBin::new();
260 storage.prepare();
261
262 let mut sl = ScanlineBin::new();
263 sl.reset(0, 100);
264 sl.add_span(0, 10, 255);
265 sl.finalize(0);
266 storage.render_scanline_bin(&sl);
267
268 sl.reset_spans();
269 sl.add_span(5, 15, 255);
270 sl.finalize(1);
271 storage.render_scanline_bin(&sl);
272
273 assert_eq!(storage.num_scanlines(), 2);
274 assert_eq!(storage.min_x(), 0);
275 assert_eq!(storage.max_x(), 19);
276 assert_eq!(storage.min_y(), 0);
277 assert_eq!(storage.max_y(), 1);
278 }
279
280 #[test]
281 fn test_embedded_spans() {
282 let mut storage = ScanlineStorageBin::new();
283 storage.prepare();
284
285 let mut sl = ScanlineBin::new();
286 sl.reset(0, 100);
287 sl.add_span(5, 10, 255);
288 sl.add_span(30, 5, 255);
289 sl.finalize(0);
290 storage.render_scanline_bin(&sl);
291
292 let spans: Vec<_> = storage.embedded_spans(0).collect();
293 assert_eq!(spans.len(), 2);
294 assert_eq!(spans[0].x, 5);
295 assert_eq!(spans[0].len, 10);
296 assert_eq!(spans[1].x, 30);
297 assert_eq!(spans[1].len, 5);
298 }
299}