Quoting Maxim Shemanarev <mcseem@...1076...>:
Well, at least the version I have (v4.1) just gets into an infinite loop anddoesn't respond. I don't think it's correct.
(assuming you mean 0.41)
Hmm, you're right. It catches trivial circular references (e.g. to self or ancestor), but not more complex ones.
Anyway, there's a choice if you control the level of recursion (and it's a must IMO). You can report an error and stop, or you can keep rendering until some level of recursion is exceeded.
For a circular reference, the standard requires that you do not render the erroneous element or any following elements at all (a naive implementation might have to throw out some intermediate rendering product to do this).
I do not believe the standard requires any particular action for references that are deep but not recursive, but stopping rendering at some point is sensible even if not strictly conforming.
I don't see any other elegant way of detecting the loops, because they can have any level of indirection (a pattern refers to another pattern that refers to another pattern, etc... and the first pattern refers to the first one).
It's also worth noting that the circularity can happen along several "axes"; for example:
... <style type="text/css">.foo { fill: url(#blah); }</style> ... <pattern id="blah" ...> <rect class="foo" ... /> </pattern> ...
BTW, is that legal to have *nested* patterns/markers at all in SVG?
Yes. See sections 13.3 and 11.6.2 of SVG 1.1:
<!ENTITY % SVG.marker.content "( %SVG.Description.class; | %SVG.Animation.class; %SVG.Structure.class; %SVG.Conditional.class; %SVG.Image.class; %SVG.Style.class; %SVG.Shape.class; %SVG.Text.class; %SVG.Marker.class; <== %SVG.ColorProfile.class; %SVG.Gradient.class; %SVG.Pattern.class; %SVG.Clip.class; %SVG.Mask.class; %SVG.Filter.class; %SVG.Cursor.class; %SVG.Hyperlink.class; %SVG.View.class; %SVG.Script.class; %SVG.Font.class; %SVG.marker.extra.content; )*"
<!ENTITY % SVG.pattern.content "( %SVG.Description.class; | %SVG.Animation.class; %SVG.Structure.class; %SVG.Conditional.class; %SVG.Image.class; %SVG.Style.class; %SVG.Shape.class; %SVG.Text.class; %SVG.Marker.class; %SVG.ColorProfile.class; %SVG.Gradient.class; %SVG.Pattern.class; <== %SVG.Clip.class; %SVG.Mask.class; %SVG.Filter.class; %SVG.Cursor.class; %SVG.Hyperlink.class; %SVG.View.class; %SVG.Script.class; %SVG.Font.class; %SVG.pattern.extra.content; )*"
-mental
Quoting Maxim Shemanarev <mcseem@...1076...>:
I don't see any other elegant way of detecting the loops, because they can have any level of indirection (a pattern refers to another pattern that refers to another pattern, etc... and the first pattern refers to the first one).
See src/sp-gradient.cpp:chase_hrefs for one approach.
(At the time I wrote that, I wasn't aware of §5.3's prohibition on all circular references: unlike circular references for <use> or the <pattern> example that mental gave, circular references among gradients would seem reasonable but for §5.3's prohibition.)
pjrm.
participants (2)
-
unknown@example.com
-
Peter Moulder