Code

better fix for lpe stack forking
authorJohan Engelen <goejendaagh@zonnet.nl>
Tue, 18 May 2010 19:17:03 +0000 (21:17 +0200)
committerJohan Engelen <goejendaagh@zonnet.nl>
Tue, 18 May 2010 19:17:03 +0000 (21:17 +0200)
src/live_effects/lpeobject.cpp
src/sp-item.cpp
src/sp-lpe-item.cpp
src/sp-lpe-item.h
src/ui/clipboard.cpp

index be5d618f26b9ca1d212a520cfe96b0649f035d12..aa916318d8da70ab7586da2aa859837d5194633c 100644 (file)
@@ -245,6 +245,7 @@ livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/,
 /**
  * If this has other users, create a new private duplicate and return it
  * returns 'this' when no forking was necessary (and therefore no duplicate was made)
+ * Check out sp_lpe_item_fork_path_effects_if_necessary !
  */
 LivePathEffectObject *
 LivePathEffectObject::fork_private_if_necessary(unsigned int nr_of_allowed_users)
index d6f68fc74019b7a5ffd39e5bc2f24e899da94d65..5a2dfb2f05f2cec6508951a87caf71e51d91c228 100644 (file)
@@ -1377,27 +1377,7 @@ 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);
+        sp_lpe_item_fork_path_effects_if_necessary(lpeitem);
 
         // now that all LPEs are forked_if_necessary, we can apply the transform
         PathEffectList effect_list =  sp_lpe_item_get_effect_list(lpeitem);
index 740690887b872c2ad12b6eda08d7ef5f5041d756..cc718f85ef3fbe0afd99ba62b948e6c15b368242 100644 (file)
@@ -795,6 +795,42 @@ void sp_lpe_item_replace_path_effect(SPLPEItem *lpeitem, LivePathEffectObject *
     SP_OBJECT_REPR(lpeitem)->setAttribute("inkscape:path-effect", r.c_str());
 }
 
+/**
+ *  Check all effects in the stack if they are used by other items, and fork them if so.
+ *  It is not recommended to fork the effects by yourself calling LivePathEffectObject::fork_private_if_necessary,
+ *  use this method instead.
+ *  Returns true if one or more effects were forked; returns false if nothing was done.
+ */
+bool sp_lpe_item_fork_path_effects_if_necessary(SPLPEItem *lpeitem, unsigned int nr_of_allowed_users)
+{
+    bool forked = false;
+
+    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.
+        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(nr_of_allowed_users);
+                    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);
+    }
+
+    return forked;
+}
+
 // Enable or disable the path effects of the item.
 // The counter allows nested calls
 static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable)
index 4823390defff8909742fd5fa8559314998105423..87425ba9489e2ddef5b0750a93ba57cd0f725ff6 100644 (file)
@@ -59,6 +59,7 @@ void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, gchar *value, bool reset);
 void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj);
 void sp_lpe_item_replace_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * old_lpeobj,
                                         LivePathEffectObject * new_lpeobj);
+bool sp_lpe_item_fork_path_effects_if_necessary(SPLPEItem *lpeitem, unsigned int nr_of_allowed_users = 1);
 void sp_lpe_item_remove_all_path_effects(SPLPEItem *lpeitem, bool keep_paths);
 void sp_lpe_item_remove_current_path_effect(SPLPEItem *lpeitem, bool keep_paths);
 void sp_lpe_item_down_current_path_effect(SPLPEItem *lpeitem);
index dd1f981b5dd8d1de2adae5520dceaf73911ea6ec..9ce2ac5bac211ae2b5908a00d549a181c32171cc 100644 (file)
@@ -1057,6 +1057,8 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effectsta
     {
         SPLPEItem *lpeitem = SP_LPE_ITEM(item);
         // for each effect in the stack, check if we need to fork it before adding it to the item
+        sp_lpe_item_fork_path_effects_if_necessary(lpeitem, 1);
+
         std::istringstream iss(effectstack);
         std::string href;
         while (std::getline(iss, href, ';'))
@@ -1065,8 +1067,7 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effectsta
             if (!obj) {
                 return;
             }
-            // if the effectstack is not used by anyone, we might as well take it
-            LivePathEffectObject *lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(1);
+            LivePathEffectObject *lpeobj = LIVEPATHEFFECT(obj);
             sp_lpe_item_add_path_effect(lpeitem, lpeobj);
         }
     }