1use crate::basics::{
9 is_close, is_move_to, is_stop, is_vertex, iround, FillingRule, VertexSource,
10 POLY_SUBPIXEL_MASK, POLY_SUBPIXEL_SCALE, POLY_SUBPIXEL_SHIFT,
11};
12use crate::rasterizer_scanline_aa::Scanline;
13
14#[derive(Debug, Clone, Copy)]
22pub struct CellStyleAa {
23 pub x: i32,
24 pub y: i32,
25 pub cover: i32,
26 pub area: i32,
27 pub left: i16,
28 pub right: i16,
29}
30
31impl CellStyleAa {
32 #[inline]
33 pub fn initial(&mut self) {
34 self.x = i32::MAX;
35 self.y = i32::MAX;
36 self.cover = 0;
37 self.area = 0;
38 self.left = -1;
39 self.right = -1;
40 }
41
42 #[inline]
43 pub fn style(&mut self, other: &CellStyleAa) {
44 self.left = other.left;
45 self.right = other.right;
46 }
47
48 #[inline]
49 pub fn not_equal(&self, ex: i32, ey: i32, style: &CellStyleAa) -> bool {
50 (ex as u32).wrapping_sub(self.x as u32)
51 | (ey as u32).wrapping_sub(self.y as u32)
52 | (self.left as u32).wrapping_sub(style.left as u32)
53 | (self.right as u32).wrapping_sub(style.right as u32)
54 != 0
55 }
56}
57
58impl Default for CellStyleAa {
59 fn default() -> Self {
60 Self {
61 x: i32::MAX,
62 y: i32::MAX,
63 cover: 0,
64 area: 0,
65 left: -1,
66 right: -1,
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub enum LayerOrder {
80 Unsorted,
81 Direct,
82 Inverse,
83}
84
85const DX_LIMIT: i64 = 16384 << POLY_SUBPIXEL_SHIFT;
91
92#[derive(Debug, Clone, Copy, Default)]
93struct SortedY {
94 start: u32,
95 num: u32,
96}
97
98struct CellsEngine {
101 cells: Vec<CellStyleAa>,
102 sorted_cells: Vec<u32>,
103 sorted_y: Vec<SortedY>,
104 curr_cell: CellStyleAa,
105 style_cell: CellStyleAa,
106 min_x: i32,
107 min_y: i32,
108 max_x: i32,
109 max_y: i32,
110 sorted: bool,
111}
112
113impl CellsEngine {
114 fn new() -> Self {
115 Self {
116 cells: Vec::new(),
117 sorted_cells: Vec::new(),
118 sorted_y: Vec::new(),
119 curr_cell: CellStyleAa::default(),
120 style_cell: CellStyleAa::default(),
121 min_x: i32::MAX,
122 min_y: i32::MAX,
123 max_x: i32::MIN,
124 max_y: i32::MIN,
125 sorted: false,
126 }
127 }
128
129 fn reset(&mut self) {
130 self.cells.clear();
131 self.sorted_cells.clear();
132 self.sorted_y.clear();
133 self.curr_cell.initial();
134 self.style_cell.initial();
135 self.min_x = i32::MAX;
136 self.min_y = i32::MAX;
137 self.max_x = i32::MIN;
138 self.max_y = i32::MIN;
139 self.sorted = false;
140 }
141
142 #[inline]
143 fn style(&mut self, style_cell: &CellStyleAa) {
144 self.style_cell.style(style_cell);
145 }
146
147 #[inline]
148 fn min_x(&self) -> i32 {
149 self.min_x
150 }
151 #[inline]
152 fn min_y(&self) -> i32 {
153 self.min_y
154 }
155 #[inline]
156 fn max_x(&self) -> i32 {
157 self.max_x
158 }
159 #[inline]
160 fn max_y(&self) -> i32 {
161 self.max_y
162 }
163 #[inline]
164 fn total_cells(&self) -> u32 {
165 self.cells.len() as u32
166 }
167 #[inline]
168 fn sorted(&self) -> bool {
169 self.sorted
170 }
171
172 #[inline]
173 fn scanline_num_cells(&self, y: u32) -> u32 {
174 self.sorted_y[(y as i32 - self.min_y) as usize].num
175 }
176
177 #[inline]
179 fn scanline_cells(&self, y: u32) -> &[u32] {
180 let sy = &self.sorted_y[(y as i32 - self.min_y) as usize];
181 &self.sorted_cells[sy.start as usize..(sy.start + sy.num) as usize]
182 }
183
184 #[inline]
185 fn cell(&self, idx: u32) -> &CellStyleAa {
186 &self.cells[idx as usize]
187 }
188
189 #[inline]
190 fn add_curr_cell(&mut self) {
191 if self.curr_cell.area | self.curr_cell.cover != 0 {
192 self.cells.push(self.curr_cell);
193 }
194 }
195
196 #[inline]
197 fn set_curr_cell(&mut self, x: i32, y: i32) {
198 if self.curr_cell.not_equal(x, y, &self.style_cell) {
199 self.add_curr_cell();
200 self.curr_cell.style(&self.style_cell);
201 self.curr_cell.x = x;
202 self.curr_cell.y = y;
203 self.curr_cell.cover = 0;
204 self.curr_cell.area = 0;
205 }
206 }
207
208 fn render_hline(&mut self, ey: i32, x1: i32, y1: i32, x2: i32, y2: i32) {
209 let ex1 = x1 >> POLY_SUBPIXEL_SHIFT;
210 let ex2 = x2 >> POLY_SUBPIXEL_SHIFT;
211 let fx1 = x1 & POLY_SUBPIXEL_MASK as i32;
212 let fx2 = x2 & POLY_SUBPIXEL_MASK as i32;
213
214 if y1 == y2 {
215 self.set_curr_cell(ex2, ey);
216 return;
217 }
218
219 if ex1 == ex2 {
220 let delta = y2 - y1;
221 self.curr_cell.cover += delta;
222 self.curr_cell.area += (fx1 + fx2) * delta;
223 return;
224 }
225
226 let mut p = (POLY_SUBPIXEL_SCALE as i64 - fx1 as i64) * (y2 - y1) as i64;
227 let mut first = POLY_SUBPIXEL_SCALE as i32;
228 let mut incr = 1_i32;
229 let mut dx = x2 as i64 - x1 as i64;
230
231 if dx < 0 {
232 p = fx1 as i64 * (y2 - y1) as i64;
233 first = 0;
234 incr = -1;
235 dx = -dx;
236 }
237
238 let mut delta = (p / dx) as i32;
239 let mut modulo = p % dx;
240 if modulo < 0 {
241 delta -= 1;
242 modulo += dx;
243 }
244
245 self.curr_cell.cover += delta;
246 self.curr_cell.area += (fx1 + first) * delta;
247
248 let mut ex1 = ex1 + incr;
249 self.set_curr_cell(ex1, ey);
250 let mut y1 = y1 + delta;
251
252 if ex1 != ex2 {
253 p = POLY_SUBPIXEL_SCALE as i64 * (y2 - y1 + delta) as i64;
254 let mut lift = (p / dx) as i32;
255 let mut rem = p % dx;
256 if rem < 0 {
257 lift -= 1;
258 rem += dx;
259 }
260 modulo -= dx;
261
262 while ex1 != ex2 {
263 delta = lift;
264 modulo += rem;
265 if modulo >= 0 {
266 modulo -= dx;
267 delta += 1;
268 }
269 self.curr_cell.cover += delta;
270 self.curr_cell.area += POLY_SUBPIXEL_SCALE as i32 * delta;
271 y1 += delta;
272 ex1 += incr;
273 self.set_curr_cell(ex1, ey);
274 }
275 }
276 delta = y2 - y1;
277 self.curr_cell.cover += delta;
278 self.curr_cell.area += (fx2 + POLY_SUBPIXEL_SCALE as i32 - first) * delta;
279 }
280
281 fn line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) {
282 let dx = x2 as i64 - x1 as i64;
283
284 if dx >= DX_LIMIT || dx <= -DX_LIMIT {
285 let cx = ((x1 as i64 + x2 as i64) >> 1) as i32;
286 let cy = ((y1 as i64 + y2 as i64) >> 1) as i32;
287 self.line(x1, y1, cx, cy);
288 self.line(cx, cy, x2, y2);
289 return;
290 }
291
292 let dy = y2 as i64 - y1 as i64;
293 let ex1 = x1 >> POLY_SUBPIXEL_SHIFT;
294 let ex2 = x2 >> POLY_SUBPIXEL_SHIFT;
295 let ey1_orig = y1 >> POLY_SUBPIXEL_SHIFT;
296 let ey2 = y2 >> POLY_SUBPIXEL_SHIFT;
297 let fy1 = y1 & POLY_SUBPIXEL_MASK as i32;
298 let fy2 = y2 & POLY_SUBPIXEL_MASK as i32;
299
300 if ex1 < self.min_x { self.min_x = ex1; }
301 if ex1 > self.max_x { self.max_x = ex1; }
302 if ey1_orig < self.min_y { self.min_y = ey1_orig; }
303 if ey1_orig > self.max_y { self.max_y = ey1_orig; }
304 if ex2 < self.min_x { self.min_x = ex2; }
305 if ex2 > self.max_x { self.max_x = ex2; }
306 if ey2 < self.min_y { self.min_y = ey2; }
307 if ey2 > self.max_y { self.max_y = ey2; }
308
309 let mut ey1 = ey1_orig;
310 self.set_curr_cell(ex1, ey1);
311
312 if ey1 == ey2 {
313 self.render_hline(ey1, x1, fy1, x2, fy2);
314 return;
315 }
316
317 let mut incr = 1_i32;
318 if dx == 0 {
319 let ex = x1 >> POLY_SUBPIXEL_SHIFT;
320 let two_fx = (x1 - (ex << POLY_SUBPIXEL_SHIFT)) << 1;
321 let mut first = POLY_SUBPIXEL_SCALE as i32;
322 if dy < 0 {
323 first = 0;
324 incr = -1;
325 }
326 let mut delta = first - fy1;
327 self.curr_cell.cover += delta;
328 self.curr_cell.area += two_fx * delta;
329 ey1 += incr;
330 self.set_curr_cell(ex, ey1);
331
332 delta = first + first - POLY_SUBPIXEL_SCALE as i32;
333 let area = two_fx * delta;
334 while ey1 != ey2 {
335 self.curr_cell.cover = delta;
336 self.curr_cell.area = area;
337 ey1 += incr;
338 self.set_curr_cell(ex, ey1);
339 }
340 delta = fy2 - POLY_SUBPIXEL_SCALE as i32 + first;
341 self.curr_cell.cover += delta;
342 self.curr_cell.area += two_fx * delta;
343 return;
344 }
345
346 let mut p = (POLY_SUBPIXEL_SCALE as i64 - fy1 as i64) * dx;
347 let mut first = POLY_SUBPIXEL_SCALE as i32;
348 let mut dy_abs = dy;
349 if dy < 0 {
350 p = fy1 as i64 * dx;
351 first = 0;
352 incr = -1;
353 dy_abs = -dy;
354 }
355
356 let mut delta = (p / dy_abs) as i32;
357 let mut modulo = p % dy_abs;
358 if modulo < 0 {
359 delta -= 1;
360 modulo += dy_abs;
361 }
362
363 let mut x_from = x1 + delta;
364 self.render_hline(ey1, x1, fy1, x_from, first);
365 ey1 += incr;
366 self.set_curr_cell(x_from >> POLY_SUBPIXEL_SHIFT, ey1);
367
368 if ey1 != ey2 {
369 p = POLY_SUBPIXEL_SCALE as i64 * dx;
370 let mut lift = (p / dy_abs) as i32;
371 let mut rem = p % dy_abs;
372 if rem < 0 {
373 lift -= 1;
374 rem += dy_abs;
375 }
376 modulo -= dy_abs;
377
378 while ey1 != ey2 {
379 delta = lift;
380 modulo += rem;
381 if modulo >= 0 {
382 modulo -= dy_abs;
383 delta += 1;
384 }
385 let x_to = x_from + delta;
386 self.render_hline(
387 ey1,
388 x_from,
389 POLY_SUBPIXEL_SCALE as i32 - first,
390 x_to,
391 first,
392 );
393 x_from = x_to;
394 ey1 += incr;
395 self.set_curr_cell(x_from >> POLY_SUBPIXEL_SHIFT, ey1);
396 }
397 }
398 self.render_hline(ey1, x_from, POLY_SUBPIXEL_SCALE as i32 - first, x2, fy2);
399 }
400
401 fn sort_cells(&mut self) {
402 if self.sorted {
403 return;
404 }
405
406 self.add_curr_cell();
407 self.curr_cell.initial();
408
409 if self.cells.is_empty() {
410 return;
411 }
412
413 let num_cells = self.cells.len();
414 self.sorted_cells.clear();
415 self.sorted_cells.resize(num_cells, 0);
416
417 let y_range = (self.max_y - self.min_y + 1) as usize;
418 self.sorted_y.clear();
419 self.sorted_y.resize(y_range, SortedY::default());
420
421 for cell in &self.cells {
422 let yi = (cell.y - self.min_y) as usize;
423 self.sorted_y[yi].start += 1;
424 }
425
426 let mut start = 0u32;
427 for sy in &mut self.sorted_y {
428 let count = sy.start;
429 sy.start = start;
430 start += count;
431 }
432
433 for (i, cell) in self.cells.iter().enumerate() {
434 let yi = (cell.y - self.min_y) as usize;
435 let sy = &mut self.sorted_y[yi];
436 self.sorted_cells[(sy.start + sy.num) as usize] = i as u32;
437 sy.num += 1;
438 }
439
440 for sy in &self.sorted_y {
441 if sy.num > 0 {
442 let start = sy.start as usize;
443 let end = (sy.start + sy.num) as usize;
444 let slice = &mut self.sorted_cells[start..end];
445 let cells = &self.cells;
446 slice.sort_unstable_by_key(|&idx| cells[idx as usize].x);
447 }
448 }
449
450 self.sorted = true;
451 }
452}
453
454fn upscale(v: f64) -> i32 {
459 iround(v * POLY_SUBPIXEL_SCALE as f64)
460}
461
462fn downscale(v: i32) -> i32 {
463 v
464}
465
466fn clipping_flags(x: i32, y: i32, clip_box: &[i32; 4]) -> u32 {
468 ((x > clip_box[2]) as u32) << 0
469 | ((y > clip_box[3]) as u32) << 1
470 | ((x < clip_box[0]) as u32) << 2
471 | ((y < clip_box[1]) as u32) << 3
472}
473
474fn clip_line_segment(
476 engine: &mut CellsEngine,
477 x1: &mut i32,
478 y1: &mut i32,
479 x2: i32,
480 y2: i32,
481 clip_box: &[i32; 4],
482) {
483 let f1 = clipping_flags(*x1, *y1, clip_box);
484 let f2 = clipping_flags(x2, y2, clip_box);
485
486 if f1 == 0 && f2 == 0 {
487 engine.line(*x1, *y1, x2, y2);
489 } else if (f1 & f2) != 0 {
490 } else {
492 let mut cx1 = *x1;
494 let mut cy1 = *y1;
495 let mut cx2 = x2;
496 let mut cy2 = y2;
497
498 if liang_barsky_clip(&mut cx1, &mut cy1, &mut cx2, &mut cy2, clip_box) {
499 engine.line(cx1, cy1, cx2, cy2);
500 }
501 }
502 *x1 = x2;
503 *y1 = y2;
504}
505
506fn liang_barsky_clip(
508 x1: &mut i32,
509 y1: &mut i32,
510 x2: &mut i32,
511 y2: &mut i32,
512 clip: &[i32; 4],
513) -> bool {
514 let dx = *x2 as f64 - *x1 as f64;
515 let dy = *y2 as f64 - *y1 as f64;
516 let mut t0 = 0.0f64;
517 let mut t1 = 1.0f64;
518
519 let clips = [
520 (-dx, *x1 as f64 - clip[0] as f64),
521 (dx, clip[2] as f64 - *x1 as f64),
522 (-dy, *y1 as f64 - clip[1] as f64),
523 (dy, clip[3] as f64 - *y1 as f64),
524 ];
525
526 for &(p, q) in &clips {
527 if p.abs() < 1e-10 {
528 if q < 0.0 {
529 return false;
530 }
531 } else {
532 let t = q / p;
533 if p < 0.0 {
534 if t > t1 {
535 return false;
536 }
537 if t > t0 {
538 t0 = t;
539 }
540 } else {
541 if t < t0 {
542 return false;
543 }
544 if t < t1 {
545 t1 = t;
546 }
547 }
548 }
549 }
550
551 let ox1 = *x1 as f64;
552 let oy1 = *y1 as f64;
553 if t1 < 1.0 {
554 *x2 = (ox1 + dx * t1) as i32;
555 *y2 = (oy1 + dy * t1) as i32;
556 }
557 if t0 > 0.0 {
558 *x1 = (ox1 + dx * t0) as i32;
559 *y1 = (oy1 + dy * t0) as i32;
560 }
561 true
562}
563
564#[derive(Debug, Clone, Copy)]
569struct StyleInfo {
570 start_cell: u32,
571 num_cells: u32,
572 last_x: i32,
573}
574
575impl Default for StyleInfo {
576 fn default() -> Self {
577 Self {
578 start_cell: 0,
579 num_cells: 0,
580 last_x: i32::MIN,
581 }
582 }
583}
584
585#[derive(Debug, Clone, Copy, Default)]
586struct CellInfo {
587 x: i32,
588 area: i32,
589 cover: i32,
590}
591
592const AA_SHIFT: u32 = 8;
597const AA_SCALE: u32 = 1 << AA_SHIFT;
598const AA_MASK: u32 = AA_SCALE - 1;
599const AA_SCALE2: u32 = AA_SCALE * 2;
600const AA_MASK2: u32 = AA_SCALE2 - 1;
601
602pub struct RasterizerCompoundAa {
608 outline: CellsEngine,
609 filling_rule: FillingRule,
610 layer_order: LayerOrder,
611 styles: Vec<StyleInfo>,
612 ast: Vec<u32>, asm: Vec<u8>, cells: Vec<CellInfo>,
615 cover_buf: Vec<u8>,
616 min_style: i32,
617 max_style: i32,
618 start_x: i32,
619 start_y: i32,
620 scan_y: i32,
621 sl_start: i32,
622 sl_len: u32,
623 clipping: bool,
625 clip_box: [i32; 4], clip_x1: i32,
627 clip_y1: i32,
628}
629
630impl RasterizerCompoundAa {
631 pub fn new() -> Self {
632 Self {
633 outline: CellsEngine::new(),
634 filling_rule: FillingRule::NonZero,
635 layer_order: LayerOrder::Direct,
636 styles: Vec::new(),
637 ast: Vec::new(),
638 asm: Vec::new(),
639 cells: Vec::new(),
640 cover_buf: Vec::new(),
641 min_style: i32::MAX,
642 max_style: i32::MIN,
643 start_x: 0,
644 start_y: 0,
645 scan_y: i32::MAX,
646 sl_start: 0,
647 sl_len: 0,
648 clipping: false,
649 clip_box: [0; 4],
650 clip_x1: 0,
651 clip_y1: 0,
652 }
653 }
654
655 pub fn reset(&mut self) {
656 self.outline.reset();
657 self.min_style = i32::MAX;
658 self.max_style = i32::MIN;
659 self.scan_y = i32::MAX;
660 self.sl_start = 0;
661 self.sl_len = 0;
662 }
663
664 pub fn reset_clipping(&mut self) {
665 self.reset();
666 self.clipping = false;
667 }
668
669 pub fn clip_box(&mut self, x1: f64, y1: f64, x2: f64, y2: f64) {
670 self.reset();
671 self.clipping = true;
672 self.clip_box = [upscale(x1), upscale(y1), upscale(x2), upscale(y2)];
673 }
674
675 pub fn filling_rule(&mut self, rule: FillingRule) {
676 self.filling_rule = rule;
677 }
678
679 pub fn layer_order(&mut self, order: LayerOrder) {
680 self.layer_order = order;
681 }
682
683 pub fn styles(&mut self, left: i32, right: i32) {
685 let mut cell = CellStyleAa::default();
686 cell.initial();
687 cell.left = left as i16;
688 cell.right = right as i16;
689 self.outline.style(&cell);
690 if left >= 0 && left < self.min_style {
691 self.min_style = left;
692 }
693 if left >= 0 && left > self.max_style {
694 self.max_style = left;
695 }
696 if right >= 0 && right < self.min_style {
697 self.min_style = right;
698 }
699 if right >= 0 && right > self.max_style {
700 self.max_style = right;
701 }
702 }
703
704 pub fn move_to(&mut self, x: i32, y: i32) {
706 if self.outline.sorted() {
707 self.reset();
708 }
709 self.start_x = downscale(x);
710 self.start_y = downscale(y);
711 if self.clipping {
712 self.clip_x1 = self.start_x;
713 self.clip_y1 = self.start_y;
714 }
715 }
716
717 pub fn line_to(&mut self, x: i32, y: i32) {
719 let x = downscale(x);
720 let y = downscale(y);
721 if self.clipping {
722 clip_line_segment(
723 &mut self.outline,
724 &mut self.clip_x1,
725 &mut self.clip_y1,
726 x,
727 y,
728 &self.clip_box,
729 );
730 } else {
731 self.outline.line(self.clip_x1, self.clip_y1, x, y);
732 self.clip_x1 = x;
733 self.clip_y1 = y;
734 }
735 }
736
737 pub fn move_to_d(&mut self, x: f64, y: f64) {
739 if self.outline.sorted() {
740 self.reset();
741 }
742 self.start_x = upscale(x);
743 self.start_y = upscale(y);
744 if self.clipping {
745 self.clip_x1 = self.start_x;
746 self.clip_y1 = self.start_y;
747 } else {
748 self.clip_x1 = self.start_x;
749 self.clip_y1 = self.start_y;
750 }
751 }
752
753 pub fn line_to_d(&mut self, x: f64, y: f64) {
755 let x = upscale(x);
756 let y = upscale(y);
757 if self.clipping {
758 clip_line_segment(
759 &mut self.outline,
760 &mut self.clip_x1,
761 &mut self.clip_y1,
762 x,
763 y,
764 &self.clip_box,
765 );
766 } else {
767 self.outline.line(self.clip_x1, self.clip_y1, x, y);
768 self.clip_x1 = x;
769 self.clip_y1 = y;
770 }
771 }
772
773 pub fn add_vertex(&mut self, x: f64, y: f64, cmd: u32) {
775 if is_move_to(cmd) {
776 self.move_to_d(x, y);
777 } else if is_vertex(cmd) {
778 self.line_to_d(x, y);
779 } else if is_close(cmd) {
780 let sx = self.start_x;
781 let sy = self.start_y;
782 if self.clipping {
783 clip_line_segment(
784 &mut self.outline,
785 &mut self.clip_x1,
786 &mut self.clip_y1,
787 sx,
788 sy,
789 &self.clip_box,
790 );
791 } else {
792 self.outline.line(self.clip_x1, self.clip_y1, sx, sy);
793 self.clip_x1 = sx;
794 self.clip_y1 = sy;
795 }
796 }
797 }
798
799 pub fn edge(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) {
801 if self.outline.sorted() {
802 self.reset();
803 }
804 let x1 = downscale(x1);
805 let y1 = downscale(y1);
806 let x2 = downscale(x2);
807 let y2 = downscale(y2);
808 self.outline.line(x1, y1, x2, y2);
809 }
810
811 pub fn edge_d(&mut self, x1: f64, y1: f64, x2: f64, y2: f64) {
813 if self.outline.sorted() {
814 self.reset();
815 }
816 self.outline
817 .line(upscale(x1), upscale(y1), upscale(x2), upscale(y2));
818 }
819
820 pub fn add_path<VS: VertexSource>(&mut self, vs: &mut VS, path_id: u32) {
822 let mut x = 0.0;
823 let mut y = 0.0;
824 vs.rewind(path_id);
825 if self.outline.sorted() {
826 self.reset();
827 }
828 loop {
829 let cmd = vs.vertex(&mut x, &mut y);
830 if is_stop(cmd) {
831 break;
832 }
833 self.add_vertex(x, y, cmd);
834 }
835 }
836
837 pub fn min_x(&self) -> i32 {
838 self.outline.min_x()
839 }
840 pub fn min_y(&self) -> i32 {
841 self.outline.min_y()
842 }
843 pub fn max_x(&self) -> i32 {
844 self.outline.max_x()
845 }
846 pub fn max_y(&self) -> i32 {
847 self.outline.max_y()
848 }
849 pub fn min_style(&self) -> i32 {
850 self.min_style
851 }
852 pub fn max_style(&self) -> i32 {
853 self.max_style
854 }
855
856 pub fn sort(&mut self) {
858 self.outline.sort_cells();
859 }
860
861 pub fn rewind_scanlines(&mut self) -> bool {
863 self.outline.sort_cells();
864 if self.outline.total_cells() == 0 {
865 return false;
866 }
867 if self.max_style < self.min_style {
868 return false;
869 }
870 self.scan_y = self.outline.min_y();
871 let num_styles = (self.max_style - self.min_style + 2) as usize;
872 self.styles.resize(num_styles, StyleInfo::default());
873 true
874 }
875
876 #[inline]
878 pub fn calculate_alpha(&self, area: i32) -> u32 {
879 let mut cover = area >> (POLY_SUBPIXEL_SHIFT * 2 + 1 - AA_SHIFT);
880 if cover < 0 {
881 cover = -cover;
882 }
883 if self.filling_rule == FillingRule::EvenOdd {
884 cover &= AA_MASK2 as i32;
885 if cover > AA_SCALE as i32 {
886 cover = AA_SCALE2 as i32 - cover;
887 }
888 }
889 if cover > AA_MASK as i32 {
890 cover = AA_MASK as i32;
891 }
892 cover as u32
893 }
894
895 fn add_style(&mut self, style_id: i32) {
897 let style_id = if style_id < 0 {
898 0
899 } else {
900 (style_id - self.min_style + 1) as u32
901 } as usize;
902
903 let nbyte = style_id >> 3;
904 let mask = 1u8 << (style_id & 7);
905
906 if (self.asm[nbyte] & mask) == 0 {
907 self.ast.push(style_id as u32);
908 self.asm[nbyte] |= mask;
909 self.styles[style_id].start_cell = 0;
910 self.styles[style_id].num_cells = 0;
911 self.styles[style_id].last_x = i32::MIN;
912 }
913 self.styles[style_id].start_cell += 1;
914 }
915
916 pub fn sweep_styles(&mut self) -> u32 {
920 loop {
921 if self.scan_y > self.outline.max_y() {
922 return 0;
923 }
924 let num_cells = self.outline.scanline_num_cells(self.scan_y as u32);
925 let cell_indices: Vec<u32> =
926 self.outline.scanline_cells(self.scan_y as u32).to_vec();
927
928 let num_styles = (self.max_style - self.min_style + 2) as usize;
929
930 self.cells
931 .resize(num_cells as usize * 2, CellInfo::default());
932 self.ast.clear();
933 self.ast.reserve(num_styles);
934 self.asm.clear();
935 self.asm.resize((num_styles + 7) >> 3, 0);
936
937 if num_cells > 0 {
938 self.asm[0] |= 1;
940 self.ast.push(0);
941 self.styles[0].start_cell = 0;
942 self.styles[0].num_cells = 0;
943 self.styles[0].last_x = i32::MIN;
944
945 let first_x = self.outline.cell(cell_indices[0]).x;
946 let last_x = self.outline.cell(cell_indices[num_cells as usize - 1]).x;
947 self.sl_start = first_x;
948 self.sl_len = (last_x - first_x + 1) as u32;
949
950 let style_pairs: Vec<(i16, i16)> = (0..num_cells as usize)
953 .map(|i| {
954 let c = self.outline.cell(cell_indices[i]);
955 (c.left, c.right)
956 })
957 .collect();
958 for &(left, right) in &style_pairs {
959 self.add_style(left as i32);
960 self.add_style(right as i32);
961 }
962
963 let mut start_cell = 0u32;
965 for i in 0..self.ast.len() {
966 let si = self.ast[i] as usize;
967 let v = self.styles[si].start_cell;
968 self.styles[si].start_cell = start_cell;
969 start_cell += v;
970 }
971
972 let cell_indices2: Vec<u32> =
974 self.outline.scanline_cells(self.scan_y as u32).to_vec();
975 for i in 0..num_cells as usize {
976 let curr_cell = self.outline.cell(cell_indices2[i]);
977
978 let style_id = if curr_cell.left < 0 {
980 0usize
981 } else {
982 (curr_cell.left as i32 - self.min_style + 1) as usize
983 };
984
985 let style = &mut self.styles[style_id];
986 if curr_cell.x == style.last_x {
987 let ci = (style.start_cell + style.num_cells - 1) as usize;
988 self.cells[ci].area += curr_cell.area;
989 self.cells[ci].cover += curr_cell.cover;
990 } else {
991 let ci = (style.start_cell + style.num_cells) as usize;
992 self.cells[ci].x = curr_cell.x;
993 self.cells[ci].area = curr_cell.area;
994 self.cells[ci].cover = curr_cell.cover;
995 style.last_x = curr_cell.x;
996 style.num_cells += 1;
997 }
998
999 let style_id = if curr_cell.right < 0 {
1001 0usize
1002 } else {
1003 (curr_cell.right as i32 - self.min_style + 1) as usize
1004 };
1005
1006 let style = &mut self.styles[style_id];
1007 if curr_cell.x == style.last_x {
1008 let ci = (style.start_cell + style.num_cells - 1) as usize;
1009 self.cells[ci].area -= curr_cell.area;
1010 self.cells[ci].cover -= curr_cell.cover;
1011 } else {
1012 let ci = (style.start_cell + style.num_cells) as usize;
1013 self.cells[ci].x = curr_cell.x;
1014 self.cells[ci].area = -curr_cell.area;
1015 self.cells[ci].cover = -curr_cell.cover;
1016 style.last_x = curr_cell.x;
1017 style.num_cells += 1;
1018 }
1019 }
1020 }
1021
1022 if self.ast.len() > 1 {
1023 break;
1024 }
1025 self.scan_y += 1;
1026 }
1027 self.scan_y += 1;
1028
1029 if self.layer_order != LayerOrder::Unsorted && self.ast.len() > 1 {
1031 let ast_slice = &mut self.ast[1..];
1032 match self.layer_order {
1033 LayerOrder::Direct => ast_slice.sort_unstable_by(|a, b| b.cmp(a)),
1034 LayerOrder::Inverse => ast_slice.sort_unstable(),
1035 LayerOrder::Unsorted => {}
1036 }
1037 }
1038
1039 (self.ast.len() - 1) as u32
1040 }
1041
1042 #[inline]
1044 pub fn style(&self, style_idx: u32) -> u32 {
1045 (self.ast[style_idx as usize + 1] as i32 + self.min_style - 1) as u32
1046 }
1047
1048 pub fn scanline_start(&self) -> i32 {
1050 self.sl_start
1051 }
1052
1053 pub fn scanline_length(&self) -> u32 {
1055 self.sl_len
1056 }
1057
1058 pub fn sweep_scanline<SL: Scanline>(&self, sl: &mut SL, style_idx: i32) -> bool {
1062 let scan_y = self.scan_y - 1;
1063 if scan_y > self.outline.max_y() {
1064 return false;
1065 }
1066
1067 sl.reset_spans();
1068
1069 let si = if style_idx < 0 {
1070 0usize
1071 } else {
1072 (style_idx + 1) as usize
1073 };
1074
1075 let st = &self.styles[self.ast[si] as usize];
1076 let mut num_cells = st.num_cells;
1077 let mut cell_idx = st.start_cell;
1078
1079 let mut cover = 0i32;
1080 while num_cells > 0 {
1081 num_cells -= 1;
1082 let cell = &self.cells[cell_idx as usize];
1083 let x = cell.x;
1084 let area = cell.area;
1085 cover += cell.cover;
1086 cell_idx += 1;
1087
1088 if area != 0 {
1089 let alpha =
1090 self.calculate_alpha((cover << (POLY_SUBPIXEL_SHIFT + 1)) - area as u32 as i32);
1091 sl.add_cell(x, alpha);
1092 if num_cells > 0 && self.cells[cell_idx as usize].x > x + 1 {
1093 let alpha = self.calculate_alpha(cover << (POLY_SUBPIXEL_SHIFT + 1));
1094 if alpha > 0 {
1095 sl.add_span(
1096 x + 1,
1097 (self.cells[cell_idx as usize].x - x - 1) as u32,
1098 alpha,
1099 );
1100 }
1101 }
1102 } else if num_cells > 0 && self.cells[cell_idx as usize].x > x {
1103 let alpha = self.calculate_alpha(cover << (POLY_SUBPIXEL_SHIFT + 1));
1104 if alpha > 0 {
1105 sl.add_span(x, (self.cells[cell_idx as usize].x - x) as u32, alpha);
1106 }
1107 }
1108 }
1109
1110 if sl.num_spans() == 0 {
1111 return false;
1112 }
1113 sl.finalize(scan_y);
1114 true
1115 }
1116
1117 pub fn navigate_scanline(&mut self, y: i32) -> bool {
1119 self.outline.sort_cells();
1120 if self.outline.total_cells() == 0 {
1121 return false;
1122 }
1123 if self.max_style < self.min_style {
1124 return false;
1125 }
1126 if y < self.outline.min_y() || y > self.outline.max_y() {
1127 return false;
1128 }
1129 self.scan_y = y;
1130 let num_styles = (self.max_style - self.min_style + 2) as usize;
1131 self.styles.resize(num_styles, StyleInfo::default());
1132 true
1133 }
1134
1135 pub fn allocate_cover_buffer(&mut self, len: u32) -> &mut [u8] {
1137 self.cover_buf.resize(len as usize, 0);
1138 &mut self.cover_buf
1139 }
1140}
1141
1142impl Default for RasterizerCompoundAa {
1143 fn default() -> Self {
1144 Self::new()
1145 }
1146}
1147
1148#[cfg(test)]
1153mod tests {
1154 use super::*;
1155 use crate::scanline_u::ScanlineU8;
1156
1157 #[test]
1158 fn test_cell_style_aa_default() {
1159 let cell = CellStyleAa::default();
1160 assert_eq!(cell.x, i32::MAX);
1161 assert_eq!(cell.y, i32::MAX);
1162 assert_eq!(cell.left, -1);
1163 assert_eq!(cell.right, -1);
1164 }
1165
1166 #[test]
1167 fn test_cell_style_aa_not_equal() {
1168 let mut c1 = CellStyleAa::default();
1169 c1.x = 10;
1170 c1.y = 20;
1171 c1.left = 1;
1172 c1.right = 2;
1173
1174 let mut style = CellStyleAa::default();
1175 style.left = 1;
1176 style.right = 2;
1177 assert!(!c1.not_equal(10, 20, &style));
1179 assert!(c1.not_equal(11, 20, &style));
1181 style.left = 3;
1183 assert!(c1.not_equal(10, 20, &style));
1184 }
1185
1186 #[test]
1187 fn test_empty_rasterizer() {
1188 let mut ras = RasterizerCompoundAa::new();
1189 assert!(!ras.rewind_scanlines());
1190 }
1191
1192 #[test]
1193 fn test_simple_rectangle_two_styles() {
1194 let mut ras = RasterizerCompoundAa::new();
1195
1196 let scale = POLY_SUBPIXEL_SCALE as i32;
1199
1200 ras.styles(0, -1);
1202 ras.move_to(10 * scale, 10 * scale);
1203 ras.line_to(10 * scale, 20 * scale);
1204
1205 ras.styles(-1, 0);
1207 ras.line_to(20 * scale, 20 * scale);
1208
1209 ras.styles(-1, 0);
1211 ras.line_to(20 * scale, 10 * scale);
1212
1213 ras.styles(0, -1);
1215 ras.line_to(10 * scale, 10 * scale);
1216
1217 assert!(ras.rewind_scanlines());
1218 assert_eq!(ras.min_style(), 0);
1219 assert_eq!(ras.max_style(), 0);
1220
1221 let num_styles = ras.sweep_styles();
1223 assert!(num_styles >= 1, "Expected at least 1 style, got {num_styles}");
1224 }
1225
1226 #[test]
1227 fn test_two_adjacent_styles() {
1228 let mut ras = RasterizerCompoundAa::new();
1229 let s = POLY_SUBPIXEL_SCALE as i32;
1230
1231 ras.styles(0, -1);
1236 ras.move_to(10 * s, 10 * s);
1237 ras.line_to(10 * s, 20 * s);
1238
1239 ras.styles(0, 1);
1241 ras.line_to(15 * s, 20 * s);
1242 ras.line_to(15 * s, 10 * s);
1243
1244 ras.styles(0, -1);
1245 ras.line_to(10 * s, 10 * s);
1246
1247 ras.styles(1, -1);
1249 ras.move_to(15 * s, 10 * s);
1250 ras.line_to(15 * s, 20 * s);
1251
1252 ras.styles(-1, 1);
1253 ras.line_to(20 * s, 20 * s);
1254 ras.line_to(20 * s, 10 * s);
1255
1256 ras.styles(1, -1);
1257 ras.line_to(15 * s, 10 * s);
1258
1259 assert!(ras.rewind_scanlines());
1260 assert_eq!(ras.min_style(), 0);
1261 assert_eq!(ras.max_style(), 1);
1262 }
1263
1264 #[test]
1265 fn test_sweep_scanline_produces_spans() {
1266 let mut ras = RasterizerCompoundAa::new();
1267 let s = POLY_SUBPIXEL_SCALE as i32;
1268
1269 ras.styles(0, -1);
1271 ras.move_to(10 * s, 10 * s);
1272 ras.line_to(10 * s, 20 * s);
1273
1274 ras.styles(-1, 0);
1275 ras.line_to(20 * s, 20 * s);
1276 ras.line_to(20 * s, 10 * s);
1277
1278 ras.styles(0, -1);
1279 ras.line_to(10 * s, 10 * s);
1280
1281 assert!(ras.rewind_scanlines());
1282
1283 let num_styles = ras.sweep_styles();
1284 assert!(num_styles >= 1);
1285
1286 let mut sl = ScanlineU8::new();
1287 sl.reset(0, 100);
1288 let ok = ras.sweep_scanline(&mut sl, 0);
1290 if ok {
1291 assert!(sl.num_spans() > 0);
1292 }
1293 }
1294
1295 #[test]
1296 fn test_layer_order() {
1297 let mut ras = RasterizerCompoundAa::new();
1298 ras.layer_order(LayerOrder::Direct);
1299 ras.layer_order(LayerOrder::Inverse);
1300 ras.layer_order(LayerOrder::Unsorted);
1301 }
1302
1303 #[test]
1304 fn test_calculate_alpha() {
1305 let ras = RasterizerCompoundAa::new();
1306 let full_area = (POLY_SUBPIXEL_SCALE * POLY_SUBPIXEL_SCALE * 2) as i32;
1308 let alpha = ras.calculate_alpha(full_area);
1309 assert_eq!(alpha, AA_MASK);
1310
1311 assert_eq!(ras.calculate_alpha(0), 0);
1313 }
1314
1315 #[test]
1316 fn test_add_path() {
1317 use crate::path_storage::PathStorage;
1318
1319 let mut ras = RasterizerCompoundAa::new();
1320 let mut path = PathStorage::new();
1321 path.move_to(10.0, 10.0);
1322 path.line_to(20.0, 10.0);
1323 path.line_to(20.0, 20.0);
1324 path.close_polygon(0);
1325
1326 ras.styles(0, -1);
1327 ras.add_path(&mut path, 0);
1328
1329 assert!(ras.rewind_scanlines());
1330 }
1331
1332 #[test]
1333 fn test_edge_methods() {
1334 let mut ras = RasterizerCompoundAa::new();
1335 let s = POLY_SUBPIXEL_SCALE as i32;
1336
1337 ras.styles(0, -1);
1338 ras.edge(10 * s, 10 * s, 20 * s, 10 * s);
1339 ras.edge(20 * s, 10 * s, 20 * s, 20 * s);
1340 ras.edge(20 * s, 20 * s, 10 * s, 20 * s);
1341 ras.edge(10 * s, 20 * s, 10 * s, 10 * s);
1342
1343 assert!(ras.rewind_scanlines());
1344 }
1345
1346 #[test]
1347 fn test_clip_box() {
1348 let mut ras = RasterizerCompoundAa::new();
1349 ras.clip_box(0.0, 0.0, 100.0, 100.0);
1350
1351 let s = POLY_SUBPIXEL_SCALE as i32;
1352 ras.styles(0, -1);
1353 ras.move_to(10 * s, 10 * s);
1354 ras.line_to(10 * s, 20 * s);
1355 ras.line_to(20 * s, 20 * s);
1356 ras.line_to(20 * s, 10 * s);
1357 ras.line_to(10 * s, 10 * s);
1358
1359 assert!(ras.rewind_scanlines());
1360 }
1361
1362 #[test]
1363 fn test_allocate_cover_buffer() {
1364 let mut ras = RasterizerCompoundAa::new();
1365 let buf = ras.allocate_cover_buffer(100);
1366 assert_eq!(buf.len(), 100);
1367 }
1368}