Comment 33 for bug 171117

Revision history for this message
Robin Battey (zanfur) wrote :

I decided to go whole hog and I basically re-structured it from the ground up. I added the parameters I discussed in comment #23, allowing you to ungroup the whole document, leave levels of grouping at the top, leave levels of grouping at the bottom as measured from the top, and leave levels of grouping at the bottom as measured from the bottom. In your PDF, only the lowest level of grouping contains the odd clip-path behavior, so you can just set it to ungroup all but one level and the view doesn't change at all. You can also easily add any filter you'd like, possibly even an xpath expression, kind of like the color replace extension (see coloreffect.py in the inkscape distribution).

Your original plugin removed any and all inherited styles from the document, even for non-group containers (such as embedded svgs, anchors, and switches). I pulled the transform merging and style merging bits out into their own one-step-only helper functions, allowing me to propagate styles and transforms for only a single group instead of a group and *everything* underneath it. There's now a "_want_ungroup" function that is easy to modify if anyone adds filters of any kind, though I've already implemented the "count from top" and "count from bottom" varieties.

I also created a stub for propagating clip-paths to a group's children, but it's not implemented yet because it's not as simple as just copying it to the children: The child might already have a clip-path, requiring you to make a new hierarchical clip-path in the defs section of the svg; and any transform the child has apparently will apply the clip-path as well, meaning you'd need to apply the reverse of that transform to the clip-path itself in order to maintain the view.

This one should be pretty simple to follow: The _deep_ungroup is the recursing bit, tracking the depth from top and height from bottom in the stack. It does the ungrouping on the way up, instead of on the way down, because it has to hit bottom before it can know the height from the bottom. On the way back up, it queries the "_want_ungroup" function for every level, and if the function returns affirmative it calls the "_ungroup" helper function that does the heavy lifting to actually flatten the group.