=== modified file 'src/sp-item-group.cpp' --- src/sp-item-group.cpp 2015-01-15 19:03:17 +0000 +++ src/sp-item-group.cpp 2015-02-11 01:17:38 +0000 @@ -399,6 +399,32 @@ } } +/** + * @description finds clones of a child of the group; and inverse the group transform + * @params + * group : current group + * parent : original parent + * g : transform * + */ +void sp_ungroup_recursive_cancel_double_transform(SPGroup *group,SPItem *parent, Geom::Affine const g){ + for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { + SPItem *citem = dynamic_cast(child); + if (citem) { + SPUse *useitem = dynamic_cast(citem); + if(useitem && useitem->get_original() == parent){ + Geom::Affine ctrans; + ctrans=g.inverse() * citem->transform; + gchar *affinestr=sp_svg_transform_write(ctrans); + citem->setAttribute("transform", affinestr); + g_free(affinestr); + } + SPGroup *groupitem = dynamic_cast(citem); + if(groupitem){ + sp_ungroup_recursive_cancel_double_transform(groupitem,parent,g); + } + } + } +} void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) @@ -435,10 +461,11 @@ /* Step 1 - generate lists of children objects */ GSList *items = NULL; GSList *objects = NULL; + Geom::Affine const g(group->transform); for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { - SPItem *citem = dynamic_cast(child); if (citem) { + sp_ungroup_recursive_cancel_double_transform(root,citem,g); /* Merging of style */ // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox @@ -472,13 +499,6 @@ // Merging transform Geom::Affine ctrans; - Geom::Affine const g(group->transform); - SPUse *useitem = dynamic_cast(citem); - if (useitem && useitem->get_original() && - useitem->get_original()->parent == dynamic_cast(group)) { - // make sure a clone's effective transform is the same as was under group - ctrans = g.inverse() * citem->transform * g; - } else { // We should not apply the group's transformation to both a linked offset AND to its source if (dynamic_cast(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? SPItem *source = sp_offset_get_source(dynamic_cast(citem)); @@ -497,7 +517,6 @@ } else { ctrans = citem->transform * g; } - } // FIXME: constructing a transform that would fully preserve the appearance of a // textpath if it is ungrouped with its path seems to be impossible in general