From 1c6eacc9f456bd16a91336fa5644e1443bcb5aba Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 23 Dec 2019 22:33:04 +0100 Subject: [PATCH] Fix bugs https://gitlab.com/inkscape/inbox/issues/169 and https://gitlab.com/inkscape/inbox/issues/72 --- src/live_effects/effect.cpp | 5 ++ src/live_effects/effect.h | 2 +- src/live_effects/lpe-bendpath.cpp | 5 ++ src/live_effects/lpe-bendpath.h | 2 + src/live_effects/lpe-envelope.cpp | 8 ++ src/live_effects/lpe-envelope.h | 1 + src/live_effects/lpe-interpolate.cpp | 5 ++ src/live_effects/lpe-interpolate.h | 1 + src/live_effects/lpe-interpolate_points.cpp | 2 - src/live_effects/lpe-jointype.cpp | 9 ++ src/live_effects/lpe-jointype.h | 1 + src/live_effects/lpe-offset.cpp | 6 ++ src/live_effects/lpe-offset.h | 1 + src/live_effects/lpe-patternalongpath.cpp | 5 ++ src/live_effects/lpe-patternalongpath.h | 2 + src/live_effects/lpe-perspective-envelope.cpp | 8 ++ src/live_effects/lpe-perspective-envelope.h | 2 + src/live_effects/lpe-powerstroke.cpp | 5 ++ src/live_effects/lpe-powerstroke.h | 1 + src/live_effects/lpe-taperstroke.cpp | 9 ++ src/live_effects/lpe-taperstroke.h | 1 + src/live_effects/lpe-transform_2pts.cpp | 6 ++ src/live_effects/lpe-transform_2pts.h | 2 + src/live_effects/parameter/parameter.cpp | 11 +++ src/live_effects/parameter/parameter.h | 3 +- src/live_effects/parameter/path.h | 2 +- src/live_effects/parameter/point.h | 2 +- .../parameter/powerstrokepointarray.cpp | 2 +- src/object/sp-ellipse.cpp | 3 +- src/object/sp-lpe-item.cpp | 89 +++++++++++++++---- src/object/sp-lpe-item.h | 3 +- src/object/sp-path.cpp | 12 ++- src/object/sp-rect.cpp | 3 +- src/object/sp-spiral.cpp | 4 +- src/object/sp-star.cpp | 4 +- 35 files changed, 194 insertions(+), 33 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 6924251a32..45cfe3afac 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 23c3dd3bd5..b216334064 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 f0bffe977c..58f27f4bdb 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 146687ab9e..b34f2886b1 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 325bf3935b..cac8d7b367 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 c9fb8bb452..0cf2bfd3f0 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 bded3433e5..7012aa528c 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 4d0755034a..1c943965ee 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 6748aae378..1d84811309 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 df39fe0d00..607ba02cbe 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 e84b11ad90..5d5e20c60e 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 edbc2e30e3..c991b032e2 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 2374791d33..4c5ed49dd2 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 3ea000e27a..2eb3fcd8aa 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 7e12561f00..690aaa99f3 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 70ca6899ce..0d80b683c6 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 5c00cded2a..7aa32ecc1a 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 a23e4525c6..2cceb6ff33 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 caf84b2dbe..0f1fa67c11 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 4c3be0bbc4..2db2e017d3 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 a5e18646ee..6b4900c1da 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 92bee07d0b..a426018625 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 31655054ee..d72e69a6c3 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 0b0153ec1a..e0afc4ef78 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 5050829ad5..b73a5fe830 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 0128cfef9a..12ddb1bb09 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 48fa5fc05f..26e0e32c81 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 9a8b21457c..bb0a81239b 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 8e18d71aec..14203334b1 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 d8c392ffb7..f4f103e76f 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 b055b5e97b..907b1f89fe 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 58a823543e..f18463ade8 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 6bb9a6027a..901168fbbf 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 25a637a391..69f85a555c 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 59f30b6fad..51bd02c1fe 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 ); -- GitLab