From ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbc Mon Sep 17 00:00:00 2001 From: johanengelen Date: Wed, 2 Jan 2008 18:10:43 +0000 Subject: [PATCH] + Fix bug #179840, forking of LPEs + Groundwork for fixing transforming LPE bugs. TODO: implement the actual transformation of LPE parameters. --- src/box3d.cpp | 3 +++ src/live_effects/effect.cpp | 16 ++++++++++++++-- src/live_effects/effect.h | 12 +++++++++--- src/live_effects/lpeobject.cpp | 31 ++++++++++++++++++++++++++----- src/live_effects/lpeobject.h | 14 ++++---------- src/selection-chemistry.cpp | 18 +++++++++++++----- src/sp-item.cpp | 25 +++++++++++++++++++++++++ src/sp-item.h | 1 + src/sp-path.cpp | 3 +++ src/sp-shape.cpp | 20 ++++++++++++++++++++ src/sp-shape.h | 4 ++++ src/splivarot.cpp | 1 + 12 files changed, 123 insertions(+), 25 deletions(-) diff --git a/src/box3d.cpp b/src/box3d.cpp index 3397cd6b0..0add188e7 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -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); } ***/ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 117fbcdb7..21c1d6719 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -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" @@ -16,17 +18,19 @@ #include "document.h" #include -#include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/parameter/parameter.h" #include #include "live_effects/n-art-bpath-2geom.h" #include "display/curve.h" -#include <2geom/sbasis-to-bezier.h> #include #include +#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::iterator it = param_vector.begin(); it != param_vector.end(); it++) { + Parameter * param = *it; + } +} } /* namespace LivePathEffect */ diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 964bcd12b..4c1e4e0eb 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -4,7 +4,7 @@ /* * Inkscape::LivePathEffect * -* Copyright (C) Johan Engelen 2007 +* Copyright (C) Johan Engelen 2007-2008 * * 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); diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp index 6066f11f3..bcb01463a 100644 --- a/src/live_effects/lpeobject.cpp +++ b/src/live_effects/lpeobject.cpp @@ -1,21 +1,23 @@ #define INKSCAPE_LIVEPATHEFFECT_OBJECT_CPP /* - * Copyright (C) Johan Engelen 2007 + * Copyright (C) Johan Engelen 2007-2008 * * 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 +#include "document-private.h" -#include "live_effects/lpeobject.h" -#include "live_effects/effect.h" +#include //#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: diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h index c2e9fafa7..bc13e596a 100644 --- a/src/live_effects/lpeobject.h +++ b/src/live_effects/lpeobject.h @@ -4,7 +4,7 @@ /* * Inkscape::LivePathEffect * -* Copyright (C) Johan Engelen 2007 +* Copyright (C) Johan Engelen 2007-2008 * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -16,19 +16,13 @@ #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. diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 040e5f839..56ef7b01f 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -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(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) ) { diff --git a/src/sp-item.cpp b/src/sp-item.cpp index f064b246c..90765fc94 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -58,12 +58,16 @@ #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 diff --git a/src/sp-item.h b/src/sp-item.h index b3867f146..9bbaefef1 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -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); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index b9e94d72e..d97bbddb9 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -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 diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index f7c9f0e71..4b27ef8ba 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -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); diff --git a/src/sp-shape.h b/src/sp-shape.h index eb7d01245..ce5407ad6 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -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); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 6c083bc30..f8e666e95 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -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); -- 2.30.2