From e72ec96ad2ab870dc0af88bc559c86b32c63dd9c Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Tue, 18 May 2010 21:17:03 +0200 Subject: [PATCH] better fix for lpe stack forking --- src/live_effects/lpeobject.cpp | 1 + src/sp-item.cpp | 22 +-------------------- src/sp-lpe-item.cpp | 36 ++++++++++++++++++++++++++++++++++ src/sp-lpe-item.h | 1 + src/ui/clipboard.cpp | 5 +++-- 5 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp index be5d618f2..aa916318d 100644 --- a/src/live_effects/lpeobject.cpp +++ b/src/live_effects/lpeobject.cpp @@ -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) diff --git a/src/sp-item.cpp b/src/sp-item.cpp index d6f68fc74..5a2dfb2f0 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -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); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 740690887..cc718f85e 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -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) diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 4823390de..87425ba94 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -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); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index dd1f981b5..9ce2ac5ba 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -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); } } -- 2.30.2