summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2010-05-14 23:08:45 +0000
committerJohan Engelen <goejendaagh@zonnet.nl>2010-05-14 23:08:45 +0000
commitc2aa64ea2a2778e4b78b16962281d0e0659de249 (patch)
tree6198723fe348d72980a7538bac4dab4526ea0bf2 /src
parentTranslations. Belarusian tutorials update. (diff)
downloadinkscape-c2aa64ea2a2778e4b78b16962281d0e0659de249.tar.gz
inkscape-c2aa64ea2a2778e4b78b16962281d0e0659de249.zip
fix bug when forking LPE stack
Fixed bugs: - https://launchpad.net/bugs/578969 - https://launchpad.net/bugs/505400 (bzr r9419)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpeobject.cpp9
-rw-r--r--src/sp-item.cpp38
-rw-r--r--src/sp-lpe-item.cpp3
3 files changed, 34 insertions, 16 deletions
diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp
index ec0dee0be..be5d618f2 100644
--- a/src/live_effects/lpeobject.cpp
+++ b/src/live_effects/lpeobject.cpp
@@ -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;
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index c4411e47d..d6f68fc74 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -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);
}
}
}
diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
index 1bb500dd2..740690887 100644
--- a/src/sp-lpe-item.cpp
+++ b/src/sp-lpe-item.cpp
@@ -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)
{