aseprite_loader/binary/chunks/
slice.rs1use bitflags::bitflags;
2use nom::{combinator::cond, multi::count, Parser};
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) =
56 count(|input| parse_slice_key(input, flags), number_of_keys).parse(input)?;
57 Ok((
58 input,
59 SliceChunk {
60 name,
61 flags,
62 slice_keys,
63 },
64 ))
65}
66
67pub fn parse_slice_key(input: &[u8], flags: SliceFlags) -> ParseResult<'_, SliceKey> {
68 let (input, frame_number) = dword(input)?;
69 let (input, x) = long(input)?;
70 let (input, y) = long(input)?;
71 let (input, width) = dword(input)?;
72 let (input, height) = dword(input)?;
73 let (input, nine_patch) =
74 cond(flags.contains(SliceFlags::NINE_PATCH), parse_nine_patch).parse(input)?;
75 let (input, pivot) = cond(flags.contains(SliceFlags::PIVOT), parse_pivot).parse(input)?;
76 Ok((
77 input,
78 SliceKey {
79 frame_number,
80 x,
81 y,
82 width,
83 height,
84 nine_patch,
85 pivot,
86 },
87 ))
88}
89
90pub fn parse_nine_patch(input: &[u8]) -> ParseResult<'_, NinePatch> {
91 let (input, x) = long(input)?;
92 let (input, y) = long(input)?;
93 let (input, width) = dword(input)?;
94 let (input, height) = dword(input)?;
95 Ok((
96 input,
97 NinePatch {
98 x,
99 y,
100 width,
101 height,
102 },
103 ))
104}
105
106pub fn parse_pivot(input: &[u8]) -> ParseResult<'_, Pivot> {
107 let (input, x) = long(input)?;
108 let (input, y) = long(input)?;
109 Ok((input, Pivot { x, y }))
110}