iced_wgpu/image/atlas/
allocator.rs1use crate::core;
2
3use guillotiere::{AtlasAllocator, Size};
4
5pub struct Allocator {
6 raw: AtlasAllocator,
7 allocations: usize,
8}
9
10impl Allocator {
11 const PADDING: u32 = 1;
12
13 pub fn new(size: u32) -> Allocator {
14 let raw = AtlasAllocator::new(Size::new(size as i32, size as i32));
15
16 Allocator {
17 raw,
18 allocations: 0,
19 }
20 }
21
22 pub fn allocate(&mut self, width: u32, height: u32) -> Option<Region> {
23 let size = self.raw.size();
24
25 let padded_width = width + Self::PADDING * 2;
26 let padded_height = height + Self::PADDING * 2;
27
28 let pad_width = padded_width as i32 <= size.width;
29 let pad_height = padded_height as i32 <= size.height;
30
31 let mut allocation = self.raw.allocate(Size::new(
32 if pad_width { padded_width } else { width } as i32,
33 if pad_height { padded_height } else { height } as i32,
34 ))?;
35
36 if pad_width {
37 allocation.rectangle.min.x += Self::PADDING as i32;
38 allocation.rectangle.max.x -= Self::PADDING as i32;
39 }
40
41 if pad_height {
42 allocation.rectangle.min.y += Self::PADDING as i32;
43 allocation.rectangle.max.y -= Self::PADDING as i32;
44 }
45
46 self.allocations += 1;
47
48 Some(Region {
49 allocation,
50 padding: core::Size::new(
51 if pad_width { Self::PADDING } else { 0 },
52 if pad_height { Self::PADDING } else { 0 },
53 ),
54 })
55 }
56
57 pub fn deallocate(&mut self, region: &Region) {
58 self.raw.deallocate(region.allocation.id);
59
60 self.allocations = self.allocations.saturating_sub(1);
61 }
62
63 pub fn is_empty(&self) -> bool {
64 self.allocations == 0
65 }
66
67 pub fn allocations(&self) -> usize {
68 self.allocations
69 }
70}
71
72pub struct Region {
73 allocation: guillotiere::Allocation,
74 padding: core::Size<u32>,
75}
76
77impl Region {
78 pub fn position(&self) -> (u32, u32) {
79 let rectangle = &self.allocation.rectangle;
80
81 (rectangle.min.x as u32, rectangle.min.y as u32)
82 }
83
84 pub fn size(&self) -> core::Size<u32> {
85 let size = self.allocation.rectangle.size();
86
87 core::Size::new(size.width as u32, size.height as u32)
88 }
89
90 pub fn padding(&self) -> crate::core::Size<u32> {
91 self.padding
92 }
93}
94
95impl std::fmt::Debug for Allocator {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 write!(f, "Allocator")
98 }
99}
100
101impl std::fmt::Debug for Region {
102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 f.debug_struct("Region")
104 .field("id", &self.allocation.id)
105 .field("rectangle", &self.allocation.rectangle)
106 .finish()
107 }
108}