]> git.tokkee.org Git - inkscape.git/commitdiff

Code

fix bug when forking LPE stack
authorJohan Engelen <goejendaagh@zonnet.nl>
Fri, 14 May 2010 23:08:45 +0000 (01:08 +0200)
committerJohan Engelen <goejendaagh@zonnet.nl>
Fri, 14 May 2010 23:08:45 +0000 (01:08 +0200)
src/live_effects/lpeobject.cpp
src/sp-item.cpp
src/sp-lpe-item.cpp

index ec0dee0beb1c5e41d9281efa2d9a28e9f939fdd7..be5d618f26b9ca1d212a520cfe96b0649f035d12 100644 (file)
@@ -252,11 +252,12 @@ LivePathEffectObject::fork_private_if_necessary(unsigned int nr_of_allowed_users
     if (SP_OBJECT_HREFCOUNT(this) > nr_of_allowed_users) {
         SPDocument *doc = SP_OBJECT_DOCUMENT(this);
         Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+        Inkscape::XML::Node *dup_repr = SP_OBJECT_REPR (this)->duplicate(xml_doc);
 
-        Inkscape::XML::Node *repr = SP_OBJECT_REPR (this)->duplicate(xml_doc);
-        SP_OBJECT_REPR (SP_DOCUMENT_DEFS (doc))->addChild(repr, NULL);
-        LivePathEffectObject *lpeobj_new = (LivePathEffectObject *) doc->getObjectByRepr(repr);
-        Inkscape::GC::release(repr);
+        SP_OBJECT_REPR (SP_DOCUMENT_DEFS (doc))->addChild(dup_repr, NULL);
+        LivePathEffectObject *lpeobj_new = LIVEPATHEFFECT( doc->getObjectByRepr(dup_repr) );
+
+        Inkscape::GC::release(dup_repr);
         return lpeobj_new;
     }
     return this;
index c4411e47d2ed100f83b3a5290e0d62b51320a2f3..d6f68fc74019b7a5ffd39e5bc2f24e899da94d65 100644 (file)
@@ -1377,22 +1377,36 @@ sp_item_adjust_livepatheffect (SPItem *item, Geom::Matrix const &postmul, bool s
 
     SPLPEItem *lpeitem = SP_LPE_ITEM (item);
     if ( sp_lpe_item_has_path_effect(lpeitem) ) {
+        // If one of the path effects is used by 2 or more items, fork it
+        // so that each object has its own independent copy of the effect.
+        // Forking messes up the path effect list, so after each fork,
+        // reload the list and recheck if more forking is required.
+        bool forked = false;
+        do {
+            forked = false;
+            PathEffectList effect_list =  sp_lpe_item_get_effect_list(lpeitem);
+            for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); it++)
+            {
+                LivePathEffectObject *lpeobj = (*it)->lpeobject;
+                if (lpeobj) {
+                    LivePathEffectObject *new_lpeobj = lpeobj->fork_private_if_necessary();
+                    if (new_lpeobj != lpeobj) {
+                        sp_lpe_item_replace_path_effect(lpeitem, lpeobj, new_lpeobj);
+                        forked = true;
+                        break;  // forked, so break the for-loop and recheck
+                    }
+                }
+            }
+        } while (forked);
+
+        // now that all LPEs are forked_if_necessary, we can apply the transform
         PathEffectList effect_list =  sp_lpe_item_get_effect_list(lpeitem);
         for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); it++)
         {
-            // If the path effect is used by 2 or more items, fork it
-            // so that each object has its own independent copy of the effect
             LivePathEffectObject *lpeobj = (*it)->lpeobject;
-            if (lpeobj) {
-                LivePathEffectObject *new_lpeobj = lpeobj->fork_private_if_necessary();
-                if (new_lpeobj != lpeobj) {
-                    sp_lpe_item_replace_path_effect(lpeitem, lpeobj, new_lpeobj);
-                }
-
-                if (lpeobj->get_lpe()) {
-                    Inkscape::LivePathEffect::Effect * effect = lpeobj->get_lpe();
-                    effect->transform_multiply(postmul, set);
-                }
+            if (lpeobj && lpeobj->get_lpe()) {
+                Inkscape::LivePathEffect::Effect * effect = lpeobj->get_lpe();
+                effect->transform_multiply(postmul, set);
             }
         }
     }
index 1bb500dd2beb7029f5c7a459543fa4c53c44cb06..740690887b872c2ad12b6eda08d7ef5f5041d756 100644 (file)
@@ -772,6 +772,9 @@ bool sp_lpe_item_set_current_path_effect(SPLPEItem *lpeitem, Inkscape::LivePathE
     return false;
 }
 
+/**
+ *  Note that this method messes up the item's \c PathEffectList.
+ */
 void sp_lpe_item_replace_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * old_lpeobj,
                                         LivePathEffectObject * new_lpeobj)
 {