aseprite_loader/binary/chunks/
slice.rs1use bitflags::bitflags;
2use nom::{combinator::cond, multi::count};
3
4use crate::binary::{
5 errors::ParseResult,
6 scalars::{dword, long, parse_dword_as_usize, parse_string, Dword, Long},
7};
8
9#[derive(Debug)]
10pub struct SliceChunk<'a> {
11 pub name: &'a str,
12 pub flags: SliceFlags,
13 pub slice_keys: Vec<SliceKey>,
14}
15
16bitflags! {
17 #[derive(Debug, Copy, Clone)]
18 pub struct SliceFlags: Dword {
19 const NINE_PATCH = 0x01;
20 const PIVOT = 0x02;
21 }
22}
23
24#[derive(Debug, Copy, Clone)]
25pub struct SliceKey {
26 pub frame_number: Dword,
27 pub x: Long,
28 pub y: Long,
29 pub width: Dword,
30 pub height: Dword,
31 pub nine_patch: Option<NinePatch>,
32 pub pivot: Option<Pivot>,
33}
34
35#[derive(Debug, Copy, Clone)]
36pub struct NinePatch {
37 pub x: Long,
38 pub y: Long,
39 pub width: Dword,
40 pub height: Dword,
41}
42
43#[derive(Debug, Copy, Clone)]
44pub struct Pivot {
45 pub x: Long,
46 pub y: Long,
47}
48
49pub fn parse_slice_chunk(input: &[u8]) -> ParseResult<'_, SliceChunk<'_>> {
50 let (input, number_of_keys) = parse_dword_as_usize(input)?;
51 let (input, flags) = dword(input)?;
52 let flags = SliceFlags::from_bits_truncate(flags);
53 let (input, _) = dword(input)?;
54 let (input, name) = parse_string(input)?;
55 let (input, slice_keys) = count(|input| parse_slice_key(input, flags), number_of_keys)(input)?;
56 Ok((
57 input,
58 SliceChunk {
59 name,
60 flags,
61 slice_keys,
62 },
63 ))
64}
65
66pub fn parse_slice_key(input: &[u8], flags: SliceFlags) -> ParseResult<'_, SliceKey> {
67 let (input, frame_number) = dword(input)?;
68 let (input, x) = long(input)?;
69 let (input, y) = long(input)?;
70 let (input, width) = dword(input)?;
71 let (input, height) = dword(input)?;
72 let (input, nine_patch) =
73 cond(flags.contains(SliceFlags::NINE_PATCH), parse_nine_patch)(input)?;
74 let (input, pivot) = cond(flags.contains(SliceFlags::PIVOT), parse_pivot)(input)?;
75 Ok((
76 input,
77 SliceKey {
78 frame_number,
79 x,
80 y,
81 width,
82 height,
83 nine_patch,
84 pivot,
85 },
86 ))
87}
88
89pub fn parse_nine_patch(input: &[u8]) -> ParseResult<'_, NinePatch> {
90 let (input, x) = long(input)?;
91 let (input, y) = long(input)?;
92 let (input, width) = dword(input)?;
93 let (input, height) = dword(input)?;
94 Ok((
95 input,
96 NinePatch {
97 x,
98 y,
99 width,
100 height,
101 },
102 ))
103}
104
105pub fn parse_pivot(input: &[u8]) -> ParseResult<'_, Pivot> {
106 let (input, x) = long(input)?;
107 let (input, y) = long(input)?;
108 Ok((input, Pivot { x, y }))
109}