1use core::{
2 marker::PhantomData,
3 ops::{Deref, DerefMut, Index, IndexMut},
4};
5
6pub type Point = mint::Point2<u32>;
8pub type Size = mint::Vector2<u32>;
10
11#[inline]
13pub const fn point(x: u32, y: u32) -> Point {
14 Point { x, y }
15}
16
17#[inline]
19pub const fn size(x: u32, y: u32) -> Size {
20 Size { x, y }
21}
22
23pub trait Surface<T> {
25 fn surface_size(&self) -> Size;
27
28 fn surface_get(&self, pt: Point) -> Option<&T>;
30
31 #[inline]
33 fn sub_surface(&self, offset: Point, size: Size) -> SubSurface<&Self, T>
34 where
35 Self: Sized,
36 {
37 SubSurface::new(self, offset, size)
38 }
39
40 #[inline]
42 fn offset_surface(&self, offset: Point) -> SubSurface<&Self, T>
43 where
44 Self: Sized,
45 {
46 let sur_size = self.surface_size();
47 SubSurface::new(
48 self,
49 offset,
50 size(sur_size.x - offset.x, sur_size.y - offset.y),
51 )
52 }
53
54 #[inline]
56 fn sub_surface_mut(&mut self, offset: Point, size: Size) -> SubSurface<&mut Self, T>
57 where
58 Self: Sized,
59 {
60 SubSurface::new(self, offset, size)
61 }
62
63 #[inline]
65 fn offset_surface_mut(&mut self, offset: Point) -> SubSurface<&mut Self, T>
66 where
67 Self: Sized,
68 {
69 let sur_size = self.surface_size();
70 SubSurface::new(
71 self,
72 offset,
73 size(sur_size.x - offset.x, sur_size.y - offset.y),
74 )
75 }
76
77 #[inline]
79 fn into_sub_surface(self, offset: Point, size: Size) -> SubSurface<Self, T>
80 where
81 Self: Sized,
82 {
83 SubSurface::new(self, offset, size)
84 }
85
86 #[inline]
88 fn into_offset_surface(self, offset: Point) -> SubSurface<Self, T>
89 where
90 Self: Sized,
91 {
92 let sur_size = self.surface_size();
93 SubSurface::new(
94 self,
95 offset,
96 size(sur_size.x - offset.x, sur_size.y - offset.y),
97 )
98 }
99}
100
101impl<S, T> Surface<T> for &S
102where
103 S: Surface<T>,
104{
105 #[inline]
106 fn surface_size(&self) -> Size {
107 (**self).surface_size()
108 }
109
110 #[inline]
111 fn surface_get(&self, pt: Point) -> Option<&T> {
112 (**self).surface_get(pt)
113 }
114}
115
116impl<S, T> Surface<T> for &mut S
117where
118 S: Surface<T>,
119{
120 #[inline]
121 fn surface_size(&self) -> Size {
122 (**self).surface_size()
123 }
124
125 #[inline]
126 fn surface_get(&self, pt: Point) -> Option<&T> {
127 (**self).surface_get(pt)
128 }
129}
130
131pub trait SurfaceMut<T>: Surface<T> {
133 fn surface_get_mut(&mut self, pt: Point) -> Option<&mut T>;
135}
136
137impl<S, T> SurfaceMut<T> for &mut S
138where
139 S: SurfaceMut<T>,
140{
141 #[inline]
142 fn surface_get_mut(&mut self, pt: Point) -> Option<&mut T> {
143 (*self).surface_get_mut(pt)
144 }
145}
146
147#[derive(Clone, Copy, Debug, PartialEq, Eq)]
149#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
150pub struct GenericSurface<Slice, Item> {
151 slice: Slice,
152 size: Size,
153 ghost: PhantomData<Item>,
154}
155
156impl<Slice, Item> GenericSurface<Slice, Item>
157where
158 Slice: AsRef<[Item]>,
159{
160 #[inline]
164 pub fn new(slice: Slice, size: Size) -> Option<Self> {
165 if slice.as_ref().len() == (size.x * size.y) as _ {
166 Some(Self {
167 slice,
168 size,
169 ghost: PhantomData,
170 })
171 } else {
172 None
173 }
174 }
175
176 #[inline]
180 pub fn new_infer(slice: Slice, width: u32) -> Self {
181 Self {
182 size: size(width, slice.as_ref().len() as u32 / width),
183 slice,
184 ghost: PhantomData,
185 }
186 }
187
188 #[inline]
190 pub fn into_inner(self) -> Slice {
191 self.slice
192 }
193}
194
195impl<Slice, Item> Deref for GenericSurface<Slice, Item>
196where
197 Slice: AsRef<[Item]>,
198{
199 type Target = [Item];
200
201 #[inline]
202 fn deref(&self) -> &Self::Target {
203 self.slice.as_ref()
204 }
205}
206
207impl<Slice, Item> DerefMut for GenericSurface<Slice, Item>
208where
209 Slice: AsRef<[Item]> + AsMut<[Item]>,
210{
211 #[inline]
212 fn deref_mut(&mut self) -> &mut Self::Target {
213 self.slice.as_mut()
214 }
215}
216
217impl<Slice, Item> Surface<Item> for GenericSurface<Slice, Item>
218where
219 Slice: AsRef<[Item]>,
220{
221 #[inline]
222 fn surface_size(&self) -> Size {
223 self.size
224 }
225
226 #[inline]
227 fn surface_get(&self, pt: Point) -> Option<&Item> {
228 if pt.x < self.size.x && pt.y < self.size.y {
229 Some(
230 self.slice
231 .as_ref()
232 .index((pt.y * self.size.x + pt.x) as usize),
233 )
234 } else {
235 None
236 }
237 }
238}
239
240impl<Slice, Item> SurfaceMut<Item> for GenericSurface<Slice, Item>
241where
242 Slice: AsRef<[Item]> + AsMut<[Item]>,
243{
244 #[inline]
245 fn surface_get_mut(&mut self, pt: Point) -> Option<&mut Item> {
246 if pt.x < self.size.x && pt.y < self.size.y {
247 Some(
248 self.slice
249 .as_mut()
250 .index_mut((pt.y * self.size.x + pt.x) as usize),
251 )
252 } else {
253 None
254 }
255 }
256}
257
258#[derive(Clone, Copy, Debug, PartialEq, Eq)]
260#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
261pub struct SingleValueSurface<T> {
262 pub size: Size,
264 pub value: T,
266}
267
268impl<T> SingleValueSurface<T> {
269 #[inline]
271 pub const fn new(value: T, size: Size) -> Self {
272 Self { size, value }
273 }
274
275 #[inline]
277 pub fn value(&self) -> &T {
278 &self.value
279 }
280
281 #[inline]
283 pub fn value_mut(&mut self) -> &mut T {
284 &mut self.value
285 }
286
287 #[inline]
289 pub fn into_inner(self) -> T {
290 self.value
291 }
292}
293
294impl<T> Surface<T> for SingleValueSurface<T> {
295 #[inline]
296 fn surface_size(&self) -> Size {
297 self.size
298 }
299
300 #[inline]
301 fn surface_get(&self, _pt: Point) -> Option<&T> {
302 Some(&self.value)
303 }
304}
305
306impl<T> SurfaceMut<T> for SingleValueSurface<T> {
307 #[inline]
308 fn surface_get_mut(&mut self, _pt: Point) -> Option<&mut T> {
309 Some(&mut self.value)
310 }
311}
312
313#[derive(Clone, Copy, Debug, PartialEq, Eq)]
315#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
316pub struct SubSurface<S, Item> {
317 surface: S,
318 offset: Point,
319 size: Size,
320 ghost: PhantomData<Item>,
321}
322
323impl<S, Item> SubSurface<S, Item> {
324 #[inline]
326 pub fn offset(&self) -> Point {
327 self.offset
328 }
329
330 #[inline]
332 pub fn size(&self) -> Size {
333 self.size
334 }
335
336 #[inline]
338 pub fn inner(&self) -> &S {
339 &self.surface
340 }
341
342 #[inline]
344 pub fn inner_mut(&mut self) -> &mut S {
345 &mut self.surface
346 }
347
348 #[inline]
350 pub fn into_inner(self) -> S {
351 self.surface
352 }
353}
354
355impl<S, Item> SubSurface<S, Item>
356where
357 S: Surface<Item>,
358{
359 #[inline]
361 pub fn new(surface: S, offset: Point, size: Size) -> Self {
362 Self {
363 surface,
364 offset,
365 size,
366 ghost: PhantomData,
367 }
368 }
369}
370
371impl<S, Item> Surface<Item> for SubSurface<S, Item>
372where
373 S: Surface<Item>,
374{
375 #[inline]
376 fn surface_size(&self) -> Size {
377 self.size
378 }
379
380 #[inline]
381 fn surface_get(&self, pt: Point) -> Option<&Item> {
382 if pt.x < self.size.x && pt.y < self.size.y {
383 self.surface
384 .surface_get(point(pt.x + self.offset.x, pt.y + self.offset.y))
385 } else {
386 None
387 }
388 }
389}
390
391impl<S, Item> SurfaceMut<Item> for SubSurface<S, Item>
392where
393 S: SurfaceMut<Item>,
394{
395 #[inline]
396 fn surface_get_mut(&mut self, pt: Point) -> Option<&mut Item> {
397 if pt.x < self.size.x && pt.y < self.size.y {
398 self.surface
399 .surface_get_mut(point(pt.x + self.offset.x, pt.y + self.offset.y))
400 } else {
401 None
402 }
403 }
404}