Skip to main content

tex_packer_core/
export_manifest.rs

1use crate::model::{Atlas, Meta, Rect};
2use serde::Serialize;
3use serde_json::{Value, json};
4
5#[derive(Debug, Clone)]
6pub(crate) struct ExportManifest {
7    pub(crate) pages: Vec<ExportPage>,
8    pub(crate) meta: Meta,
9}
10
11#[derive(Debug, Clone)]
12pub(crate) struct ExportPage {
13    pub(crate) id: usize,
14    pub(crate) width: u32,
15    pub(crate) height: u32,
16    pub(crate) image: String,
17    pub(crate) frames: Vec<ExportFrame>,
18}
19
20#[derive(Debug, Clone)]
21pub(crate) struct ExportFrame {
22    pub(crate) key: String,
23    pub(crate) frame: Rect,
24    pub(crate) rotated: bool,
25    pub(crate) trimmed: bool,
26    pub(crate) sprite_source_size: Rect,
27    pub(crate) source_size: (u32, u32),
28    pub(crate) pivot: (f32, f32),
29    pub(crate) page: usize,
30    pub(crate) page_size: (u32, u32),
31}
32
33impl ExportManifest {
34    pub(crate) fn from_atlas<K: ToString + Clone>(atlas: &Atlas<K>) -> Self {
35        let default_page_names: Vec<String> = atlas
36            .pages
37            .iter()
38            .map(|page| format!("page_{}.png", page.id))
39            .collect();
40        Self::from_atlas_with_page_names(atlas, &default_page_names)
41    }
42
43    pub(crate) fn from_atlas_with_page_names<K: ToString + Clone>(
44        atlas: &Atlas<K>,
45        page_names: &[String],
46    ) -> Self {
47        let pages = atlas
48            .pages
49            .iter()
50            .enumerate()
51            .map(|(idx, page)| {
52                let image = page_names
53                    .get(idx)
54                    .cloned()
55                    .unwrap_or_else(|| format!("page_{}.png", page.id));
56                let frames = page
57                    .frames
58                    .iter()
59                    .map(|frame| ExportFrame {
60                        key: frame.key.to_string(),
61                        frame: frame.frame,
62                        rotated: frame.rotated,
63                        trimmed: frame.trimmed,
64                        sprite_source_size: frame.source,
65                        source_size: frame.source_size,
66                        pivot: (0.5, 0.5),
67                        page: page.id,
68                        page_size: (page.width, page.height),
69                    })
70                    .collect();
71                ExportPage {
72                    id: page.id,
73                    width: page.width,
74                    height: page.height,
75                    image,
76                    frames,
77                }
78            })
79            .collect();
80
81        Self {
82            pages,
83            meta: atlas.meta.clone(),
84        }
85    }
86}
87
88impl ExportFrame {
89    pub(crate) fn frame_value(&self) -> Value {
90        rect_value(&self.frame)
91    }
92
93    pub(crate) fn sprite_source_size_value(&self) -> Value {
94        rect_value(&self.sprite_source_size)
95    }
96
97    pub(crate) fn source_size_value(&self) -> Value {
98        size_value(self.source_size)
99    }
100
101    pub(crate) fn pivot_value(&self) -> Value {
102        json!({"x": self.pivot.0, "y": self.pivot.1})
103    }
104
105    pub(crate) fn page_size_value(&self) -> Value {
106        size_value(self.page_size)
107    }
108}
109
110pub(crate) fn rect_value(rect: &Rect) -> Value {
111    json!({"x": rect.x, "y": rect.y, "w": rect.w, "h": rect.h})
112}
113
114pub(crate) fn size_value(size: (u32, u32)) -> Value {
115    json!({"w": size.0, "h": size.1})
116}
117
118#[derive(Debug, Clone, Serialize)]
119pub struct TemplateContext {
120    pub pages: Vec<TemplatePage>,
121    pub meta: Value,
122}
123
124#[derive(Debug, Clone, Serialize)]
125pub struct TemplatePage {
126    pub image: String,
127    pub size: Value,
128    pub sprites: Vec<TemplateSprite>,
129}
130
131#[derive(Debug, Clone, Serialize)]
132pub struct TemplateSprite {
133    pub name: String,
134    pub frame: Value,
135    pub rotated: bool,
136    pub trimmed: bool,
137    pub sprite_source_size: Value,
138    pub source_size: Value,
139    pub pivot: Value,
140}
141
142pub fn to_template_context<K: ToString + Clone>(
143    atlas: &Atlas<K>,
144    page_names: &[String],
145) -> TemplateContext {
146    let manifest = ExportManifest::from_atlas_with_page_names(atlas, page_names);
147    let pages = manifest
148        .pages
149        .iter()
150        .map(|page| TemplatePage {
151            image: page.image.clone(),
152            size: size_value((page.width, page.height)),
153            sprites: page
154                .frames
155                .iter()
156                .map(|frame| TemplateSprite {
157                    name: frame.key.clone(),
158                    frame: frame.frame_value(),
159                    rotated: frame.rotated,
160                    trimmed: frame.trimmed,
161                    sprite_source_size: frame.sprite_source_size_value(),
162                    source_size: frame.source_size_value(),
163                    pivot: frame.pivot_value(),
164                })
165                .collect(),
166        })
167        .collect();
168    let meta = json!({
169        "app": manifest.meta.app,
170        "version": manifest.meta.version,
171        "format": manifest.meta.format,
172        "scale": manifest.meta.scale,
173    });
174    TemplateContext { pages, meta }
175}