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(&mut self, buf: &O) -> Option> where O: 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(&mut self, buf: &O, resize_fn: F) -> Rect where O: Buffer2d::Buffer as Buffer2d>::Pixel>, F: Fn((usize, usize)) -> (usize, usize); } impl GrowingPacker for P where A: ResizeableBuffer2d, P: Packer { fn pack_resize(&mut self, buf: &O, resize_fn: F) -> Rect where O: Buffer2d::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) } } } }