use std::rc::Rc;
use crate::svgtree::{self, AId, EId};
use crate::{converter, Group, Node, NodeKind, Transform, Units};
#[derive(Clone, Debug)]
pub struct ClipPath {
pub id: String,
pub units: Units,
pub transform: Transform,
pub clip_path: Option<Rc<Self>>,
pub root: Node,
}
impl Default for ClipPath {
fn default() -> Self {
ClipPath {
id: String::new(),
units: Units::UserSpaceOnUse,
transform: Transform::default(),
clip_path: None,
root: Node::new(NodeKind::Group(Group::default())),
}
}
}
pub(crate) fn convert(
node: svgtree::Node,
state: &converter::State,
cache: &mut converter::Cache,
) -> Option<Rc<ClipPath>> {
if !node.has_tag_name(EId::ClipPath) {
return None;
}
if !node.has_valid_transform(AId::Transform) {
return None;
}
if let Some(clip) = cache.clip_paths.get(node.element_id()) {
return Some(clip.clone());
}
let mut clip_path = None;
if let Some(link) = node.attribute::<svgtree::Node>(AId::ClipPath) {
clip_path = convert(link, state, cache);
if clip_path.is_none() {
return None;
}
}
let units = node
.attribute(AId::ClipPathUnits)
.unwrap_or(Units::UserSpaceOnUse);
let mut clip = ClipPath {
id: node.element_id().to_string(),
units,
transform: node.attribute(AId::Transform).unwrap_or_default(),
clip_path,
root: Node::new(NodeKind::Group(Group::default())),
};
let mut clip_state = state.clone();
clip_state.parent_clip_path = Some(node);
converter::convert_clip_path_elements(node, &clip_state, cache, &mut clip.root);
converter::ungroup_groups(clip.root.clone(), false);
if clip.root.has_children() {
let clip = Rc::new(clip);
cache
.clip_paths
.insert(node.element_id().to_string(), clip.clone());
Some(clip)
} else {
None
}
}