123 |
123 |
124 pub fn fill(&mut self, start_point: Point, border_value: T, fill_value: T) { |
124 pub fn fill(&mut self, start_point: Point, border_value: T, fill_value: T) { |
125 debug_assert!(self.is_valid_coordinate(start_point.x - 1, start_point.y)); |
125 debug_assert!(self.is_valid_coordinate(start_point.x - 1, start_point.y)); |
126 debug_assert!(self.is_valid_coordinate(start_point.x, start_point.y)); |
126 debug_assert!(self.is_valid_coordinate(start_point.x, start_point.y)); |
127 |
127 |
|
128 let mask = self.mask; |
|
129 let width = self.width(); |
|
130 |
128 let mut stack: Vec<(usize, usize, usize, isize)> = Vec::new(); |
131 let mut stack: Vec<(usize, usize, usize, isize)> = Vec::new(); |
129 fn push<T: Copy + PartialEq>( |
132 fn push( |
130 land: &Land2D<T>, |
133 mask: SizeMask, |
131 stack: &mut Vec<(usize, usize, usize, isize)>, |
134 stack: &mut Vec<(usize, usize, usize, isize)>, |
132 xl: usize, |
135 xl: usize, |
133 xr: usize, |
136 xr: usize, |
134 y: usize, |
137 y: usize, |
135 dir: isize, |
138 dir: isize, |
136 ) { |
139 ) { |
137 let yd = y as isize + dir; |
140 let yd = y as isize + dir; |
138 |
141 if mask.contains_y(yd as usize) { |
139 if land.is_valid_y(yd as i32) { |
|
140 stack.push((xl, xr, yd as usize, dir)); |
142 stack.push((xl, xr, yd as usize, dir)); |
141 } |
143 } |
142 }; |
144 }; |
143 |
145 |
144 let start_x_l = (start_point.x - 1) as usize; |
146 let start_x_l = (start_point.x - 1) as usize; |
145 let start_x_r = start_point.x as usize; |
147 let start_x_r = start_point.x as usize; |
146 push( |
148 for dir in [-1, 1].iter().cloned() { |
147 self, |
149 push(mask, &mut stack, start_x_l, start_x_r, start_point.y as usize, dir); |
148 &mut stack, |
150 } |
149 start_x_l, |
151 |
150 start_x_r, |
152 while let Some((mut xl, mut xr, y, dir)) = stack.pop() { |
151 start_point.y as usize, |
153 let row = &mut self.pixels[y][..]; |
152 -1, |
154 while xl > 0 && row.get(xl) |
153 ); |
|
154 push( |
|
155 self, |
|
156 &mut stack, |
|
157 start_x_l, |
|
158 start_x_r, |
|
159 start_point.y as usize, |
|
160 1, |
|
161 ); |
|
162 |
|
163 while let Some(a) = stack.pop() { |
|
164 let (mut xl, mut xr, y, mut dir) = a; |
|
165 |
|
166 while xl > 0 && self |
|
167 .pixels |
|
168 .get(y, xl) |
|
169 .map_or(false, |v| *v != border_value && *v != fill_value) |
155 .map_or(false, |v| *v != border_value && *v != fill_value) |
170 { |
156 { |
171 xl -= 1; |
157 xl -= 1; |
172 } |
158 } |
173 |
159 |
174 while xr < self.width() - 1 && self |
160 while xr < width - 1 && row.get(xr) |
175 .pixels |
|
176 .get(y, xr) |
|
177 .map_or(false, |v| *v != border_value && *v != fill_value) |
161 .map_or(false, |v| *v != border_value && *v != fill_value) |
178 { |
162 { |
179 xr += 1; |
163 xr += 1; |
180 } |
164 } |
181 |
165 |
182 while xl < xr { |
166 while xl < xr { |
183 while xl <= xr |
167 while xl <= xr && (row[xl] == border_value || row[xl] == fill_value) |
184 && (self.pixels[y][xl] == border_value || self.pixels[y][xl] == fill_value) |
|
185 { |
168 { |
186 xl += 1; |
169 xl += 1; |
187 } |
170 } |
188 |
171 |
189 let mut x = xl; |
172 let x = xl; |
190 |
173 |
191 while xl <= xr |
174 while xl <= xr && (row[xl] != border_value && row[xl] != fill_value) |
192 && (self.pixels[y][xl] != border_value && self.pixels[y][xl] != fill_value) |
|
193 { |
175 { |
194 self.pixels[y][xl] = fill_value; |
176 row[xl] = fill_value; |
195 |
|
196 xl += 1; |
177 xl += 1; |
197 } |
178 } |
198 |
179 |
199 if x < xl { |
180 if x < xl { |
200 push(self, &mut stack, x, xl - 1, y, dir); |
181 push(mask, &mut stack, x, xl - 1, y, dir); |
201 push(self, &mut stack, x, xl - 1, y, -dir); |
182 push(mask, &mut stack, x, xl - 1, y, -dir); |
202 } |
183 } |
203 } |
184 } |
204 } |
185 } |
205 } |
186 } |
206 |
187 |