|
|
- mod skyline;
-
- use ::texture::{Buffer2d, ResizeableBuffer2d};
- use ::geometry::Rect;
-
- pub use self::skyline::SkylinePacker;
-
- pub trait Packer {
- type Buffer: Buffer2d;
-
- fn new(b: Self::Buffer) -> Self;
- fn pack<O>(&mut self, buf: &O) -> Option<Rect<usize>>
- where O: Buffer2d<Pixel=<Self::Buffer as Buffer2d>::Pixel>; // buffer with same pixel type as this atlas
-
- fn set_margin(&mut self, margin: usize);
- fn buf(&self) -> &Self::Buffer;
- fn buf_mut(&mut self) -> &mut Self::Buffer;
- fn into_buf(self) -> Self::Buffer; // TODO: consider actually implementing Into?
-
- fn dimensions(&self) -> (usize, usize);
- fn set_dimensions(&mut self, w: usize, h: usize);
- }
-
- pub trait GrowingPacker: Packer {
- /// `resize_fn` should describe a strategy for growing the atlas buffer based on the current size.
- fn pack_resize<F, O>(&mut self, buf: &O, resize_fn: F) -> Rect<usize>
- where O: Buffer2d<Pixel=<<Self as Packer>::Buffer as Buffer2d>::Pixel>,
- F: Fn((usize, usize)) -> (usize, usize);
- }
-
- impl <A, P> GrowingPacker for P
- where A: ResizeableBuffer2d, P: Packer<Buffer = A>
- {
- fn pack_resize<F, O>(&mut self, buf: &O, resize_fn: F) -> Rect<usize>
- where O: Buffer2d<Pixel=<<Self as Packer>::Buffer as Buffer2d>::Pixel>,
- F: Fn((usize, usize)) -> (usize, usize)
- {
- match self.pack(buf) {
- Some(p) => p,
- None => {
- let (w, h) = self.dimensions();
- let (w_, h_) = resize_fn((w, h));
- if w_ <= w || h_ <= h {
- panic!("Resize functions must make the buffer larger!");
- }
-
- self.buf_mut().resize(w_, h_);
- self.set_dimensions(w_, h_);
-
- // recurse, trying this new size
- self.pack_resize(buf, resize_fn)
- }
- }
- }
- }
|