Code

+ Fix bug #179840, forking of LPEs
authorjohanengelen <johanengelen@users.sourceforge.net>
Wed, 2 Jan 2008 18:10:43 +0000 (18:10 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Wed, 2 Jan 2008 18:10:43 +0000 (18:10 +0000)
+ Groundwork for fixing transforming LPE bugs. TODO: implement the actual transformation of LPE parameters.

12 files changed:
src/box3d.cpp
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpeobject.cpp
src/live_effects/lpeobject.h
src/selection-chemistry.cpp
src/sp-item.cpp
src/sp-item.h
src/sp-path.cpp
src/sp-shape.cpp
src/sp-shape.h
src/splivarot.cpp

index 3397cd6b01088ff24bc7787ff1d5ed2b85af1e49..0add188e7cbd1a163b640a5d39f6c146072f798d 100644 (file)
@@ -402,6 +402,9 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform)
 
         // Adjust gradient fill
         sp_item_adjust_gradient(sideitem, xform);
+
+        // Adjust LPE
+        sp_item_adjust_livepatheffect(item, xform);
     }
     ***/
 
index 117fbcdb7360bb3c6a41b4cddf80a5413aae253e..21c1d6719d4f119ef28a68c7c4f3f0f11b72f70e 100644 (file)
@@ -6,6 +6,8 @@
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include "live_effects/effect.h"
+
 #include "display/display-forward.h"
 #include "xml/node-event-vector.h"
 #include "sp-object.h"
 #include "document.h"
 #include <glibmm/i18n.h>
 
-#include "live_effects/effect.h"
 #include "live_effects/lpeobject.h"
 #include "live_effects/parameter/parameter.h"
 #include <glibmm/ustring.h>
 #include "live_effects/n-art-bpath-2geom.h"
 #include "display/curve.h"
-#include <2geom/sbasis-to-bezier.h>
 #include <gtkmm.h>
 
 #include <exception>
 
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/matrix.h>
+
+
 // include effects:
 #include "live_effects/lpe-skeletalstrokes.h"
 #include "live_effects/lpe-pathalongpath.h"
@@ -351,6 +355,14 @@ Effect::setup_notepath(Inkscape::NodePath::Path *np)
     np->helperpath_width = 1.0;
 }
 
+void
+Effect::transform_multiply(Geom::Matrix const& postmul, bool set)
+{
+    // cycle through all parameters. Most parameters will not need transformation, but path and point params do.
+    for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); it++) {
+        Parameter * param = *it;
+    }
+}
 
 } /* namespace LivePathEffect */
 
index 964bcd12b256fcb2807d90b95254ce5a216da8c8..4c1e4e0eb1a955d71b3e2e8d07ba4cdba8f33c14 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * Inkscape::LivePathEffect
  *
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+* Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -33,6 +33,10 @@ namespace Gtk {
     class Tooltips;
 }
 
+namespace Geom {
+    class Matrix;
+}
+
 namespace Inkscape {
 
 namespace XML {
@@ -74,6 +78,10 @@ public:
 
     virtual void resetDefaults(SPItem * item);
 
+    virtual void setup_notepath(Inkscape::NodePath::Path *np);
+
+    virtual void transform_multiply(Geom::Matrix const& postmul, bool set);
+
     Glib::ustring          getName();
     Inkscape::XML::Node *  getRepr();
     SPDocument *           getSPDoc();
@@ -85,8 +93,6 @@ public:
 
     void editNextParamOncanvas(SPItem * item, SPDesktop * desktop);
 
-    virtual void setup_notepath(Inkscape::NodePath::Path *np);
-
 protected:
     Effect(LivePathEffectObject *lpeobject);
 
index 6066f11f356409422c799b10303a6754a985cfb6..bcb01463a741e609253fc29149996df32576424c 100644 (file)
@@ -1,21 +1,23 @@
 #define INKSCAPE_LIVEPATHEFFECT_OBJECT_CPP
 
 /*
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include "live_effects/lpeobject.h"
+
+#include "live_effects/effect.h"
+
 #include "xml/repr.h"
 #include "xml/node-event-vector.h"
 #include "sp-object.h"
 #include "attributes.h"
-
 #include "document.h"
-#include <glibmm/i18n.h>
+#include "document-private.h"
 
-#include "live_effects/lpeobject.h"
-#include "live_effects/effect.h"
+#include <glibmm/i18n.h>
 
 //#define LIVEPATHEFFECT_VERBOSE
 
@@ -251,6 +253,25 @@ livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/,
     lpeobj->requestModified(SP_OBJECT_MODIFIED_FLAG);
 }
 
+/**
+ * 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)
+ */
+LivePathEffectObject *
+LivePathEffectObject::fork_private_if_necessary(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 *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);
+        return lpeobj_new;
+    }
+    return this;
+}
 
 /*
   Local Variables:
index c2e9fafa7949582827d1cc928f131444fac8ee8a..bc13e596adbb50fa6d12bf47c3a2760a087e4503 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * Inkscape::LivePathEffect
  *
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+* Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #define LIVEPATHEFFECT(o)    (G_TYPE_CHECK_INSTANCE_CAST((o), TYPE_LIVEPATHEFFECT, LivePathEffectObject))
 #define IS_LIVEPATHEFFECT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), TYPE_LIVEPATHEFFECT))
 
-/*
-namespace Inkscape {
-namespace LivePathEffect {
-    class Effect;
-};
-};
-*/
-
 struct LivePathEffectObject : public SPObject {
-    Inkscape::LivePathEffect::EffectType effecttype;  // fixme: i think this is not needed
+    Inkscape::LivePathEffect::EffectType effecttype;
     Inkscape::LivePathEffect::Effect *lpe;
 
     bool effecttype_set;
+
+    LivePathEffectObject * fork_private_if_necessary(int nr_of_allowed_users = 1);
 };
 
 /// The LivePathEffect vtable.
index 040e5f8392585d43c300dc1c864d170f4c54ed85..56ef7b01f97d334f3c61e8d537dab9ebaa58d4c9 100644 (file)
@@ -76,6 +76,8 @@
 #include "xml/simple-document.h"
 #include "sp-filter-reference.h"
 #include "gradient-drag.h"
+#include "uri-references.h"
+#include "live_effects/lpeobject.h"
 
 using NR::X;
 using NR::Y;
@@ -1268,11 +1270,12 @@ void sp_selection_paste_livepatheffect()
         return;
     }
 
-    paste_defs (&defs_clipboard, sp_desktop_document(desktop));
+    SPDocument *doc = sp_desktop_document(desktop);
+    paste_defs (&defs_clipboard, doc);
 
     Inkscape::XML::Node *repr = (Inkscape::XML::Node *) clipboard->data;
-    char const *effectstr = repr->attribute("inkscape:path-effect");
-    if (!effectstr) {
+    char const *effecturi = repr->attribute("inkscape:path-effect");
+    if (!effecturi) {
         SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Clipboard does not contain a live path effect."));
         return;
     }
@@ -1280,8 +1283,13 @@ void sp_selection_paste_livepatheffect()
     for ( GSList const *itemlist = selection->itemList(); itemlist != NULL; itemlist = g_slist_next(itemlist) ) {
         SPItem *item = reinterpret_cast<SPItem*>(itemlist->data);
         if ( item && SP_IS_SHAPE(item) ) {
-            Inkscape::XML::Node *selrepr = (Inkscape::XML::Node *) SP_OBJECT_REPR(item);
-            selrepr->setAttribute("inkscape:path-effect", effectstr);
+            SPShape * shape = SP_SHAPE(item);
+
+            // create a private LPE object!
+            SPObject * obj = sp_uri_reference_resolve(doc, effecturi);
+            LivePathEffectObject * lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(0);
+            
+            sp_shape_set_path_effect(shape, lpeobj);
 
             // set inkscape:original-d for paths. the other shapes don't need this.
             if ( SP_IS_PATH(item) ) {
index f064b246c619e7e88c61ea68d404b9f71925c9a7..90765fc949ab13cf0783b1823b2c6df5bed247d2 100644 (file)
 #include "libnr/nr-matrix-translate-ops.h"
 #include "libnr/nr-scale-translate-ops.h"
 #include "libnr/nr-translate-scale-ops.h"
+#include "libnr/nr-convert2geom.h"
 #include "algorithms/find-last-if.h"
 #include "util/reverse-list.h"
 
 #include "xml/repr.h"
 #include "extract-uri.h"
 
+#include "live_effects/lpeobject.h"
+#include "live_effects/effect.h"
+
 #define noSP_ITEM_DEBUG_IDLE
 
 static void sp_item_class_init(SPItemClass *klass);
@@ -1155,6 +1159,27 @@ sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, N
 
 }
 
+void
+sp_item_adjust_livepatheffect (SPItem *item, NR::Matrix const &postmul, bool set)
+{
+    if ( !SP_IS_SHAPE(item) )
+        return;
+
+    SPShape *shape = SP_SHAPE (item);
+    if ( sp_shape_has_path_effect(shape) ) {
+        LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
+        LivePathEffectObject *new_lpeobj = lpeobj->fork_private_if_necessary();
+        if (new_lpeobj != lpeobj) {
+            sp_shape_set_path_effect(shape, new_lpeobj);
+        }
+
+        Inkscape::LivePathEffect::Effect * effect = sp_shape_get_livepatheffect(shape);
+        if (effect) {
+            effect->transform_multiply (to_2geom(postmul), set);
+        }
+    }
+}
+
 /**
  * A temporary wrapper for the next function accepting the NRMatrix
  * instead of NR::Matrix
index b3867f146156ca4b53f960b46ff537c58488bed3..9bbaefef167c48e019c3f4970e76208849b89bb1 100644 (file)
@@ -228,6 +228,7 @@ void sp_item_adjust_gradient(SPItem *item, /* NR::Matrix const &premul, */ NR::M
 void sp_item_adjust_stroke(SPItem *item, gdouble ex);
 void sp_item_adjust_stroke_width_recursive(SPItem *item, gdouble ex);
 void sp_item_adjust_paint_recursive(SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern);
+void sp_item_adjust_livepatheffect(SPItem *item, NR::Matrix const &postmul, bool set = false);
 
 void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NRMatrix const *transform, NR::Matrix const *adv = NULL);
 void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv = NULL, bool compensate = true);
index b9e94d72e3a6ffcfbc81cb9ce043eeaf29a9292a..d97bbddb9664b6d7b3946af85a7f03b4c86d8f9e 100644 (file)
@@ -363,6 +363,9 @@ sp_path_set_transform(SPItem *item, NR::Matrix const &xform)
     // Adjust gradient fill
     sp_item_adjust_gradient(item, xform);
 
+    // Adjust LPE
+    sp_item_adjust_livepatheffect(item, xform);
+
     item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
 
     // nothing remains - we've written all of the transform, so return identity
index f7c9f0e71b4460725f544f9716c31735f6b4446d..4b27ef8ba870c289e763bcc0481db13fd0bafc43 100644 (file)
@@ -9,6 +9,7 @@
  * Copyright (C) 1999-2002 Lauris Kaplinski
  * Copyright (C) 2000-2001 Ximian, Inc.
  * Copyright (C) 2004 John Cliff
+ * Copyright (C) 2007-2008 Johan Engelen
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -1157,6 +1158,17 @@ sp_shape_get_livepatheffectobject(SPShape *shape) {
     }
 }
 
+Inkscape::LivePathEffect::Effect *
+sp_shape_get_livepatheffect(SPShape *shape) {
+    if (!shape) return NULL;
+
+    LivePathEffectObject * lpeobj = sp_shape_get_livepatheffectobject(shape);
+    if (lpeobj)
+        return lpeobj->lpe;
+    else
+        return NULL;
+}
+
 /**
  * Calls any registered handlers for the update_patheffect action
  */
@@ -1219,6 +1231,14 @@ void sp_shape_set_path_effect(SPShape *shape, gchar *value)
     }
 }
 
+void sp_shape_set_path_effect(SPShape *shape, LivePathEffectObject * new_lpeobj)
+{
+    const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");
+    gchar *hrefstr = g_strdup_printf("#%s", repr_id);
+    sp_shape_set_path_effect(shape, hrefstr);
+    g_free(hrefstr);
+}
+
 void sp_shape_remove_path_effect(SPShape *shape)
 {
     Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
index eb7d01245604277276f41c9142715dc9642f8be0..ce5407ad6926a342dbe8ee5cfd1e9c758cf5bdab 100644 (file)
@@ -9,6 +9,7 @@
  *
  * Copyright (C) 1999-2002 Lauris Kaplinski
  * Copyright (C) 2000-2001 Ximian, Inc.
+ * Copyright (C) 2008 Johan Engelen
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -32,6 +33,7 @@ struct LivePathEffectObject;
 namespace Inkscape{ 
 namespace LivePathEffect{
     class LPEObjectReference;
+    class Effect;
 };
 };
 
@@ -78,10 +80,12 @@ NR::Matrix sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *
 bool sp_shape_marker_required(SPShape const *shape, int const m, NArtBpath *bp);
 
 LivePathEffectObject * sp_shape_get_livepatheffectobject(SPShape *shape);
+Inkscape::LivePathEffect::Effect * sp_shape_get_livepatheffect(SPShape *shape);
 void sp_shape_update_patheffect (SPShape *shape, bool write);
 void sp_shape_perform_path_effect(SPCurve *curve, SPShape *shape);
 
 void sp_shape_set_path_effect(SPShape *shape, gchar *value);
+void sp_shape_set_path_effect(SPShape *shape, LivePathEffectObject * new_lpeobj);
 void sp_shape_remove_path_effect(SPShape *shape);
 bool sp_shape_has_path_effect(SPShape *shape);
 
index 6c083bc30a1e88f4dc8e753038fc78d7e1a97427..f8e666e95a589db04ffeb087fb3f7ad6e9087f56 100644 (file)
@@ -455,6 +455,7 @@ sp_selected_path_boolop(bool_op bop, const unsigned int verb, const Glib::ustrin
     sp_item_adjust_stroke(item_source, i2root.expansion());
     sp_item_adjust_pattern(item_source, i2root);
     sp_item_adjust_gradient(item_source, i2root);
+    sp_item_adjust_livepatheffect(item_source, i2root);
 
     Inkscape::XML::Node *repr_source = SP_OBJECT_REPR(source);