From a9db40f1af1528b95f817fec51d236319875ec93 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 5 Jul 2025 13:14:58 +0200 Subject: [PATCH] Start of markers knockout LPE --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 19 ++++ src/live_effects/lpe-slice-markers.cpp | 117 +++++++++++++++++++++++++ src/live_effects/lpe-slice-markers.h | 47 ++++++++++ 5 files changed, 186 insertions(+) create mode 100644 src/live_effects/lpe-slice-markers.cpp create mode 100644 src/live_effects/lpe-slice-markers.h diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 89703479cc..ca7130d9a0 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -59,6 +59,7 @@ set(live_effects_SRC lpe-test-doEffect-stack.cpp lpe-text_label.cpp lpe-tiling.cpp + lpe-slice-markers.cpp lpe-transform_2pts.cpp lpegroupbbox.cpp lpeobject-reference.cpp @@ -157,6 +158,7 @@ set(live_effects_SRC lpe-test-doEffect-stack.h lpe-text_label.h lpe-tiling.h + lpe-slice-markers.h lpe-transform_2pts.h lpe-vonkoch.h lpegroupbbox.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 0ae38eb414..22ee815cc0 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -59,6 +59,7 @@ enum EffectType { BOOL_OP, SLICE, TILING, + SLICE_MARKERS, // PUT NEW LPE BEFORE EXPERIMENTAL IN THE SAME ORDER AS IN effect.cpp // Visible Experimental LPE's ANGLE_BISECTOR, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 758f4c554c..9c655b6a16 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -77,6 +77,7 @@ #include "live_effects/lpe-test-doEffect-stack.h" #include "live_effects/lpe-text_label.h" #include "live_effects/lpe-tiling.h" +#include "live_effects/lpe-slice-markers.h" #include "live_effects/lpe-transform_2pts.h" #include "live_effects/lpe-vonkoch.h" #include "message-stack.h" @@ -680,6 +681,21 @@ const EnumEffectData LPETypeData[] = { false ,//on_text false ,//experimental }, + /* 1.5 */ + { + SLICE_MARKERS, + NC_("path effect", "Slice markers") ,//label + "slice_markers" ,//key + "slice-markerss" ,//icon + N_("Slice markers") ,//description + LPECategory::Convert ,//category + true ,//on_path + true ,//on_shape + false ,//on_group + false ,//on_image + false ,//on_text + false ,//experimental + }, // VISIBLE experimental LPEs { ANGLE_BISECTOR, @@ -1102,6 +1118,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case TILING: neweffect = static_cast ( new LPETiling(lpeobj) ); break; + case SLICE_MARKERS: + neweffect = static_cast ( new LPESliceMarkers(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = nullptr; diff --git a/src/live_effects/lpe-slice-markers.cpp b/src/live_effects/lpe-slice-markers.cpp new file mode 100644 index 0000000000..e649feb6c4 --- /dev/null +++ b/src/live_effects/lpe-slice-markers.cpp @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Author(s): + * Jabiertxo Arraiza Cenoz + * + * Copyright (C) 2014 Author(s) + * + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "lpe-slice-markers.h" +#include "helper/geom.h" +#include "object/sp-shape.h" +#include "object/sp-marker.h" + +namespace Inkscape::LivePathEffect { + +LPESliceMarkers::LPESliceMarkers(LivePathEffectObject *lpeobject) + : Effect(lpeobject) +{ + _provides_knotholder_entities = false; + _provides_path_adjustment = true; +} + +void LPESliceMarkers::doOnApply(SPLPEItem const *lpeItem) +{ + SPLPEItem *splpeitem = const_cast(lpeItem); + auto shape = cast(splpeitem); + if (!shape) { + g_warning("LPE Slice Nodes can only be applied to shapes (not groups)."); + SPLPEItem *item = const_cast(lpeItem); + item->removeCurrentPathEffect(false); + } +} + +Gtk::Widget *LPESliceMarkers::newWidget() +{ + return Gtk::make_managed(Gtk::Orientation::VERTICAL); +} + +void LPESliceMarkers::doBeforeEffect(SPLPEItem const *lpeItem) +{ + auto shape = cast(lpeItem); + if(shape && shape->hasMarkers()) { + pos = {0,0,0}; + if(auto const mstart = shape->_marker[SP_MARKER_LOC_START]) { + if (mstart->refY == 0 /* drop unhandled */ ) { + pos[0] = mstart->refX; + } + } + /* if(auto mmid = shape->_marker[SP_MARKER_LOC_MID]) { + pos[1] = mmid->refX; + } */ + if(auto const mend = shape->_marker[SP_MARKER_LOC_END]) { + pos[1] = mend->refX; + } + } +} + +Geom::PathVector +LPESliceMarkers::doEffect_path(Geom::PathVector const &path_in) +{ + Geom::PathVector original_pathv = pathv_to_linear_and_cubic_beziers(path_in); + Geom::PathVector res; + for (auto & path_it : original_pathv) { + Geom::PathVector _tmp; + if (path_it.empty()) { + continue; + } + Geom::Path::iterator curve_it1 = path_it.begin(); + Geom::Path::iterator curve_it2 = ++(path_it.begin()); + Geom::Path::iterator curve_endit = path_it.end_default(); + if (path_it.closed()) { + const Geom::Curve &closingline = path_it.back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it.end_open(); + } + } + Geom::Path tmp; + if (path_it.size() == 1) { + tmp.append(path_it.initialCurve().portion(pos[0], 1-pos[1])); + } else { + while (curve_it1 != curve_endit) { + if (*curve_it1 == path_it.initialCurve()){ + tmp.append(curve_it1->portion(pos[0],1)); + } else { + tmp.append(*curve_it1);//->portion(pos[1], 1-pos[1])); + } + } + tmp.append(curve_it1->portion(0, 1-pos[1])); + } + res.push_back(tmp); + } + + return res; +} + + +} // namespace Inkscape::LivePathEffect + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offset:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-slice-markers.h b/src/live_effects/lpe-slice-markers.h new file mode 100644 index 0000000000..60dc16b8f8 --- /dev/null +++ b/src/live_effects/lpe-slice-markers.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Author(s): + * Jabiertxo Arraiza Cenoz + * + * Copyright (C) 2014 Author(s) + * + * Jabiertxof:Thanks to all people help me + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_LPE_SLICE_MARKERS_H +#define INKSCAPE_LPE_SLICE_MARKERS_H + +#include "live_effects/effect.h" + +namespace Inkscape::LivePathEffect { + +class LPESliceMarkers : public Effect { +public: + LPESliceMarkers(LivePathEffectObject *lpeobject); + void doBeforeEffect(SPLPEItem const *lpeItem) override; + void doOnApply(SPLPEItem const *lpeItem) override; + Geom::PathVector doEffect_path(Geom::PathVector const &path_in) override; + Gtk::Widget *newWidget() override; + std::vector pos = {0,0,0}; +private: + LPESliceMarkers(const LPESliceMarkers &); + LPESliceMarkers &operator=(const LPESliceMarkers &); + +}; + +} // namespace Inkscape::LivePathEffect + +#endif // INKSCAPE_SLICE_MARKERS_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- GitLab