glifparser/glif/mfek/
layer.rs1use serde::Serialize;
2use serde::Deserialize;
3use kurbo::Affine;
4use plist;
5
6use super::{MFEKOutline, LayerOperation};
7use crate::color::Color;
8use crate::glif::name_to_filename;
9use crate::image::GlifImage;
10use crate::point::PointData;
11
12macro_rules! DEFAULT_LAYER_FORMAT_STR {() => {"Layer {}"}}
13pub const DEFAULT_LAYER_FORMAT_STR: &str = DEFAULT_LAYER_FORMAT_STR!();
14
15#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
16pub struct Layer<PD: PointData> {
17 pub name: String,
18 pub visible: bool,
19 pub color: Option<Color>,
20 pub outline: MFEKOutline<PD>,
21 pub operation: Option<LayerOperation>,
22 pub images: Vec<(GlifImage, Affine)>,
23}
24
25pub struct CubicLayer<PD: PointData> (Layer<PD>);
26
27impl<PD: PointData> Layer<PD> {
28 pub fn to_glyphs_dir(&self, idx: usize) -> String {
29 if idx == 0 {
30 String::from("glyphs")
31 } else {
32 format!("glyphs.{}", name_to_filename(&self.name, false))
33 }
34 }
35}
36
37pub trait ToLayerInfoPlist {
39 fn to_layerinfo_plist(&self) -> Option<plist::Value>;
43}
44
45pub trait ToLayerContentsPlist {
47 fn to_layercontents_plist(&self) -> plist::Value;
51
52 fn merge_layercontents_plists(&self, other: plist::Value) -> plist::Value;
56}
57
58impl<PD: PointData> ToLayerInfoPlist for Layer<PD> {
59 fn to_layerinfo_plist(&self) -> Option<plist::Value> {
60 let color = if let Some(color) = self.color {
61 color
62 } else {
63 return None
64 };
65
66 let mut layerinfo: plist::Dictionary = plist::Dictionary::new();
67
68 layerinfo.insert(String::from("color"), plist::Value::String(color.to_string()));
69
70 Some(plist::Value::Dictionary(layerinfo))
71 }
72}
73
74impl<PD: PointData> ToLayerContentsPlist for &[Layer<PD>] {
75 fn to_layercontents_plist(&self) -> plist::Value {
76 let mut ret: Vec<plist::Value> = Vec::new();
77
78 for (i, layer) in self.iter().enumerate() {
79 if !layer.visible { continue }
80 let key = if layer.name == format!(DEFAULT_LAYER_FORMAT_STR!(), 0) {
81 String::from("public.default") } else {
83 layer.name.clone()
84 };
85 let value = layer.to_glyphs_dir(i);
86 ret.push(plist::Value::Array(vec![plist::Value::String(key), plist::Value::String(value)]));
87 }
88
89 plist::Value::Array(ret)
90 }
91 fn merge_layercontents_plists(&self, other: plist::Value) -> plist::Value {
92 let our_lc = self.to_layercontents_plist();
93 let inner_ours: Vec<plist::Value> = our_lc.into_array().unwrap(); let mut inner_theirs: Vec<plist::Value> = other.into_array().unwrap();
95 for l in inner_ours.iter() {
96 if !inner_theirs.contains(&l) {
97 inner_theirs.push(l.clone());
98 }
99 }
100 plist::Value::Array(inner_theirs)
101 }
102}