use crate::{
texture::{Pixel, Texture},
texture_packer::{PackResult, TexturePacker},
texture_packer_config::TexturePackerConfig,
};
use std::hash::Hash;
pub struct MultiTexturePacker<'a, T: 'a + Clone, K: Clone + Eq + Hash> {
config: TexturePackerConfig,
pages: Vec<TexturePacker<'a, T, K>>,
}
impl<'a, Pix: Pixel, T: Clone + Texture<Pixel = Pix>, K: Clone + Eq + Hash>
MultiTexturePacker<'a, T, K>
{
pub fn get_pages(&self) -> &[TexturePacker<'a, T, K>] {
&self.pages
}
}
impl<'a, Pix: Pixel, T: 'a + Clone + Texture<Pixel = Pix>, K: Clone + Eq + Hash>
MultiTexturePacker<'a, T, K>
{
pub fn new_skyline(config: TexturePackerConfig) -> Self {
Self {
config,
pages: vec![],
}
}
}
impl<'a, Pix: Pixel, T: 'a + Clone + Texture<Pixel = Pix>, K: Clone + Eq + Hash>
MultiTexturePacker<'a, T, K>
{
pub fn pack_ref(&mut self, key: K, texture: &'a T) -> PackResult<()> {
for packer in &mut self.pages {
if packer.can_pack(texture) {
return packer.pack_ref(key, texture);
}
}
let mut packer = TexturePacker::new_skyline(self.config);
packer.pack_ref(key, texture)?;
self.pages.push(packer);
Ok(())
}
pub fn pack_own(&mut self, key: K, texture: T) -> PackResult<()> {
for packer in &mut self.pages {
if packer.can_pack(&texture) {
return packer.pack_own(key, texture);
}
}
let mut packer = TexturePacker::new_skyline(self.config);
packer.pack_own(key, texture)?;
self.pages.push(packer);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{texture::memory_rgba8_texture as mrt, texture_packer::PackError};
#[test]
fn texture_too_small() {
let config = TexturePackerConfig {
max_width: 1,
max_height: 1,
allow_rotation: false,
border_padding: 0,
texture_padding: 0,
texture_extrusion: 0,
trim: false,
texture_outlines: false,
};
let mut mtp = MultiTexturePacker::new_skyline(config);
let texture = mrt::MemoryRGBA8Texture::from_memory(&[0, 0, 0, 0, 0, 0, 0, 0], 2, 1);
assert_eq!(
Err(PackError::TextureTooLargeToFitIntoAtlas),
mtp.pack_own(String::from(""), texture)
);
}
}