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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// external
use svgdom;
// self
use tree;
use tree::NodeExt;
use super::prelude::*;
use super::{
path,
text,
shapes,
IriResolveResult,
};
pub fn convert(
node: &svgdom::Node,
tree: &mut tree::Tree,
) -> tree::Node {
let attrs = node.attributes();
let mut clip_path = None;
if let Some(&AValue::FuncLink(ref link)) = attrs.get_type(AId::ClipPath) {
if link.is_tag_name(EId::ClipPath) {
clip_path = Some(link.id().to_string());
}
}
tree.append_to_defs(
tree::NodeKind::ClipPath(tree::ClipPath {
id: node.id().clone(),
units: super::convert_element_units(&attrs, AId::ClipPathUnits),
transform: attrs.get_transform(AId::Transform).unwrap_or_default(),
clip_path,
})
)
}
pub fn convert_children(
parent_svg: &svgdom::Node,
parent: &mut tree::Node,
opt: &Options,
tree: &mut tree::Tree,
) {
for (id, node) in parent_svg.children().svg() {
match id {
EId::Rect
| EId::Polyline
| EId::Polygon
| EId::Circle
| EId::Ellipse => {
if let Some(d) = shapes::convert(&node) {
path::convert(&node, d, opt, parent.clone(), tree);
}
}
EId::Path => {
let attrs = node.attributes();
if let Some(d) = attrs.get_path(AId::D) {
path::convert(&node, d.clone(), opt, parent.clone(), tree);
}
}
EId::Text => {
text::convert(&node, opt, parent.clone(), tree);
}
EId::Line => {
// `line` doesn't impact rendering because stroke is always disabled
// for `clipPath` children. So we can ignore it completely.
}
EId::G => {
// By the SVG spec, `clipPath` cannot contain a `g` element,
// but since in `usvg` `clip-path` attribute can be set only for groups
// we have to create one 'temporarily'.
// It will be available in the tree, but will be ignored
// during `Tree::to_svgdom` conversion.
let attrs = node.attributes();
let ts = attrs.get_transform(AId::Transform).unwrap_or_default();
let opacity = attrs.get_number(AId::Opacity).map(|v| v.into());
let clip_path = match super::resolve_iri(&node, EId::ClipPath, AId::ClipPath, tree) {
IriResolveResult::Id(id) => Some(id),
IriResolveResult::Skip => continue,
IriResolveResult::None => None,
};
let mask = match super::resolve_iri(&node, EId::Mask, AId::Mask, tree) {
IriResolveResult::Id(id) => Some(id),
IriResolveResult::Skip => continue,
IriResolveResult::None => None,
};
let filter = match super::resolve_iri(&node, EId::Filter, AId::Filter, tree) {
IriResolveResult::Id(id) => Some(id),
IriResolveResult::Skip => continue,
IriResolveResult::None => None,
};
if clip_path.is_none() && mask.is_none() && filter.is_none() {
continue;
}
let mut g_node = parent.append_kind(tree::NodeKind::Group(tree::Group {
id: node.id().clone(),
transform: ts,
opacity,
clip_path,
mask,
filter,
}));
convert_children(&node, &mut g_node, opt, tree);
}
_ => {
warn!("Skipping the '{}' clipPath invalid child element '{}'.",
node.id(), id);
continue;
}
}
}
}
|