Skip to content

Commit

Permalink
Impl atlas tool
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jul 19, 2023
1 parent 36d12b2 commit 943c0a4
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 19 deletions.
47 changes: 34 additions & 13 deletions atlas/src/atlas.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use {
crate::pack::{self, Pack, Rect},
png::{Error as ImageError, Format, Image},
std::fmt,
std::{collections::BTreeMap, fmt},
};

pub struct ImageData {
pub name: Box<str>,
pub data: Vec<u8>,
}

/// Make an atlas from images.
///
/// # Errors
Expand All @@ -22,20 +27,16 @@ where

let mut sprites = sprites?;
sprites.sort_unstable_by(|a, b| a.name.cmp(&b.name));
Ok(Atlas::pack(sprites))
}

pub struct ImageData {
pub name: Box<str>,
pub data: Vec<u8>,
Atlas::pack(sprites)
}

pub struct Atlas {
map: Image,
pub png: Vec<u8>,
pub map: BTreeMap<Box<str>, Rect>,
}

impl Atlas {
fn pack(sprites: Vec<Sprite>) -> Self {
fn pack(sprites: Vec<Sprite>) -> Result<Self, Error> {
use std::iter;

let entries: Vec<_> = sprites
Expand All @@ -59,11 +60,18 @@ impl Atlas {

let Pack { rects, side } = pack::pack(&entries);
let mut map = Image::empty((side, side), format);
for (sprite, Rect { point, .. }) in iter::zip(sprites, rects) {
map.copy_from(&sprite.image, point);
for (Sprite { image, .. }, rect) in iter::zip(&sprites, &rects) {
map.copy_from(image, rect.point());
}

Self { map }
Ok(Self {
png: png::encode_png(&map)?,
map: sprites
.into_iter()
.map(|Sprite { name, .. }| name)
.zip(rects)
.collect(),
})
}
}

Expand All @@ -77,9 +85,22 @@ pub struct Error {
name: Box<str>,
}

impl From<ImageError> for Error {
fn from(err: ImageError) -> Self {
Self {
err,
name: Box::default(),
}
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Self { err, name } = self;
write!(f, "with an image {name:?}: {err}")
if name.is_empty() {
write!(f, "{err}")
} else {
write!(f, "with an image {name:?}: {err}")
}
}
}
33 changes: 27 additions & 6 deletions atlas/src/pack.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
use serde::Serialize;

type Size = (u32, u32);
type Position = (u32, u32);
type Point = (u32, u32);

#[derive(Clone, Copy, Serialize)]
#[serde(into = "[u32; 4]")]
pub struct Rect {
size: Size,
point: Point,
}

impl Rect {
pub(crate) fn point(self) -> Point {
self.point
}
}

impl From<Rect> for [u32; 4] {
fn from(
Rect {
size: (w, h),
point: (x, y),
}: Rect,
) -> Self {
[x, y, w, h]
}
}

pub(crate) struct Pack {
pub rects: Vec<Rect>,
pub side: u32,
}

pub(crate) struct Rect {
pub size: Size,
pub point: Position,
}

pub(crate) fn pack(entries: &[Size]) -> Pack {
let mut side = initial_side(entries);
loop {
Expand Down

0 comments on commit 943c0a4

Please sign in to comment.