tumo_path/raster/
array.rs1use super::*;
2
3pub struct ArrayStorage<const MAX_BAND: usize = 512, const MAX_CELLS: usize = 1024> {
4 min: FixedPoint,
5 max: FixedPoint,
6 height: usize,
7 cell_count: usize,
8 heap_cells: Vec<Cell>,
9 heap_lines: Vec<i32>,
10 cells: [Cell; MAX_CELLS],
11 lines: [i32; MAX_BAND],
12}
13impl<const MAX_BAND: usize, const MAX_CELLS: usize> ArrayStorage<MAX_BAND, MAX_CELLS> {
14 pub fn new(min: FixedPoint, max: FixedPoint) -> Self {
15 let height = (max.trunc_y() as i64 - min.trunc_y() as i64) as usize;
16 Self {
17 min,
18 max,
19 height,
20 cell_count: 0,
21 heap_cells: Vec::new(),
22 heap_lines: if height > MAX_BAND {
23 let mut v = Vec::with_capacity(height);
24 v.resize(height, -1);
25 v
26 } else {
27 Vec::new()
28 },
29 cells: [Cell::default(); MAX_CELLS],
30 lines: [-1; MAX_BAND],
31 }
32 }
33}
34impl<const MAX_BAND: usize, const MAX_CELLS: usize> Rastive for ArrayStorage<MAX_BAND, MAX_CELLS> {
35 fn reset(&mut self, min: FixedPoint, max: FixedPoint) {
36 let height = (max.trunc_y() as i64 - min.trunc_y() as i64) as usize;
37 self.min = min;
38 self.max = max;
39 self.height = height;
40 self.cell_count = 0;
41 self.heap_cells.clear();
42 self.heap_lines.clear();
43 if self.height > MAX_BAND {
44 self.heap_lines.resize(height, -1);
45 } else {
46 for i in 0..self.height {
47 self.lines[i] = -1;
48 }
49 }
50 }
51 fn bounds(&self) -> (FixedPoint, FixedPoint) {
52 (self.min, self.max)
53 }
54 fn store(&mut self, x: i32, y: i32, area: i32, cover: i32) {
55 let yindex = (y - self.min.trunc_y()) as usize;
56 let lines = if self.height > MAX_BAND {
57 &mut self.heap_lines[..]
58 } else {
59 &mut self.lines[..]
60 };
61 let cells = if !self.heap_cells.is_empty() {
62 &mut self.heap_cells[..]
63 } else {
64 &mut self.cells[..]
65 };
66 let mut cell_index = lines[yindex];
67 let mut last_index = -1;
68 while cell_index != -1 {
69 let cell = &mut cells[cell_index as usize];
70 if cell.x > x {
71 break;
72 } else if cell.x == x {
73 cell.area = cell.area.wrapping_add(area);
74 cell.cover = cell.cover.wrapping_add(cover);
75 return;
76 }
77 last_index = cell_index;
78 cell_index = cell.next;
79 }
80 let new_index = self.cell_count;
81 self.cell_count += 1;
82 let cell = Cell {
83 x,
84 area,
85 cover,
86 next: cell_index,
87 };
88 if last_index != -1 {
89 cells[last_index as usize].next = new_index as i32;
90 } else {
91 lines[yindex] = new_index as i32;
92 }
93 if new_index < MAX_CELLS {
94 cells[new_index] = cell;
95 } else {
96 if self.heap_cells.is_empty() {
97 self.heap_cells.extend_from_slice(&self.cells);
98 }
99 self.heap_cells.push(cell);
100 }
101 }
102 fn cells(&self) -> &[Cell] {
103 if self.cell_count > MAX_CELLS {
104 &self.heap_cells
105 } else {
106 &self.cells
107 }
108 }
109 fn lines(&self) -> &[i32] {
110 if self.height > MAX_BAND {
111 &self.heap_lines
112 } else {
113 &self.lines[..self.height]
114 }
115 }
116}