Skip to content

Fix SVG embedding

Matthew Woehlke requested to merge mwoehlke/inkscape:fix-svg-embedding into master

See commit messages for details. This fixes #1757 (closed) and a related problem:

  • An embedded (via a <use>) SVG cannot resolve hrefs to elements in the embedded SVG.
  • The child document's CSS styling is not applied.

Both of these behaviors are prescribed¹ by the specification.

That said, note that (as I understand the spec), this implementation is non-conforming, because it will resolve references anywhere in the embedded document, not just within the selected subtree. However, a) from my (admittedly limited) understanding of the code, I believe it is somewhat challenging to implement this strictly according to the spec², and would meanwhile like it to be less broken, and b) I suspect this behavior is actually more useful anyway. (In particular, allowing references outside the referenced subtree makes it possible to embed multiple parts of an SVG that share definitions, which would otherwise require duplicating those definitions in the embedding document.)

I'm very new to Inkscape's code, and this may not be the best approach. Also, it seems to be causing an assertion failure. However, I would appreciate if someone more knowledgeable can perhaps take a look and help get this into shape where it could be merged.

Note: Passing the SPUse to URIReference::attach seems fairly kludgy, but it was the most obvious way to ensure that the child document gets bound to the SPUse only when resolving the href and not, say, a url in the <use>'s style (as might happen if we just tried to dynamic_cast the reference's owner). Thoughts on a better way to handle this would be welcome.

(¹ Strictly speaking, as I understand the spec, <style> from the embedded document should only be used if part of the referenced subtree. However, CSS from the child was never being used, even if the subtree was actually the <svg>. It's not 100% clear that referencing the <svg> is supposed to be allowed, but it isn't clearly proscribed either, and in any case, doing so works since at least Inkscape 1.0.2.)

(² It would appear to require rebuilding the child SPDocument to contain only the referenced subtree. As I believe some of the stuff from the <svg> is required, this seems like it may require a non-trivial effort of combining bits of the root <svg> and the referenced subtree. Moreover, as noted, I would be inclined to want to put such logic behind some sort of 'strict conformance' option.)

Merge request reports