thorvg / thorvg

Thor Vector Graphics is a lightweight portable library used for drawing vector-based scenes and animations including SVG and Lottie. It can be freely utilized across various software platforms and applications to visualize graphical contents.

Home Page:https://www.thorvg.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[SVG] Nested elements rendering when they shouldn't

MewPurPur opened this issue · comments

<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="6" height="4" fill="red"><circle cx="10" cy="10" r="3"/></rect></svg>

Every renderer I found ignores the circle inside the rect tag, but not ThorVG, which renders both shapes.

I didn't find this behavior stated explicitly anywhere in the SVG specification. This seems like it might be it, though: https://www.w3.org/TR/SVG2/struct.html#InterfaceSVGSVGElement

To find the non-container graphics elements within a given element element, the following steps are run:

Let result be an initially empty list.
If element is an ‘svg’ or ‘g’ element, then for each child element child of element, in document order:

Otherwise, if element is a graphics element then append element to result.
Return result.

But while at it, I found other related ones that we're doing wrong: https://www.w3.org/TR/SVG2/struct.html#UnknownElement

Here's an example SVG from the specification, trimmed down to only consider the elements we currently support:

<svg viewBox="0 0 700 200" xmlns="http://www.w3.org/2000/svg">
  <mysteryElement>
    <path d="M0 0h600v200h-600z" fill="#bdb76b"/>
  </mysteryElement>
  <hideElement xmlns="http://www.example.com/invisibleML">
    <path d="M0 0h300v100h-300z" fill="#f5f5f5"/>
  </hideElement>
  <linearGradient>
    <gradientExtension>
      <path d="M300 0h100v200h-100z" fill="#f0f"/>
    </gradientExtension>
  </linearGradient>
</svg>

The rectangle inside the mysteryElement renders, which is correct.

The rectangle inside the hideElement shouldn't render because namespace was overridden with a non-SVG one, but it does render.

The rectangle inside gradientExtension shouldn't render because linearGradient isn't rendered, but it does. It actually does even if we put it directly under linearGradient.

@MewPurPur this first example should be (and will be :) ) fixed. basic shapes should be siblings within a container, not nested within each other.

Regarding the unknown elements - do you really need them, or are they more like a curiosity ?

Regarding the unknown elements - do you really need them, or are they more like a curiosity?

I'm making a code-focused SVG editor with the ThorVG rendering backend, so in theory, since it accepts any code, anything that doesn't render according to the specification counts as a bug in my app too.

In practice, only the issues with shapes rendering when inside other shapes or gradients will be encountered often, since you can create those from the GUI and drag-and-drop them around easily, while the other things are niche and can't be done via UI.

@MewPurPur, do you think we can close this one? The 'unknown elements support' issue can be opened separately.

hmm.. I wonder if 'unknown elements support' can be resolved.
I don't think we can distinguish between <mysteryElement> and <hideElement xmlns="http://www.example.com/invisibleML"> in our current structure. Neither may be recognized, or both may be recognized as <g>.
Graphics Element declared inside <linearGradient> can be sent as a child of defs.
I don't know if I should support this, I don't think it's common.

hmm.. I wonder if 'unknown elements support' can be resolved. I don't think we can distinguish between <mysteryElement> and <hideElement xmlns="http://www.example.com/invisibleML"> in our current structure. Neither may be recognized, or both may be recognized as <g>. Graphics Element declared inside <linearGradient> can be sent as a child of defs. I don't know if I should support this, I don't think it's common.

Yes, I don't think anyone will ever use this, so I would suggest separating this task from here. If @MewPurPur thinks it's worthwhile to open such an issue, he will. I believe the original issue here has already been resolved.

Sure, we can close this. But I'll open for the "Shapes inside linearGradient element rendering" one, it's important to me.