From 6d0e470368887b4485fe02cd227dd2df363b2ba5 Mon Sep 17 00:00:00 2001 From: dvlierop2 Date: Sat, 20 Jun 2009 13:18:48 +0000 Subject: [PATCH] When ungrouping, apply the correct transformation to a linked offset (fixes bug #239430) --- src/sp-item-group.cpp | 48 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index ed5382fae..9c19ce75a 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -34,6 +34,7 @@ #include "sp-item-transform.h" #include "sp-root.h" #include "sp-use.h" +#include "sp-offset.h" #include "sp-clippath.h" #include "sp-mask.h" #include "sp-path.h" @@ -366,18 +367,18 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") || !strcmp (grepr->name(), "svg:switch")); - // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse - sp_item_adjust_paint_recursive (gitem, Geom::identity(), Geom::identity(), false); + // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse + sp_item_adjust_paint_recursive (gitem, Geom::identity(), Geom::identity(), false); SPItem *pitem = SP_ITEM (SP_OBJECT_PARENT (gitem)); Inkscape::XML::Node *prepr = SP_OBJECT_REPR (pitem); - if (SP_IS_BOX3D(gitem)) { - group = box3d_convert_to_group(SP_BOX3D(gitem)); - gitem = SP_ITEM(group); - } + if (SP_IS_BOX3D(gitem)) { + group = box3d_convert_to_group(SP_BOX3D(gitem)); + gitem = SP_ITEM(group); + } - sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(group), false); + sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(group), false); /* Step 1 - generate lists of children objects */ GSList *items = NULL; @@ -428,7 +429,24 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // make sure a clone's effective transform is the same as was under group ctrans = g.inverse() * citem->transform * g; } else { - ctrans = citem->transform * g; + // We should not apply the group's transformation to both a linked offset AND to its source + if (SP_IS_OFFSET(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? + SPItem *source = sp_offset_get_source(SP_OFFSET(citem)); + // When dealing with a chain of linked offsets, the transformation of an offset will be + // tied to the transformation of the top-most source, not to any of the intermediate + // offsets. So let's find the top-most source + while (source != NULL && SP_IS_OFFSET(source)) { + source = sp_offset_get_source(SP_OFFSET(source)); + } + if (source != NULL && // If true then we must be dealing with a linked offset ... + SP_OBJECT(group)->isAncestorOf(SP_OBJECT(source)) == false) { // ... of which the source is not in the same group + ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset + } else { + ctrans = citem->transform; + } + } else { + ctrans = citem->transform * g; + } } // FIXME: constructing a transform that would fully preserve the appearance of a @@ -443,7 +461,7 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // (i.e. optimized into the object if the corresponding preference is set) gchar *affinestr=sp_svg_transform_write(ctrans); nrepr->setAttribute("transform", affinestr); - g_free(affinestr); + g_free(affinestr); items = g_slist_prepend (items, nrepr); @@ -464,11 +482,11 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) if (objects) { Inkscape::XML::Node *last_def = SP_OBJECT_REPR(defs)->lastChild(); while (objects) { - Inkscape::XML::Node *repr = (Inkscape::XML::Node *) objects->data; - if (!sp_repr_is_meta_element(repr)) - SP_OBJECT_REPR(defs)->addChild(repr, last_def); - Inkscape::GC::release(repr); - objects = g_slist_remove (objects, objects->data); + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) objects->data; + if (!sp_repr_is_meta_element(repr)) + SP_OBJECT_REPR(defs)->addChild(repr, last_def); + Inkscape::GC::release(repr); + objects = g_slist_remove (objects, objects->data); } } @@ -476,7 +494,7 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) while (items) { Inkscape::XML::Node *repr = (Inkscape::XML::Node *) items->data; // add item - prepr->appendChild(repr); + prepr->appendChild(repr); // restore position; since the items list was prepended (i.e. reverse), we now add // all children at the same pos, which inverts the order once again repr->setPosition(pos > 0 ? pos : 0); -- 2.30.2