diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 6924251a32f57d5402365510a2862cefcd832315..45cfe3afac6f1b104adc94ad88459062ec870821 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -1155,6 +1155,11 @@ Effect::setCurrentZoom(double cZ) current_zoom = cZ; } +/** + * Overrided function to apply transforms for example to powerstrole, jointtype or tapperstroke + */ +void Effect::transform_multiply(Geom::Affine const &postmul, bool /*set*/) {} + void Effect::setSelectedNodePoints(std::vector sNP) { diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 23c3dd3bd5a94718acd1909bbd5ad07238eb2ee2..b21633406409e8df41703556a694feaf5f89bbff 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -76,7 +76,7 @@ public: bool isNodePointSelected(Geom::Point const &nodePoint) const; virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); - + virtual void transform_multiply(Geom::Affine const &postmul, bool set); virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void doOnException(SPLPEItem const *lpeitem); virtual void doOnRemove (SPLPEItem const* lpeitem); diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index f0bffe977c15c1a14020bd30cc7ed303afe176d2..58f27f4bdb3936feae861b6467216e8dfcd244da 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -96,6 +96,11 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) } } +void LPEBendPath::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + bend_path.param_transform_multiply(postmul, false); +} + Geom::Piecewise > LPEBendPath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 146687ab9e2558b97cf772fb2ea3a2ad054f56fc..b34f2886b1031194dabaea8bd3f92996991b23fd 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -44,6 +44,8 @@ public: void resetDefaults(SPItem const* item) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) override; void addKnotHolderEntities(KnotHolder * knotholder, SPItem * item) override; diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index 325bf3935b98c3fb5808055845e0df29b9356d1c..cac8d7b367b9b666bec4250033c59d80d3ae4078 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -35,6 +35,14 @@ LPEEnvelope::LPEEnvelope(LivePathEffectObject *lpeobject) : LPEEnvelope::~LPEEnvelope() = default; +void LPEEnvelope::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + bend_path1.param_transform_multiply(postmul, false); + bend_path2.param_transform_multiply(postmul, false); + bend_path3.param_transform_multiply(postmul, false); + bend_path4.param_transform_multiply(postmul, false); +} + void LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { diff --git a/src/live_effects/lpe-envelope.h b/src/live_effects/lpe-envelope.h index c9fb8bb452b3d15a13d7fca2fddc0970a1aa2999..0cf2bfd3f05aed27a37e13ea4830a7147cd61fcf 100644 --- a/src/live_effects/lpe-envelope.h +++ b/src/live_effects/lpe-envelope.h @@ -33,6 +33,7 @@ public: ~LPEEnvelope() override; void doBeforeEffect (SPLPEItem const* lpeitem) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) override; diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index bded3433e571938d6289d3da18da3d75e209a330..7012aa528ce2369e266703283ad5fcd580cd71cf 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -47,6 +47,11 @@ LPEInterpolate::LPEInterpolate(LivePathEffectObject *lpeobject) LPEInterpolate::~LPEInterpolate() = default; +void LPEInterpolate::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + trajectory_path.param_transform_multiply(postmul, false); +} + /* * interpolate path_in[0] to path_in[1] */ diff --git a/src/live_effects/lpe-interpolate.h b/src/live_effects/lpe-interpolate.h index 4d0755034a42fe8c9c358ad91ecd6bf3be94d77d..1c943965ee06be33dbc6f0218406d8977c8e5a22 100644 --- a/src/live_effects/lpe-interpolate.h +++ b/src/live_effects/lpe-interpolate.h @@ -29,6 +29,7 @@ class LPEInterpolate : public Effect { ~LPEInterpolate() override; Geom::PathVector doEffect_path(Geom::PathVector const &path_in) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; void resetDefaults(SPItem const *item) override; diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp index 6748aae378259b6f83561d2c516247cf714b5387..1d8481130987dc956189ddafba4237ca0d101754 100644 --- a/src/live_effects/lpe-interpolate_points.cpp +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -30,7 +30,6 @@ static const Util::EnumData InterpolatorTypeData[] = { }; static const Util::EnumDataConverter InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); - LPEInterpolatePoints::LPEInterpolatePoints(LivePathEffectObject *lpeobject) : Effect(lpeobject) , interpolator_type( @@ -46,7 +45,6 @@ LPEInterpolatePoints::LPEInterpolatePoints(LivePathEffectObject *lpeobject) LPEInterpolatePoints::~LPEInterpolatePoints() = default; - Geom::PathVector LPEInterpolatePoints::doEffect_path (Geom::PathVector const & path_in) { diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index df39fe0d00861326f5bd7f3f29ed8663ae9d455d..607ba02cbe31820a2375f4de7addd5840781fefa 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -128,6 +128,15 @@ void LPEJoinType::doOnApply(SPLPEItem const* lpeitem) } } +void LPEJoinType::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs ? prefs->getBool("/options/transform/stroke", true) : true; + if (transform_stroke) { + line_width.param_transform_multiply(postmul, false); + } +} + //from LPEPowerStroke -- sets stroke color from existing fill color void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem) diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h index e84b11ad9042f432a04062e367c3e6374f88048e..5d5e20c60ea4cf95a2715502263a3d62ad4742b2 100644 --- a/src/live_effects/lpe-jointype.h +++ b/src/live_effects/lpe-jointype.h @@ -25,6 +25,7 @@ public: void doOnApply(SPLPEItem const* lpeitem) override; void doOnRemove(SPLPEItem const* lpeitem) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; private: diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index edbc2e30e32794f59e43b173e0de09215ada63ca..c991b032e24e431a25ec055d19078b4ae927496f 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -135,6 +135,12 @@ LPEOffset::get_nearest_point(Geom::PathVector pathv, Geom::Point point) const return res; } +void LPEOffset::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + offset.param_transform_multiply(postmul, true); + offset_pt = Geom::Point(Geom::infinity(), Geom::infinity()); +} + Geom::Point LPEOffset::get_default_point(Geom::PathVector pathv) const { diff --git a/src/live_effects/lpe-offset.h b/src/live_effects/lpe-offset.h index 2374791d3390e7121633d32c46432d36b28aa9a6..4c5ed49dd2a38517e0f6e48d076e44d7550b33df 100644 --- a/src/live_effects/lpe-offset.h +++ b/src/live_effects/lpe-offset.h @@ -36,6 +36,7 @@ public: ~LPEOffset() override; void doBeforeEffect (SPLPEItem const* lpeitem) override; Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; void addKnotHolderEntities(KnotHolder * knotholder, SPItem * item) override; void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec) override; void calculateOffset (Geom::PathVector const & path_in); diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 3ea000e27a8d725aea1d51123ae93c7d06702b82..2eb3fcd8aa14db52b314212a4ca2c35b465fa6fe 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -114,6 +114,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : LPEPatternAlongPath::~LPEPatternAlongPath() = default; +void LPEPatternAlongPath::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + pattern.param_transform_multiply(postmul, false); +} + void LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) { diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index 7e12561f0054b29c37b6d53d401936a4d35d3f68..690aaa99f3d1121b366d1706078c6eaabe6c6fbd 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -40,6 +40,8 @@ public: Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) override; void addKnotHolderEntities(KnotHolder * knotholder, SPItem * item) override; diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 70ca6899cec92b4d31b00bab78bf8226eee83dd6..0d80b683c62dc70d94f12fc2ca414903a662056a 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -67,6 +67,14 @@ LPEPerspectiveEnvelope::LPEPerspectiveEnvelope(LivePathEffectObject *lpeobject) LPEPerspectiveEnvelope::~LPEPerspectiveEnvelope() = default; +void LPEPerspectiveEnvelope::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + up_left_point.param_transform_multiply(postmul, false); + up_right_point.param_transform_multiply(postmul, false); + down_left_point.param_transform_multiply(postmul, false); + down_right_point.param_transform_multiply(postmul, false); +} + bool pointInTriangle(Geom::Point const &p, std::vector points) { if (points.size() != 3) { diff --git a/src/live_effects/lpe-perspective-envelope.h b/src/live_effects/lpe-perspective-envelope.h index 5c00cded2aa11ae0a484f7d62577eaa95d1fe3f9..7aa32ecc1a2756fc6fd0fc5a7f19cfc5dee240e2 100644 --- a/src/live_effects/lpe-perspective-envelope.h +++ b/src/live_effects/lpe-perspective-envelope.h @@ -37,6 +37,8 @@ public: virtual Geom::Point projectPoint(Geom::Point p); + void transform_multiply(Geom::Affine const &postmul, bool set) override; + virtual Geom::Point projectPoint(Geom::Point p, double m[][3]); virtual Geom::Point pointAtRatio(Geom::Coord ratio,Geom::Point A, Geom::Point B); diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index a23e4525c637d86912dba5e42cc385b8bca7f951..2cceb6ff332a9fe266570b5811cc164430c898cd 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -766,6 +766,11 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in) return path_out; } +void LPEPowerStroke::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + offset_points.param_transform_multiply(postmul, false); +} + void LPEPowerStroke::doAfterEffect(SPLPEItem const *lpeitem) { if (pathvector_before_effect[0].size() == pathvector_after_effect[0].size()) { diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h index caf84b2dbe55923b7542a50292f3ee71c81fe0d4..0f1fa67c11ab1b30a83abdcb933d2d89017363a3 100644 --- a/src/live_effects/lpe-powerstroke.h +++ b/src/live_effects/lpe-powerstroke.h @@ -43,6 +43,7 @@ public: void doOnApply(SPLPEItem const* lpeitem) override; void doOnRemove(SPLPEItem const* lpeitem) override; void doAfterEffect(SPLPEItem const *lpeitem) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; void applyStyle(SPLPEItem *lpeitem); // methods called by path-manipulator upon edits void adjustForNewPath(Geom::PathVector const & path_in); diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 4c3be0bbc4ec158db880f175b408094393097e85..2db2e017d30157eeeb15bfba125d24e5cd4e96ef 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -94,6 +94,15 @@ LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : // from LPEPowerStroke -- sets fill if stroke color because we will // be converting to a fill to make the new join. +void LPETaperStroke::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs ? prefs->getBool("/options/transform/stroke", true) : true; + if (transform_stroke) { + line_width.param_transform_multiply(postmul, false); + } +} + void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem) { if (SP_IS_SHAPE(lpeitem)) { diff --git a/src/live_effects/lpe-taperstroke.h b/src/live_effects/lpe-taperstroke.h index a5e18646ee0a6b8cdf96490e559aa13661643fb6..6b4900c1da21d7cac2234c772883e64d70661a9d 100644 --- a/src/live_effects/lpe-taperstroke.h +++ b/src/live_effects/lpe-taperstroke.h @@ -36,6 +36,7 @@ public: Geom::PathVector doEffect_path (Geom::PathVector const& path_in) override; Geom::PathVector doEffect_simplePath(Geom::PathVector const& path_in); + void transform_multiply(Geom::Affine const &postmul, bool set) override; void addKnotHolderEntities(KnotHolder * knotholder, SPItem * item) override; diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 92bee07d0bbbb9927ae1de0e7fb4b8b2fa80f931..a426018625c28e820ee7074b76bc4f40051e02a1 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -117,6 +117,12 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) end.param_set_default(); } +void LPETransform2Pts::transform_multiply(Geom::Affine const &postmul, bool /*set*/) +{ + start.param_transform_multiply(postmul, false); + end.param_transform_multiply(postmul, false); +} + void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 31655054eef5b0ce009f3b335f60cd352a3dd2e1..d72e69a6c38a328e95cf9265378b327fadab147a 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -34,6 +34,8 @@ public: void doBeforeEffect (SPLPEItem const* lpeitem) override; + void transform_multiply(Geom::Affine const &postmul, bool set) override; + Gtk::Widget *newWidget() override; void updateIndex(); diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 0b0153ec1a6bfa9d6473c0a993b5ac5a4882a49f..e0afc4ef78bf06e9bfb32b86a15674dfcabeefbd 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -108,6 +108,17 @@ void ScalarParam::param_update_default(const gchar *default_value) } } +void ScalarParam::param_transform_multiply(Geom::Affine const &postmul, bool set) +{ + // Check if proportional stroke-width scaling is on + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs ? prefs->getBool("/options/transform/stroke", true) : true; + if (transform_stroke || set) { + param_set_value(value * postmul.descrim()); + write_to_SVG(); + } +} + void ScalarParam::param_set_value(gdouble val) { value = val; diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 5050829ad57d386d6155b3c651ebd556f69fc426..b73a5fe830865f4b2aeadeab2bbcb6d08730254f 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -80,7 +80,7 @@ class Parameter { virtual void param_editOncanvas(SPItem * /*item*/, SPDesktop * /*dt*/){}; virtual void param_setup_nodepath(Inkscape::NodePath::Path * /*np*/){}; - virtual void param_transform_multiply(Geom::Affine const & /*postmul*/, bool /*set*/){}; + virtual void param_transform_multiply(Geom::Affine const & /*postmul*/, bool set){}; Glib::ustring param_key; Glib::ustring param_tooltip; @@ -109,6 +109,7 @@ class ScalarParam : public Parameter { bool param_readSVGValue(const gchar *strvalue) override; Glib::ustring param_getSVGValue() const override; Glib::ustring param_getDefaultSVGValue() const override; + void param_transform_multiply(Geom::Affine const &postmul, bool set) override; void param_set_default() override; void param_update_default(gdouble default_value); diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h index 0128cfef9a7af711944774d5d86ec9cb4cb2cc52..12ddb1bb0974ade1be6d3075ac4a1381b8e9b262 100644 --- a/src/live_effects/parameter/path.h +++ b/src/live_effects/parameter/path.h @@ -51,7 +51,7 @@ public: void param_setup_nodepath(Inkscape::NodePath::Path *np) override; void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec) override; - void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/) override; + void param_transform_multiply(Geom::Affine const &postmul, bool set) override; void setFromOriginalD(bool from_original_d){ _from_original_d = from_original_d; }; sigc::signal signal_path_pasted; diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 48fa5fc05f227842f30bb5461b91ed5f0caa706d..26e0e32c81fe889844801049d3cbc622cd2994fb 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -49,7 +49,7 @@ public: void param_update_default(Geom::Point default_point); void param_update_default(const gchar * default_point) override; - void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/) override; + void param_transform_multiply(Geom::Affine const & /*postmul*/, bool set) override; void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index 9a8b21457cbef9229a77a07319b9026f60e1bd2b..bb0a81239bb4aea029326a1330c346dcf091a04b 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -54,7 +54,7 @@ void PowerStrokePointArrayParam::param_transform_multiply(Geom::Affine const &po point_it != e; ++point_it) { // scale each width knot with the average scaling in X and Y - Geom::Coord const A = (*point_it)[Geom::Y] * ((postmul.expansionX() + postmul.expansionY()) / 2); + Geom::Coord const A = (*point_it)[Geom::Y] * postmul.descrim(); result.emplace_back((*point_it)[Geom::X], A); } param_set_and_write_new_value(result); diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 8e18d71aecca0bed8f7a619fb15e7b2fa9780c9c..14203334b11b9afd56cafa9e250160105c18604e 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -500,7 +500,8 @@ void SPGenericEllipse::set_shape() Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) { - if (hasPathEffectRecursive() && pathEffectsEnabled()) { + notifyTransform(xform); + if (pathEffectsEnabled() && !optimizeTransforms()) { return xform; } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index d8c392ffb7aa1b8c72e4e3b2c68b7c3a7060b1bd..f4f103e76f899ac724f731cd5d3145264b24e0cd 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -20,29 +20,29 @@ #include "bad-uri-exception.h" +#include "attributes.h" +#include "desktop.h" +#include "display/curve.h" +#include "inkscape.h" #include "live_effects/effect.h" -#include "live_effects/lpe-path_length.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" -#include "live_effects/lpe-mirror_symmetry.h" +#include "live_effects/lpe-bool.h" +#include "live_effects/lpe-clone-original.h" #include "live_effects/lpe-copy_rotate.h" - -#include "sp-path.h" -#include "sp-root.h" -#include "sp-item-group.h" -#include "attributes.h" -#include "uri.h" +#include "live_effects/lpe-lattice2.h" +#include "live_effects/lpe-measure-segments.h" +#include "live_effects/lpe-mirror_symmetry.h" #include "message-stack.h" -#include "inkscape.h" -#include "desktop.h" -#include "ui/shape-editor.h" #include "path-chemistry.h" -#include "sp-ellipse.h" -#include "display/curve.h" -#include "svg/svg.h" #include "sp-clippath.h" +#include "sp-ellipse.h" +#include "sp-item-group.h" #include "sp-mask.h" +#include "sp-path.h" #include "sp-rect.h" +#include "sp-root.h" +#include "svg/svg.h" +#include "ui/shape-editor.h" +#include "uri.h" /* LPEItem base class */ @@ -281,6 +281,63 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: return true; } +/** + * returns true when LPE write unoptimiced + */ +bool SPLPEItem::optimizeTransforms() +{ + bool ret = true; + if (dynamic_cast(this)) { + return false; + } + std::list::iterator i; + for (i = this->path_effect_list->begin(); i != this->path_effect_list->end(); ++i) { + Inkscape::LivePathEffect::LPEObjectReference *lperef = (*i); + if (!lperef) { + continue; + } + if (!ret) { + break; + } + LivePathEffectObject *lpeobj = lperef->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + if (dynamic_cast(lpe) || + dynamic_cast(lpe) || + dynamic_cast(lpe) || + dynamic_cast(lpe) || + dynamic_cast(lpe) || + dynamic_cast(lpe)) { + ret = false; + } + } + } + } + return ret; +} + +/** + * notify tranbsform applied to a LPE + */ +void SPLPEItem::notifyTransform(Geom::Affine const &postmul) +{ + std::list::iterator i; + for (i = this->path_effect_list->begin(); i != this->path_effect_list->end(); ++i) { + Inkscape::LivePathEffect::LPEObjectReference *lperef = (*i); + if (!lperef) { + continue; + } + LivePathEffectObject *lpeobj = lperef->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + lpe->transform_multiply(postmul, false); + } + } + } +} + // CPPIFY: make pure virtual void SPLPEItem::update_patheffect(bool /*write*/) { //throw; diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index b055b5e97ba0afda22677d605c74264a5e06f046..907b1f89fee3315ba8f789229667b9ba5044c9f1 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -70,7 +70,8 @@ public: Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override; virtual void update_patheffect(bool write); - + bool optimizeTransforms(); + void notifyTransform(Geom::Affine const &postmul); bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 58a823543e744f51946c6e5cbec88da15d43d681..f18463ade8a831e5eb50c608cfe8c18eb73804f5 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -343,12 +343,16 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { if (!_curve) { // 0 nodes, nothing to transform return Geom::identity(); } - if (hasPathEffectRecursive() && pathEffectsEnabled()) { + + if (pathEffectsEnabled() && !optimizeTransforms()) { return transform; } - - _curve->transform(transform); - + if (hasPathEffectRecursive() && pathEffectsEnabled()) { + _curve_before_lpe->transform(transform); + } else { + _curve->transform(transform); + } + notifyTransform(transform); // Adjust stroke this->adjust_stroke(transform.descrim()); diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index 6bb9a6027a2dce92868e227ab05c5be5a9c7927b..901168fbbf2f6ff0a89cb2d091f135ad44f8932c 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -378,9 +378,10 @@ void SPRect::update_patheffect(bool write) { } Geom::Affine SPRect::set_transform(Geom::Affine const& xform) { - if (hasPathEffectRecursive() && pathEffectsEnabled()) { + if (pathEffectsEnabled() && !optimizeTransforms()) { return xform; } + notifyTransform(xform); /* Calculate rect start in parent coords. */ Geom::Point pos(Geom::Point(this->x.computed, this->y.computed) * xform); diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index 25a637a391ec501bd567f6d64b5751a760207c68..69f85a555cf84e7ee06a0838b46705d0ae4bfdbe 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -409,14 +409,14 @@ void SPSpiral::snappoints(std::vector &p, Inkscape */ Geom::Affine SPSpiral::set_transform(Geom::Affine const &xform) { - if (hasPathEffectRecursive() && pathEffectsEnabled()) { + if (pathEffectsEnabled() && !optimizeTransforms()) { return xform; } // Only set transform with proportional scaling if (!xform.withoutTranslation().isUniformScale()) { return xform; } - + notifyTransform(xform); /* Calculate spiral start in parent coords. */ Geom::Point pos( Geom::Point(this->cx, this->cy) * xform ); diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 59f30b6fad3536605b05e7e0c03ba5683a677382..51bd02c1fea77fa250cd41de24e267794ef80130 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -491,13 +491,15 @@ void SPStar::snappoints(std::vector &p, Inkscape:: Geom::Affine SPStar::set_transform(Geom::Affine const &xform) { bool opt_trans = (randomized == 0); - if (hasPathEffectRecursive() && pathEffectsEnabled()) { + if (pathEffectsEnabled() && !optimizeTransforms()) { return xform; } // Only set transform with proportional scaling if (!xform.withoutTranslation().isUniformScale()) { return xform; } + notifyTransform(xform); + /* Calculate star start in parent coords. */ Geom::Point pos( this->center * xform );