Code

Fix change in revision 9947 to be consistent with rest of the codebase.
[inkscape.git] / src / sp-lpe-item.cpp
index cc718f85ef3fbe0afd99ba62b948e6c15b368242..afd36d2ddef30cf1a68293cd86112984c86cf416 100644 (file)
@@ -1,5 +1,3 @@
-#define __SP_LPE_ITEM_CPP__
-
 /** \file
  * Base class for live path effect items
  */
@@ -7,6 +5,7 @@
  * Authors:
  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
  *   Bastien Bouclet <bgkweb@gmail.com>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2008 authors
  *
@@ -137,7 +136,7 @@ sp_lpe_item_finalize(GObject *object)
 static void
 sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
 {
-    sp_object_read_attr(object, "inkscape:path-effect");
+    object->readAttr( "inkscape:path-effect" );
 
     if (((SPObjectClass *) parent_class)->build) {
         ((SPObjectClass *) parent_class)->build(object, document, repr);
@@ -681,7 +680,7 @@ sp_lpe_item_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape:
         (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref);
 
     if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
-        SPObject *ochild = sp_object_get_child_by_repr(object, child);
+        SPObject *ochild = object->get_child_by_repr(child);
         if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
             sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild));
         }
@@ -692,7 +691,7 @@ static void
 sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child)
 {
     if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
-        SPObject *ochild = sp_object_get_child_by_repr(object, child);
+        SPObject *ochild = object->get_child_by_repr(child);
         if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
             sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild));
         }
@@ -773,16 +772,20 @@ bool sp_lpe_item_set_current_path_effect(SPLPEItem *lpeitem, Inkscape::LivePathE
 }
 
 /**
+ * Writes a new "inkscape:path-effect" string to xml, where the old_lpeobjects are substituted by the new ones.
  *  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)
+void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> const old_lpeobjs,
+                                    std::vector<LivePathEffectObject const *> const new_lpeobjs )
 {
     HRefList hreflist;
-    for (PathEffectList::const_iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it)
+    for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it)
     {
-        if ((*it)->lpeobject == old_lpeobj) {
-            const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");
+        LivePathEffectObject const * current_lpeobj = (*it)->lpeobject;
+        std::vector<LivePathEffectObject const *>::const_iterator found_it(std::find(old_lpeobjs.begin(), old_lpeobjs.end(), current_lpeobj));
+        if ( found_it != old_lpeobjs.end() ) {
+            std::vector<LivePathEffectObject const *>::difference_type found_index = std::distance (old_lpeobjs.begin(), found_it);
+            const gchar * repr_id = SP_OBJECT_REPR(new_lpeobjs[found_index])->attribute("id");
             gchar *hrefstr = g_strdup_printf("#%s", repr_id);
             hreflist.push_back( std::string(hrefstr) );
             g_free(hrefstr);
@@ -792,7 +795,7 @@ void sp_lpe_item_replace_path_effect(SPLPEItem *lpeitem, LivePathEffectObject *
         }
     }
     std::string r = hreflist_write_svg(hreflist);
-    SP_OBJECT_REPR(lpeitem)->setAttribute("inkscape:path-effect", r.c_str());
+    SP_OBJECT_REPR(this)->setAttribute("inkscape:path-effect", r.c_str());
 }
 
 /**
@@ -808,24 +811,30 @@ bool sp_lpe_item_fork_path_effects_if_necessary(SPLPEItem *lpeitem, unsigned int
     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
-                    }
+        // Note: replacing path effects messes up the path effect list
+
+        // Clones of the LPEItem will increase the refcount of the lpeobjects.
+        // Therefore, nr_of_allowed_users should be increased with the number of clones (i.e. refs to the lpeitem)
+        nr_of_allowed_users += SP_OBJECT(lpeitem)->hrefcount;
+
+        std::vector<LivePathEffectObject const *> old_lpeobjs, new_lpeobjs;
+        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 *forked_lpeobj = lpeobj->fork_private_if_necessary(nr_of_allowed_users);
+                if (forked_lpeobj != lpeobj) {
+                    forked = true;
+                    old_lpeobjs.push_back(lpeobj);
+                    new_lpeobjs.push_back(forked_lpeobj);
                 }
             }
-        } while (forked);
+        }
+
+        if (forked) {
+            lpeitem->replacePathEffects(old_lpeobjs, new_lpeobjs);
+        }
     }
 
     return forked;
@@ -858,4 +867,4 @@ bool sp_lpe_item_path_effects_enabled(SPLPEItem *lpeitem)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :