Skip to main content

tumo_path/raster/
array.rs

1use 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}