1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use std::io::{self, Read, Seek, SeekFrom};
use bitflags::bitflags;
use byteorder::{LittleEndian, ReadBytesExt};
use num_enum::CustomTryInto;
use crate::helpers::read_string;
bitflags! {
pub struct Flags: u16 {
const Visible = 1;
const Editable = 2;
const LockMovement = 4;
const Backgrount = 8;
const PreferLinkedCels = 16;
const DisplayCollapsed = 32;
const ReferenceLayer = 64;
}
}
#[derive(Eq, PartialEq, CustomTryInto)]
#[repr(u16)]
pub enum LayerType {
Normal = 0,
Group = 1,
}
#[derive(Eq, PartialEq, CustomTryInto)]
#[repr(u16)]
pub enum BlendMode {
Normal = 0,
Multiply = 1,
Screen = 2,
Overlay = 3,
Darken = 4,
Lighten = 5,
ColorDodge = 6,
ColorBurn = 7,
HardLight = 8,
SoftLight = 9,
Difference = 10,
Exclusion = 11,
Hue = 12,
Saturation = 13,
Color = 14,
Luminosity = 15,
Addition = 16,
Subtract = 17,
Divide = 18,
}
pub struct LayerChunk {
pub flags: Flags,
pub layer_type: LayerType,
pub layer_child_level: u16,
pub blend_mode: BlendMode,
pub opacity: u8,
pub layer_name: String,
}
impl LayerChunk {
pub fn from_read<R>(read: &mut R) -> io::Result<Self>
where
R: Read + Seek,
{
let flags = Flags::from_bits_truncate(read.read_u16::<LittleEndian>()?);
let layer_type = read
.read_u16::<LittleEndian>()?
.try_into_LayerType()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let layer_child_level = read.read_u16::<LittleEndian>()?;
read.seek(SeekFrom::Current(2 + 2))?;
let blend_mode = read
.read_u16::<LittleEndian>()?
.try_into_BlendMode()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let opacity = read.read_u8()?;
read.seek(SeekFrom::Current(3))?;
let layer_name = read_string(read)?;
Ok(Self {
flags,
layer_type,
layer_child_level,
blend_mode,
opacity,
layer_name,
})
}
}