bitmapfont_creator/
output.rs1use std::path::{Path, PathBuf};
4use serde::{Deserialize, Serialize};
5
6use crate::error::{BitmapFontError, Result};
7use crate::packer::AtlasResult;
8use crate::xml_generator::CharMetrics;
9
10#[derive(Debug, Serialize, Deserialize)]
12pub struct OutputResult {
13 pub success: bool,
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub atlas_path: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub xml_path: Option<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub char_count: Option<usize>,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub atlas_size: Option<AtlasSize>,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub char_map: Option<serde_json::Value>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub error_type: Option<String>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub error_message: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub suggestion: Option<String>,
39}
40
41#[derive(Debug, Serialize, Deserialize)]
43pub struct AtlasSize {
44 pub width: u32,
45 pub height: u32,
46}
47
48impl OutputResult {
49 pub fn success(
51 atlas_path: PathBuf,
52 xml_path: PathBuf,
53 char_count: usize,
54 atlas_width: u32,
55 atlas_height: u32,
56 chars: &[CharMetrics],
57 ) -> Self {
58 let char_map = chars.iter().map(|c| {
59 (c.char.clone(), serde_json::json!({
60 "x": c.x,
61 "y": c.y,
62 "width": c.width,
63 "height": c.height,
64 "xoffset": c.xoffset,
65 "yoffset": c.yoffset,
66 "xadvance": c.xadvance,
67 "padding": c.padding
68 }))
69 }).collect::<serde_json::Map<String, serde_json::Value>>();
70
71 OutputResult {
72 success: true,
73 atlas_path: Some(atlas_path.to_string_lossy().to_string()),
74 xml_path: Some(xml_path.to_string_lossy().to_string()),
75 char_count: Some(char_count),
76 atlas_size: Some(AtlasSize {
77 width: atlas_width,
78 height: atlas_height,
79 }),
80 char_map: Some(serde_json::Value::Object(char_map)),
81 error_type: None,
82 error_message: None,
83 suggestion: None,
84 }
85 }
86
87 pub fn error(error_type: &str, message: &str, suggestion: &str) -> Self {
89 OutputResult {
90 success: false,
91 atlas_path: None,
92 xml_path: None,
93 char_count: None,
94 atlas_size: None,
95 char_map: None,
96 error_type: Some(error_type.to_string()),
97 error_message: Some(message.to_string()),
98 suggestion: Some(suggestion.to_string()),
99 }
100 }
101
102 pub fn to_json(&self) -> Result<String> {
104 serde_json::to_string_pretty(self)
105 .map_err(|e| BitmapFontError::XmlGeneration(format!("Failed to serialize JSON: {}", e)))
106 }
107}
108
109pub fn save_outputs(
111 atlas: &AtlasResult,
112 xml_content: &str,
113 output_dir: &Path,
114 font_name: &str,
115) -> Result<(PathBuf, PathBuf)> {
116 std::fs::create_dir_all(output_dir)?;
118
119 let atlas_path = output_dir.join(format!("{}.png", font_name));
121 atlas.image.save(&atlas_path)
122 .map_err(|e| BitmapFontError::Io(std::io::Error::new(
123 std::io::ErrorKind::Other,
124 format!("Failed to save atlas: {}", e)
125 )))?;
126
127 let xml_path = output_dir.join(format!("{}.xml", font_name));
129 std::fs::write(&xml_path, xml_content)?;
130
131 Ok((atlas_path, xml_path))
132}