From d88f1447c4447ef1d80789f1ade8dd8c37d6a293 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 28 Jul 2025 11:47:30 +0200 Subject: [PATCH 1/3] Add LPE option to convert Polygons, Polylines, and Lines to Paths. We don't currently support LPE's on Polygons, Polylines, and Lines, but we don't block adding LPE's to these objects, resulting in crashes. This commit blocks using the LPE dialog to add LPE's to these objects, instead, offering to convert them to Paths. Fixes #5793. --- src/ui/dialog/livepatheffect-editor.cpp | 58 +++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 27286217b1..db57130b0c 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -25,7 +25,10 @@ #include "live_effects/effect.h" #include "live_effects/lpeobject-reference.h" #include "object/sp-flowtext.h" +#include "object/sp-line.h" #include "object/sp-path.h" +#include "object/sp-polygon.h" +#include "object/sp-polyline.h" #include "object/sp-shape.h" #include "object/sp-text.h" #include "object/sp-use.h" @@ -468,11 +471,29 @@ LivePathEffectEditor::selection_info() _LPESelectionInfo.set_visible(false); if (selection && (selected = selection->singleItem()) ) { auto highlight = selected->highlight_color().toRGBA(); - if (is(selected) || is(selected)) { - _LPESelectionInfo.set_text(_("Text objects do not support Live Path Effects")); + if (is(selected) || + is(selected) || + is(selected) || + is(selected) || + is(selected)) { + + char* info = _("Text objects do not support Live Path Effects"); + char* labeltext = _("Convert text to paths"); + if (is(selected)) { + info = _("Polygon objects do not support Live Path Effects"); + labeltext = _("Convert polygon to path"); + } + else if (is(selected)) { + info = _("Polyline objects do not support Live Path Effects"); + labeltext = _("Convert polyline to path"); + } + else if (is(selected)) { + info = _("Line objects do not support Live Path Effects"); + labeltext = _("Convert line to path"); + } + _LPESelectionInfo.set_text(info); _LPESelectionInfo.set_visible(true); - Glib::ustring labeltext = _("Convert text to paths"); auto const selectbutton = Gtk::make_managed(); auto const boxc = Gtk::make_managed(); auto const lbl = Gtk::make_managed(labeltext); @@ -487,20 +508,23 @@ LivePathEffectEditor::selection_info() }); _LPEParentBox.append(*selectbutton); - Glib::ustring labeltext2 = _("Clone"); - auto const selectbutton2 = Gtk::make_managed(); - auto const boxc2 = Gtk::make_managed(); - auto const lbl2 = Gtk::make_managed(labeltext2); - auto const type2 = get_shape_image("clone", highlight); - UI::pack_start(*boxc2, *type2, false, false); - UI::pack_start(*boxc2, *lbl2, false, false); - type2->set_margin_start(4); - type2->set_margin_end(4); - selectbutton2->set_child(*boxc2); - selectbutton2->signal_clicked().connect([=](){ - selection->clone(); - }); - _LPEParentBox.append(*selectbutton2); + if (is(selected) || + is(selected)) { + Glib::ustring labeltext2 = _("Clone"); + auto const selectbutton2 = Gtk::make_managed(); + auto const boxc2 = Gtk::make_managed(); + auto const lbl2 = Gtk::make_managed(labeltext2); + auto const type2 = get_shape_image("clone", highlight); + UI::pack_start(*boxc2, *type2, false, false); + UI::pack_start(*boxc2, *lbl2, false, false); + type2->set_margin_start(4); + type2->set_margin_end(4); + selectbutton2->set_child(*boxc2); + selectbutton2->signal_clicked().connect([=](){ + selection->clone(); + }); + _LPEParentBox.append(*selectbutton2); + } } else if (!is(selected) && !is(selected)) { _LPESelectionInfo.set_text(_("Select a path, shape, clone or group")); _LPESelectionInfo.set_visible(true); -- GitLab From b2847c02588e9ab74cb589b32f98c4b7147d8b76 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 15 Aug 2025 14:41:12 +0200 Subject: [PATCH 2/3] Add function to determine if an object can have an LPE applied to it. Add more obects that can't have LPE's (3d boxes, offset paths). --- src/live_effects/effect.cpp | 24 ++++++++++++++++++++ src/live_effects/effect.h | 3 +++ src/ui/dialog/livepatheffect-editor.cpp | 29 +++++++++++++++++-------- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 758f4c554c..7685b05918 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -80,9 +80,20 @@ #include "live_effects/lpe-transform_2pts.h" #include "live_effects/lpe-vonkoch.h" #include "message-stack.h" + +#include "object/box3d.h" #include "object/sp-defs.h" +#include "object/sp-ellipse.h" // ellipse, circle, path +#include "object/sp-item-group.h" +#include "object/sp-offset.h" +#include "object/sp-path.h" +#include "object/sp-rect.h" #include "object/sp-root.h" #include "object/sp-shape.h" +#include "object/sp-spiral.h" +#include "object/sp-star.h" +#include "object/sp-use.h" + #include "path-chemistry.h" #include "ui/icon-loader.h" #include "ui/pack.h" @@ -2032,6 +2043,19 @@ Effect::providesKnotholder() const return false; } +bool can_have_lpe(SPObject const* object) { + + return ( + is(object) || + (is(object) && !is(object)) || + (is(object) && !is(object)) || + is(object) || + is(object) || + is(object) || + is(object) + ); +} + } /* namespace LivePathEffect */ } /* namespace Inkscape */ diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 5bd827a974..62f4f9ba60 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -234,9 +234,12 @@ private: bool defaultsopen; }; +bool can_have_lpe(SPObject const* object); + } //namespace LivePathEffect } //namespace Inkscape + #endif // INKSCAPE_LIVEPATHEFFECT_H /* diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index db57130b0c..7b4ddb492a 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -24,8 +24,10 @@ #include "inkscape.h" #include "live_effects/effect.h" #include "live_effects/lpeobject-reference.h" +#include "object/box3d.h" #include "object/sp-flowtext.h" #include "object/sp-line.h" +#include "object/sp-offset.h" #include "object/sp-path.h" #include "object/sp-polygon.h" #include "object/sp-polyline.h" @@ -471,15 +473,15 @@ LivePathEffectEditor::selection_info() _LPESelectionInfo.set_visible(false); if (selection && (selected = selection->singleItem()) ) { auto highlight = selected->highlight_color().toRGBA(); - if (is(selected) || - is(selected) || - is(selected) || - is(selected) || - is(selected)) { - - char* info = _("Text objects do not support Live Path Effects"); - char* labeltext = _("Convert text to paths"); - if (is(selected)) { + if (!Inkscape::LivePathEffect::can_have_lpe(selected)) { + + char* info = _("Selected object does not support Live Path Effects"); + char* labeltext = _("Convert object to path"); + if (is(selected) || is(selected)) { + info = _("Text objects do not support Live Path Effects"); + labeltext = _("Convert text to paths"); + } + else if (is(selected)) { info = _("Polygon objects do not support Live Path Effects"); labeltext = _("Convert polygon to path"); } @@ -491,6 +493,15 @@ LivePathEffectEditor::selection_info() info = _("Line objects do not support Live Path Effects"); labeltext = _("Convert line to path"); } + else if (is(selected)) { + info = _("3D Box objects do not support Live Path Effects"); + labeltext = _("Convert box to paths"); + } + else if (is(selected)) { + info = _("Offset paths do not support Live Path Effects"); + labeltext = _("Convert offset path to path"); + } + _LPESelectionInfo.set_text(info); _LPESelectionInfo.set_visible(true); -- GitLab From b9080b333e6e9e738430be50d6241902c1fec57d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 30 Oct 2025 10:34:42 +0100 Subject: [PATCH 3/3] Explicitly reject items that can't have LPE's in object tree. --- src/object/sp-item-group.cpp | 7 +++++++ src/object/sp-lpe-item.cpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 390d6b0f44..bf322ae385 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -1045,6 +1045,13 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa { std::vector const item_list = group->item_list(); for (auto sub_item : item_list) { + + if (!Inkscape::LivePathEffect::can_have_lpe(sub_item)) { + // Reject things with curves that can't have path + // effects: polygons, paths with offsets, etc. + continue; + } + auto sub_group = cast(sub_item); if (sub_group) { sp_group_perform_patheffect(sub_group, top_group, lpe, write); diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index a02a1ed9a6..6b15503e4a 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -199,6 +199,12 @@ bool SPLPEItem::isOnSymbol() const { */ bool SPLPEItem::performPathEffect(Geom::PathVector &curve, SPShape *current, bool is_clip_or_mask) { + if (!Inkscape::LivePathEffect::can_have_lpe(current)) { + // Reject things that have curves put can't have path + // effects: polygons, paths with offsets, etc. + return false; + } + if (this->hasPathEffect() && this->pathEffectsEnabled()) { PathEffectList path_effect_list(*this->path_effect_list); auto const path_effect_list_size = path_effect_list.size(); -- GitLab