1#[macro_use]
2extern crate structure;
3
4pub mod types;
5
6use types::*;
7use wasm_bindgen::prelude::*;
8
9fn chunk_for_color(obj: &ObjectColor) -> Vec<u8> {
10 let mut title = obj.name.clone();
11 title.push('\0');
12 let mut chunk = structure!(">H").pack(title.len() as u16).unwrap();
14
15 for character in title.encode_utf16() {
17 let be_bytes = character.to_be_bytes();
18 chunk.push(be_bytes[0]);
19 chunk.push(be_bytes[1]);
20 }
21
22 let color_mode = match obj.data.mode {
23 ColorMode::Rgb => "RGB",
24 ColorMode::Lab => "LAB",
25 ColorMode::Cmyk => "CMYK",
26 ColorMode::Gray => "Gray",
27 };
28
29 let adjusted_color_mode = format!("{:<4}", color_mode);
31 chunk.append(&mut structure!("!4s").pack(adjusted_color_mode.as_bytes()).unwrap());
32
33 for value in &obj.data.values {
35 chunk.append(&mut structure!("!f").pack(*value).unwrap());
36 }
37
38 chunk.append(&mut structure!(">h").pack(obj.object_type as i16).unwrap());
40
41 let mut head_chunk = vec![0, 1];
43 head_chunk.append(&mut structure!(">I").pack(chunk.len() as u32).unwrap());
45 head_chunk.append(&mut chunk);
47
48 return head_chunk;
49}
50
51fn chunk_for_swatch(obj: &ObjectSwatch) -> Vec<u8> {
52 let mut title = obj.name.clone();
53 title.push('\0');
54 let mut chunk_body = structure!(">H").pack(title.len() as u16).unwrap();
56
57 for character in title.encode_utf16() {
59 let be_bytes = character.to_be_bytes();
60 chunk_body.push(be_bytes[0]);
61 chunk_body.push(be_bytes[1]);
62 }
63
64 let mut chunk_head = vec![192, 1];
66 chunk_head.append(&mut structure!(">I").pack(chunk_body.len() as u32).unwrap());
68
69 let mut chunk = Vec::new();
70 chunk.append(&mut chunk_head);
71 chunk.append(&mut chunk_body);
72
73 for color in &obj.swatches {
75 chunk.append(&mut chunk_for_color(&color));
76 }
77
78 chunk.append(&mut vec![192, 2]);
80 chunk.append(&mut vec![0, 0, 0, 0]);
81
82 return chunk;
83}
84
85pub fn create_ase(swatch_objects: &Vec<ObjectSwatch>, color_objects: &Vec<ObjectColor>) -> Vec<u8> {
135 let s = structure!("!4sHHI");
136 let header = "ASEF".as_bytes();
137 let (v_major, v_minor) = (1, 0);
138
139 let mut chunk_count: u32 = 0;
140 let mut chunks = Vec::new();
141 for object in swatch_objects {
142 chunk_count += 2 + object.swatches.len() as u32;
143 chunks.append(&mut chunk_for_swatch(&object));
144 }
145
146 for object in color_objects {
147 chunk_count += 1;
148 chunks.append(&mut chunk_for_color(&object));
149 }
150
151 let mut head_chunk = s.pack(header, v_major, v_minor, chunk_count).unwrap();
152 head_chunk.append(&mut chunks);
153
154 return head_chunk;
155}
156
157#[wasm_bindgen]
159pub fn create_ase_js(swatches: &JsValue, colors: &JsValue) -> Vec<u8> {
160 let swatch_objects: Vec<ObjectSwatch> = swatches.into_serde().unwrap();
161 let color_objects: Vec<ObjectColor> = colors.into_serde().unwrap();
162
163 return create_ase(&swatch_objects, &color_objects);
164}