Skip to content

Commit

Permalink
(usvg) Fix clip paths writing with multiple text elements inside.
Browse files Browse the repository at this point in the history
Fix panic and fix bug where xlink would not be generated for images inside of masks.
  • Loading branch information
LaurenzV authored Oct 31, 2023
1 parent 7cb1ec4 commit 2f599e9
Showing 1 changed file with 26 additions and 9 deletions.
35 changes: 26 additions & 9 deletions crates/usvg/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub(crate) fn convert(tree: &Tree, opt: &XmlOptions) -> String {
xml.write_svg_attribute(AId::Height, &tree.size.height());
xml.write_viewbox(&tree.view_box);
xml.write_attribute("xmlns", "http://www.w3.org/2000/svg");
if has_xlink(tree) {
if has_xlink(&tree.root) {
xml.write_attribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
}

Expand Down Expand Up @@ -592,16 +592,21 @@ fn conv_element(node: &Node, is_clip_path: bool, opt: &XmlOptions, xml: &mut Xml
NodeKind::Group(ref g) => {
if is_clip_path {
// ClipPath with a Group element is an `usvg` special case.
// Group will contain a single Path element and we should set
// Group will contain a single path element and we should set
// `clip-path` on it.

if let NodeKind::Path(ref path) = *node.first_child().unwrap().borrow() {
let path = path.clone();
// TODO: As mentioned above, if it is a group element it should only contain a
// single path element. However when converting text nodes to path, multiple
// paths might be present. As a temporary workaround, we just loop over all
// children instead.
for child in node.children() {
if let NodeKind::Path(ref path) = *child.borrow() {
let path = path.clone();

let clip_id = g.clip_path.as_ref().map(|cp| cp.id.as_str());
write_path(&path, is_clip_path, g.transform, clip_id, opt, xml);
let clip_id = g.clip_path.as_ref().map(|cp| cp.id.as_str());
write_path(&path, is_clip_path, g.transform, clip_id, opt, xml);
}
}

return;
}

Expand Down Expand Up @@ -932,8 +937,8 @@ impl XmlWriterExt for XmlWriter {
}
}

fn has_xlink(tree: &Tree) -> bool {
for n in tree.root.descendants() {
fn has_xlink(node: &Node) -> bool {
for n in node.descendants() {
match *n.borrow() {
NodeKind::Group(ref g) => {
for filter in &g.filters {
Expand All @@ -945,6 +950,18 @@ fn has_xlink(tree: &Tree) -> bool {
return true;
}
}

if let Some(ref mask) = g.mask {
if has_xlink(&mask.root) {
return true;
}

if let Some(ref sub_mask) = mask.mask {
if has_xlink(&sub_mask.root) {
return true;
}
}
}
}
NodeKind::Image(_) => {
return true;
Expand Down

0 comments on commit 2f599e9

Please sign in to comment.