111 } |
111 } |
112 } |
112 } |
113 |
113 |
114 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
114 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
115 pub struct Size { |
115 pub struct Size { |
116 pub width: usize, |
116 pub width: u32, |
117 pub height: usize, |
117 pub height: u32, |
118 } |
118 } |
119 |
119 |
120 impl Size { |
120 impl Size { |
121 pub const EMPTY: Self = Self::square(0); |
121 pub const EMPTY: Self = Self::square(0); |
122 |
122 |
123 #[inline] |
123 #[inline] |
124 pub const fn new(width: usize, height: usize) -> Self { |
124 pub const fn new(width: u32, height: u32) -> Self { |
125 Self { width, height } |
125 Self { width, height } |
126 } |
126 } |
127 |
127 |
128 #[inline] |
128 #[inline] |
129 pub const fn square(size: usize) -> Self { |
129 pub const fn square(size: u32) -> Self { |
130 Self { |
130 Self { |
131 width: size, |
131 width: size, |
132 height: size, |
132 height: size, |
133 } |
133 } |
134 } |
134 } |
135 |
135 |
136 #[inline] |
136 #[inline] |
137 pub const fn area(&self) -> usize { |
137 pub const fn area(&self) -> u32 { |
138 self.width * self.height |
138 self.width * self.height |
139 } |
139 } |
140 |
140 |
141 #[inline] |
141 #[inline] |
142 pub const fn linear_index(&self, x: usize, y: usize) -> usize { |
142 pub const fn linear_index(&self, x: u32, y: u32) -> u32 { |
143 y * self.width + x |
143 y * self.width + x |
144 } |
144 } |
145 |
145 |
146 #[inline] |
146 #[inline] |
147 pub const fn is_power_of_two(&self) -> bool { |
147 pub const fn is_power_of_two(&self) -> bool { |
192 size: Size, |
192 size: Size, |
193 } |
193 } |
194 |
194 |
195 impl PotSize { |
195 impl PotSize { |
196 #[inline] |
196 #[inline] |
197 const fn new_impl(width: usize, height: usize) -> Self { |
197 const fn new_impl(width: u32, height: u32) -> Self { |
198 debug_assert!(width.is_power_of_two() && height.is_power_of_two()); |
198 debug_assert!(width.is_power_of_two() && height.is_power_of_two()); |
199 Self { |
199 Self { |
200 size: Size::new(width, height), |
200 size: Size::new(width, height), |
201 } |
201 } |
202 } |
202 } |
203 |
203 |
204 #[inline] |
204 #[inline] |
205 pub const fn new(width: usize, height: usize) -> Option<Self> { |
205 pub const fn new(width: u32, height: u32) -> Option<Self> { |
206 if width.is_power_of_two() && height.is_power_of_two() { |
206 if width.is_power_of_two() && height.is_power_of_two() { |
207 Some(Self::new_impl(width, height)) |
207 Some(Self::new_impl(width, height)) |
208 } else { |
208 } else { |
209 None |
209 None |
210 } |
210 } |
212 |
212 |
213 pub const fn size(&self) -> Size { |
213 pub const fn size(&self) -> Size { |
214 self.size |
214 self.size |
215 } |
215 } |
216 |
216 |
217 pub const fn width(&self) -> usize { |
217 pub const fn width(&self) -> u32 { |
218 self.size.width |
218 self.size.width |
219 } |
219 } |
220 |
220 |
221 pub const fn height(&self) -> usize { |
221 pub const fn height(&self) -> u32 { |
222 self.size.height |
222 self.size.height |
223 } |
223 } |
224 |
224 |
225 #[inline] |
225 #[inline] |
226 pub const fn square(size: usize) -> Option<Self> { |
226 pub const fn square(size: u32) -> Option<Self> { |
227 if size.is_power_of_two() { |
227 if size.is_power_of_two() { |
228 Some(Self::new_impl(size, size)) |
228 Some(Self::new_impl(size, size)) |
229 } else { |
229 } else { |
230 None |
230 None |
231 } |
231 } |
232 } |
232 } |
233 |
233 |
234 #[inline] |
234 #[inline] |
235 pub const fn area(&self) -> usize { |
235 pub const fn area(&self) -> u32 { |
236 self.size.area() |
236 self.size.area() |
237 } |
237 } |
238 |
238 |
239 #[inline] |
239 #[inline] |
240 pub const fn linear_index(&self, x: usize, y: usize) -> usize { |
240 pub const fn linear_index(&self, x: u32, y: u32) -> u32 { |
241 self.size.linear_index(x, y) |
241 self.size.linear_index(x, y) |
242 } |
242 } |
243 |
243 |
244 #[inline] |
244 #[inline] |
245 pub const fn transpose(&self) -> Self { |
245 pub const fn transpose(&self) -> Self { |
287 size: Size::new(!(size.width() - 1), !(size.height() - 1)), |
287 size: Size::new(!(size.width() - 1), !(size.height() - 1)), |
288 } |
288 } |
289 } |
289 } |
290 |
290 |
291 #[inline] |
291 #[inline] |
292 pub fn contains_x<T: Into<usize>>(&self, x: T) -> bool { |
292 pub fn contains_x<T: Into<u32>>(&self, x: T) -> bool { |
293 (self.size.width & x.into()) == 0 |
293 (self.size.width & x.into()) == 0 |
294 } |
294 } |
295 |
295 |
296 #[inline] |
296 #[inline] |
297 pub fn contains_y<T: Into<usize>>(&self, y: T) -> bool { |
297 pub fn contains_y<T: Into<u32>>(&self, y: T) -> bool { |
298 (self.size.height & y.into()) == 0 |
298 (self.size.height & y.into()) == 0 |
299 } |
299 } |
300 |
300 |
301 #[inline] |
301 #[inline] |
302 pub fn contains(&self, point: Point) -> bool { |
302 pub fn contains(&self, point: Point) -> bool { |
303 self.contains_x(point.x as usize) && self.contains_y(point.y as usize) |
303 self.contains_x(point.x as u32) && self.contains_y(point.y as u32) |
304 } |
304 } |
305 |
305 |
306 #[inline] |
306 #[inline] |
307 pub const fn to_size(&self) -> PotSize { |
307 pub const fn to_size(&self) -> PotSize { |
308 PotSize::new_impl(!self.size.width + 1, !self.size.height + 1) |
308 PotSize::new_impl(!self.size.width + 1, !self.size.height + 1) |
437 top_left, |
437 top_left, |
438 top_left + Point::new(size.width as i32 - 1, size.height as i32 - 1), |
438 top_left + Point::new(size.width as i32 - 1, size.height as i32 - 1), |
439 ) |
439 ) |
440 } |
440 } |
441 |
441 |
442 pub fn from_size_coords(x: i32, y: i32, width: usize, height: usize) -> Self { |
442 pub fn from_size_coords(x: i32, y: i32, width: u32, height: u32) -> Self { |
443 Self::from_size(Point::new(x, y), Size::new(width, height)) |
443 Self::from_size(Point::new(x, y), Size::new(width, height)) |
444 } |
444 } |
445 |
445 |
446 pub fn at_origin(size: Size) -> Self { |
446 pub fn at_origin(size: Size) -> Self { |
447 Self::from_size(Point::ZERO, size) |
447 Self::from_size(Point::ZERO, size) |
448 } |
448 } |
449 |
449 |
450 #[inline] |
450 #[inline] |
451 pub const fn width(&self) -> usize { |
451 pub const fn width(&self) -> u32 { |
452 (self.right() - self.left() + 1) as usize |
452 (self.right() - self.left() + 1) as u32 |
453 } |
453 } |
454 |
454 |
455 #[inline] |
455 #[inline] |
456 pub const fn height(&self) -> usize { |
456 pub const fn height(&self) -> u32 { |
457 (self.bottom() - self.top() + 1) as usize |
457 (self.bottom() - self.top() + 1) as u32 |
458 } |
458 } |
459 |
459 |
460 #[inline] |
460 #[inline] |
461 pub const fn size(&self) -> Size { |
461 pub const fn size(&self) -> Size { |
462 Size::new(self.width(), self.height()) |
462 Size::new(self.width(), self.height()) |
463 } |
463 } |
464 |
464 |
465 #[inline] |
465 #[inline] |
466 pub const fn area(&self) -> usize { |
466 pub const fn area(&self) -> u32 { |
467 self.size().area() |
467 self.size().area() |
468 } |
468 } |
469 |
469 |
470 #[inline] |
470 #[inline] |
471 pub const fn left(&self) -> i32 { |
471 pub const fn left(&self) -> i32 { |
502 (self.top_left() + self.bottom_right()) / 2 |
502 (self.top_left() + self.bottom_right()) / 2 |
503 } |
503 } |
504 |
504 |
505 #[inline] |
505 #[inline] |
506 pub fn with_margin(&self, margin: i32) -> Self { |
506 pub fn with_margin(&self, margin: i32) -> Self { |
507 let offset = Point::new(min(margin, self.width() as i32 / 2), min(margin, self.height() as i32 / 2)); |
507 let offset = Point::new( |
|
508 min(margin, self.width() as i32 / 2), |
|
509 min(margin, self.height() as i32 / 2), |
|
510 ); |
508 Self::new(self.top_left() + offset, self.bottom_right() - offset) |
511 Self::new(self.top_left() + offset, self.bottom_right() - offset) |
509 } |
512 } |
510 |
513 |
511 #[inline] |
514 #[inline] |
512 pub const fn x_range(&self) -> RangeInclusive<i32> { |
515 pub const fn x_range(&self) -> RangeInclusive<i32> { |
564 self.bottom() + bottom, |
567 self.bottom() + bottom, |
565 ) |
568 ) |
566 } |
569 } |
567 |
570 |
568 #[inline] |
571 #[inline] |
569 pub fn quotient(self, x: usize, y: usize) -> Point { |
572 pub fn quotient(self, x: u32, y: u32) -> Point { |
570 self.top_left() + Point::new((x % self.width()) as i32, (y % self.height()) as i32) |
573 self.top_left() + Point::new((x % self.width()) as i32, (y % self.height()) as i32) |
571 } |
574 } |
572 } |
575 } |
573 |
576 |
574 trait RangeClamp<T> { |
577 trait RangeClamp<T> { |