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
91
92
93
94
95
96
97
98
99
100
use svgtypes::{Length, LengthUnit as Unit};
use crate::{NodeKind, OptionLog, Rect, Tree, Units, converter};
use crate::svgtree::{self, AId, EId};
#[derive(Clone, Debug)]
pub struct Mask {
pub id: String,
pub units: Units,
pub content_units: Units,
pub rect: Rect,
pub mask: Option<String>,
}
pub(crate) fn convert(
node: svgtree::Node,
state: &converter::State,
id_generator: &mut converter::NodeIdGenerator,
tree: &mut Tree,
) -> Option<String> {
if !node.has_tag_name(EId::Mask) {
return None;
}
if let Some(id) = node.attribute(AId::Id) {
if tree.defs_by_id(id).is_some() {
return Some(id.to_string());
}
}
let units = node.attribute(AId::MaskUnits).unwrap_or(Units::ObjectBoundingBox);
let content_units = node.attribute(AId::MaskContentUnits).unwrap_or(Units::UserSpaceOnUse);
let rect = Rect::new(
node.convert_length(AId::X, units, state, Length::new(-10.0, Unit::Percent)),
node.convert_length(AId::Y, units, state, Length::new(-10.0, Unit::Percent)),
node.convert_length(AId::Width, units, state, Length::new(120.0, Unit::Percent)),
node.convert_length(AId::Height, units, state, Length::new(120.0, Unit::Percent)),
);
let rect = rect.log_none(|| log::warn!("Mask '{}' has an invalid size. Skipped.", node.element_id()))?;
let mut mask = None;
if let Some(link) = node.attribute::<svgtree::Node>(AId::Mask) {
mask = convert(link, state, id_generator, tree);
if mask.is_none() {
return None;
}
}
let mut mask = tree.append_to_defs(NodeKind::Mask(Mask {
id: node.element_id().to_string(),
units,
content_units,
rect,
mask,
}));
converter::convert_children(node, state, id_generator, &mut mask, tree);
if mask.has_children() {
Some(node.element_id().to_string())
} else {
mask.detach();
None
}
}