From f53c232a2cf287dc161e7492013141ef04b5253b Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Fri, 15 Feb 2019 12:57:01 +0100 Subject: Add descriptions and fixes to show disabled and rename dash to dashed stoke LPE --- src/live_effects/CMakeLists.txt | 4 +- src/live_effects/effect-enum.h | 2 +- src/live_effects/effect.cpp | 36 ++--- src/live_effects/lpe-dash-stroke.cpp | 284 --------------------------------- src/live_effects/lpe-dash-stroke.h | 36 ----- src/live_effects/lpe-dashed-stroke.cpp | 284 +++++++++++++++++++++++++++++++++ src/live_effects/lpe-dashed-stroke.h | 36 +++++ src/ui/dialog/livepatheffect-add.cpp | 17 +- 8 files changed, 355 insertions(+), 344 deletions(-) delete mode 100644 src/live_effects/lpe-dash-stroke.cpp delete mode 100644 src/live_effects/lpe-dash-stroke.h create mode 100644 src/live_effects/lpe-dashed-stroke.cpp create mode 100644 src/live_effects/lpe-dashed-stroke.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index a26a7f413..17a9d46ad 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -14,7 +14,7 @@ set(live_effects_SRC lpe-constructgrid.cpp lpe-copy_rotate.cpp lpe-curvestitch.cpp - lpe-dash-stroke.cpp + lpe-dashed-stroke.cpp lpe-dynastroke.cpp lpe-ellipse_5pts.cpp lpe-embrodery-stitch.cpp @@ -107,7 +107,7 @@ set(live_effects_SRC lpe-constructgrid.h lpe-copy_rotate.h lpe-curvestitch.h - lpe-dash-stroke.h + lpe-dashed-stroke.h lpe-dynastroke.h lpe-ellipse_5pts.h lpe-embrodery-stitch.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index c82471439..3ac25bd18 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -57,7 +57,7 @@ enum EffectType { POWERMASK, PTS2ELLIPSE, OFFSET, - DASH_STROKE, + DASHED_STROKE, DOEFFECTSTACK_TEST, ANGLE_BISECTOR, CIRCLE_WITH_RADIUS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 960831a5e..67a760d6f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -344,7 +344,7 @@ const EnumEffectData LPETypeData[] = { , "perspective-envelope" //key wrong key with "-" retain because historic , "perspective-envelope" //icon , "Perspective/Envelope" //untranslated name - , N_("Perspective or envelope a item by 4 corner ponts") //description + , N_("Transform the object to fit into a shape with four corners, either by stretching it or creating the illusion of a 3D-perspective.") //description , true //on_path , true //on_shape , true //on_group @@ -358,7 +358,7 @@ const EnumEffectData LPETypeData[] = { , "interpolate_points" //key , "interpolate-points" //icon , "Interpolate points" //untranslated name - , N_("Interpolate points creating diferent conxions between: straight, smooth...") //description + , N_("Connect the nodes of the path (e.g. corresponding to data points) by different types of lines.") //description , true //on_path , true //on_shape , true //on_group @@ -386,7 +386,7 @@ const EnumEffectData LPETypeData[] = { , "show_handles" //key , "show-handles" //icon , "Show handles" //untranslated name - , N_("Show handles of element, perfect to temporsty show path handles and nodes") //description + , N_("Draw the handles and nodes of paths (replaces the original styling with a black stroke).") //description , true //on_path , true //on_shape , true //on_group @@ -400,7 +400,7 @@ const EnumEffectData LPETypeData[] = { , "roughen" //key , "roughen" //icon , "Roughen" //untranslated name - , N_("Roughen a item so looks a slight more natural or handcrafted or totaly deformed.") //description + , N_("Roughen an object by adding and randomly shifting new nodes.") //description , true //on_path , true //on_shape , true //on_group @@ -414,7 +414,7 @@ const EnumEffectData LPETypeData[] = { , "bspline" //key , "bspline" //icon , "BSpline" //untranslated name - , N_("Add BSpline bsplie to a path, this usualy is added on path creation and not directly from here") //description + , N_("Create a BSpline that molds into the path's corners. This effect is usually used directly on the canvas with the BSpline mode of the drawing tools.") //description , true //on_path , false //on_shape , false //on_group @@ -428,7 +428,7 @@ const EnumEffectData LPETypeData[] = { , "join_type" //key , "join-type" //icon , "Join type" //untranslated name - , N_("Join type convert a path stroke to a real fill path, act lice conbert stroke to path but non destructive. Also have the extrapolated arc option for line joins") //description + , N_("Select among various join types for a path's corner nodes (mitre, rounded, extrapolated arc, ...)") //description , true //on_path , true //on_shape , true //on_group @@ -485,7 +485,7 @@ const EnumEffectData LPETypeData[] = { , "attach_path" //key , "attach-path" //icon , "Attach path" //untranslated name - , N_("Join starting and/or ending paths to current path") //description + , N_("Glue the current path's ends to a specific position on one or two other paths.") //description , true //on_path , true //on_shape , true //on_group @@ -499,7 +499,7 @@ const EnumEffectData LPETypeData[] = { , "fill_between_strokes" //key , "fill-between-strokes" //icon , "Fill between strokes" //untranslated name - , N_("Create a updateable fill between 2 diferent paths") //description + , N_("Turn the path into a fill between two other open paths (e.g. between two paths with PowerStroke applied to them)") //description , true //on_path , true //on_shape , true //on_group @@ -513,7 +513,7 @@ const EnumEffectData LPETypeData[] = { , "fill_between_many" //key , "fill-between-many" //icon , "Fill between many" //untranslated name - , N_("Create a updateable fill between many diferent paths") //description + , N_("Turn the path into a fill between multiple other open paths (e.g. between paths with PowerStroke applied to them)") //description , true //on_path , true //on_shape , true //on_group @@ -527,7 +527,7 @@ const EnumEffectData LPETypeData[] = { , "ellipse_5pts" //key , "ellipse-5pts" //icon , "Ellipse by 5 points" //untranslated name - , N_("Create a ellipse by a path with 5 points") //description + , N_("Create an ellipse from 5 nodes on its circumference.") //description , true //on_path , true //on_shape , true //on_group @@ -556,7 +556,7 @@ const EnumEffectData LPETypeData[] = { , "measure_segments" //key , "measure-segments" //icon , "Measure Segments" //untranslated name - , N_("Measure segments, add lines, units, projections...") //description + , N_("Add dimensioning for distances between nodes, optionally with projection and many other configuration options.") //description , true //on_path , true //on_shape , false //on_group @@ -654,7 +654,7 @@ const EnumEffectData LPETypeData[] = { , "offset" //key , "offset" //icon , "Offset" //untranslated name - , N_("Offset a item also with line joins cusp") //description + , N_("Offset the path, optionally keeping cusp corners cusp.") //description , true //on_path , true //on_shape , true //on_group @@ -663,12 +663,12 @@ const EnumEffectData LPETypeData[] = { , false //experimental }, { - DASH_STROKE - , N_("Dash Stroke") //label - , "dash_stroke" //key - , "dash-stroke" //icon - , "Dash Stroke" //untranslated name - , N_("Dash Stroke that fit exatly") //description + DASHED_STROKE + , N_("Dashed Stroke") //label + , "dashed_stroke" //key + , "dashed-stroke" //icon + , "Dashed Stroke" //untranslated name + , N_("Add a dashed stroke whose dashes end exactly on a node, optionally with the same number of dashes per path segment.") //description , true //on_path , true //on_shape , true //on_group diff --git a/src/live_effects/lpe-dash-stroke.cpp b/src/live_effects/lpe-dash-stroke.cpp deleted file mode 100644 index 1972b583c..000000000 --- a/src/live_effects/lpe-dash-stroke.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ -#include "live_effects/lpe-dash-stroke.h" -#include "2geom/pathvector.h" -#include "2geom/path.h" -#include "helper/geom.h" - -// TODO due to internal breakage in glibmm headers, this must be last: -#include - -namespace Inkscape { -namespace LivePathEffect { - -LPEDashStroke::LPEDashStroke(LivePathEffectObject *lpeobject) - : Effect(lpeobject), - numberdashes(_("Number of dashes"), _("Number of dashes"), "numberdashes", &wr, this, 3), - holefactor(_("Hole factor"), _("Hole factor"), "holefactor", &wr, this, 0.0), - splitsegments(_("Use segments"), _("Use segments"), "splitsegments", &wr, this, true), - halfextreme(_("Half start/end"), _("Start and end of each segment has half size"), "halfextreme", &wr, this, true), - unifysegment(_("Unify dashes"), _("Approximately unify the dashes length using the minimal length segment"), "unifysegment", &wr, this, true), - message(_("Info Box"), _("Important messages"), "message", &wr, this, _("Add \"Fill Between Many LPE\" to add fill.")) -{ - registerParameter(&numberdashes); - registerParameter(&holefactor); - registerParameter(&splitsegments); - registerParameter(&halfextreme); - registerParameter(&unifysegment); - registerParameter(&message); - numberdashes.param_set_range(2, 999999999); - numberdashes.param_set_increments(1, 1); - numberdashes.param_set_digits(0); - holefactor.param_set_range(-0.99999, 0.99999); - holefactor.param_set_increments(0.01, 0.01); - holefactor.param_set_digits(5); - message.param_set_min_height(30); -} - -LPEDashStroke::~LPEDashStroke() = default; - -void -LPEDashStroke::doBeforeEffect (SPLPEItem const* lpeitem){ -} - -///Calculate the time in curve_in with a real time of A -//TODO: find a better place to it -double -LPEDashStroke::timeAtLength(double const A, Geom::Path const &segment) -{ - if ( A == 0 || segment[0].isDegenerate()) { - return 0; - } - double t = 1; - t = timeAtLength(A, segment.toPwSb()); - return t; -} - -///Calculate the time in curve_in with a real time of A -//TODO: find a better place to it -double -LPEDashStroke::timeAtLength(double const A, Geom::Piecewise > pwd2) -{ - if ( A == 0 || pwd2.size() == 0) { - return 0; - } - - double t = pwd2.size(); - std::vector t_roots = roots(Geom::arcLengthSb(pwd2) - A); - if (!t_roots.empty()) { - t = t_roots[0]; - } - return t; -} - -Geom::PathVector -LPEDashStroke::doEffect_path(Geom::PathVector const & path_in){ - Geom::PathVector const pv = pathv_to_linear_and_cubic_beziers(path_in); - Geom::PathVector result; - for (const auto & path_it : pv) { - if (path_it.empty()) { - continue; - } - Geom::Path::const_iterator curve_it1 = path_it.begin(); - Geom::Path::const_iterator curve_it2 = ++(path_it.begin()); - Geom::Path::const_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(); - } - } - size_t numberdashes_fixed = numberdashes; - if(!splitsegments) { - numberdashes_fixed++; - } - size_t numberholes = numberdashes_fixed - 1; - size_t ammount = numberdashes_fixed + numberholes; - if (halfextreme) { - ammount--; - } - double base = 1/(double)ammount; - double globaldash = base * numberdashes_fixed * (1 + holefactor); - if (halfextreme) { - globaldash = base * (numberdashes_fixed - 1) * (1 + holefactor); - } - double globalhole = 1-globaldash; - double dashpercent = globaldash/numberdashes_fixed; - if (halfextreme) { - dashpercent = globaldash/(numberdashes_fixed -1); - } - double holepercent = globalhole/numberholes; - double dashsize_fixed = 0; - double holesize_fixed = 0; - Geom::Piecewise > pwd2 = path_it.toPwSb(); - double lenght_pwd2 = length (pwd2); - double minlenght = lenght_pwd2; - if(unifysegment) { - while (curve_it1 != curve_endit) { - double lenght_segment = (*curve_it1).length(); - if (lenght_segment < minlenght) { - minlenght = lenght_segment; - dashsize_fixed = (*curve_it1).length() * dashpercent; - holesize_fixed = (*curve_it1).length() * holepercent; - } - ++curve_it1; - ++curve_it2; - } - curve_it1 = path_it.begin(); - curve_it2 = ++(path_it.begin()); - curve_endit = path_it.end_default(); - } - size_t p_index = 0; - size_t start_index = result.size(); - if(splitsegments) { - while (curve_it1 != curve_endit) { - Geom::Path segment = path_it.portion(p_index, p_index + 1); - if(unifysegment) { - double integral; - double fractional = modf((*curve_it1).length()/(dashsize_fixed + holesize_fixed), &integral); - numberdashes_fixed = (size_t)integral + 1; - numberholes = numberdashes_fixed - 1; - ammount = numberdashes_fixed + numberholes; - if (halfextreme) { - ammount--; - } - base = 1/(double)ammount; - globaldash = base * numberdashes_fixed * (1 + holefactor); - if (halfextreme) { - globaldash = base * (numberdashes_fixed - 1) * (1 + holefactor); - } - globalhole = 1-globaldash; - dashpercent = globaldash/numberdashes_fixed; - if (halfextreme) { - dashpercent = globaldash/(numberdashes_fixed -1); - } - holepercent = globalhole/numberholes; - } - double dashsize = (*curve_it1).length() * dashpercent; - double holesize = (*curve_it1).length() * holepercent; - if ((*curve_it1).isLineSegment()) { - if (result.size() && Geom::are_near(segment.initialPoint(),result[result.size()-1].finalPoint())) { - result[result.size()-1].setFinal(segment.initialPoint()); - if (halfextreme) { - result[result.size()-1].append(segment.portion(0.0, dashpercent/2.0)); - } else { - result[result.size()-1].append(segment.portion(0.0, dashpercent)); - } - } else { - if (halfextreme) { - result.push_back(segment.portion(0.0, dashpercent/2.0)); - } else { - result.push_back(segment.portion(0.0, dashpercent)); - } - } - - double start = dashpercent + holepercent; - if (halfextreme) { - start = (dashpercent/2.0) + holepercent; - } - while (start < 1) { - if (start + dashpercent > 1) { - result.push_back(segment.portion(start, 1)); - } else { - result.push_back(segment.portion(start, start + dashpercent)); - } - start += dashpercent + holepercent; - } - } else if (!(*curve_it1).isLineSegment()) { - double start = 0.0; - double end = 0.0; - if (halfextreme) { - end = timeAtLength(dashsize/2.0,segment); - } else { - end = timeAtLength(dashsize,segment); - } - if (result.size() && Geom::are_near(segment.initialPoint(),result[result.size()-1].finalPoint())) { - result[result.size()-1].setFinal(segment.initialPoint()); - result[result.size()-1].append(segment.portion(start, end)); - } else { - result.push_back(segment.portion(start, end)); - } - double startsize = dashsize + holesize; - if (halfextreme) { - startsize = (dashsize/2.0) + holesize; - } - double endsize = startsize + dashsize; - start = timeAtLength(startsize,segment); - end = timeAtLength(endsize,segment); - while (start < 1 && start > 0) { - result.push_back(segment.portion(start, end)); - startsize = endsize + holesize; - endsize = startsize + dashsize; - start = timeAtLength(startsize,segment); - end = timeAtLength(endsize,segment); - } - } - if (curve_it2 == curve_endit) { - if (path_it.closed()) { - Geom::Path end = result[result.size()-1]; - end.setFinal(result[start_index].initialPoint()); - end.append(result[start_index]); - result[start_index] = end; - } - } - p_index ++; - ++curve_it1; - ++curve_it2; - } - } else { - double start = 0.0; - double end = 0.0; - double dashsize = lenght_pwd2 * dashpercent; - double holesize = lenght_pwd2 * holepercent; - if (halfextreme) { - end = timeAtLength(dashsize/2.0,pwd2); - } else { - end = timeAtLength(dashsize,pwd2); - } - result.push_back(path_it.portion(start, end)); - double startsize = dashsize + holesize; - if (halfextreme) { - startsize = (dashsize/2.0) + holesize; - } - double endsize = startsize + dashsize; - start = timeAtLength(startsize,pwd2); - end = timeAtLength(endsize,pwd2); - while (start < path_it.size() && start > 0) { - result.push_back(path_it.portion(start, end)); - startsize = endsize + holesize; - endsize = startsize + dashsize; - start = timeAtLength(startsize,pwd2); - end = timeAtLength(endsize,pwd2); - } - if (path_it.closed()) { - Geom::Path end = result[result.size()-1]; - end.setFinal(result[start_index].initialPoint()); - end.append(result[start_index]); - result[start_index] = end; - } - } - } - return result; -} - -}; //namespace LivePathEffect -}; /* namespace Inkscape */ - -/* - 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 : diff --git a/src/live_effects/lpe-dash-stroke.h b/src/live_effects/lpe-dash-stroke.h deleted file mode 100644 index 3bc64d0cd..000000000 --- a/src/live_effects/lpe-dash-stroke.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INKSCAPE_LPE_DASH_STROKE_H -#define INKSCAPE_LPE_DASH_STROKE_H - -/* - * Inkscape::LPEDashStroke - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "live_effects/effect.h" -#include "live_effects/parameter/message.h" - -namespace Inkscape { -namespace LivePathEffect { - -class LPEDashStroke : public Effect { -public: - LPEDashStroke(LivePathEffectObject *lpeobject); - ~LPEDashStroke() override; - void doBeforeEffect (SPLPEItem const* lpeitem) override; - Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; - double timeAtLength(double const A, Geom::Path const &segment); - double timeAtLength(double const A, Geom::Piecewise > pwd2); -private: - ScalarParam numberdashes; - ScalarParam holefactor; - BoolParam splitsegments; - BoolParam halfextreme; - BoolParam unifysegment; - MessageParam message; -}; - -} //namespace LivePathEffect -} //namespace Inkscape -#endif diff --git a/src/live_effects/lpe-dashed-stroke.cpp b/src/live_effects/lpe-dashed-stroke.cpp new file mode 100644 index 000000000..b29b50b43 --- /dev/null +++ b/src/live_effects/lpe-dashed-stroke.cpp @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ +#include "live_effects/lpe-dash-stroke.h" +#include "2geom/pathvector.h" +#include "2geom/path.h" +#include "helper/geom.h" + +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +namespace Inkscape { +namespace LivePathEffect { + +LPEDashedStroke::LPEDashedStroke(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + numberdashes(_("Number of dashes"), _("Number of dashes"), "numberdashes", &wr, this, 3), + holefactor(_("Hole factor"), _("Hole factor"), "holefactor", &wr, this, 0.0), + splitsegments(_("Use segments"), _("Use segments"), "splitsegments", &wr, this, true), + halfextreme(_("Half start/end"), _("Start and end of each segment has half size"), "halfextreme", &wr, this, true), + unifysegment(_("Unify dashes"), _("Approximately unify the dashes length using the minimal length segment"), "unifysegment", &wr, this, true), + message(_("Info Box"), _("Important messages"), "message", &wr, this, _("Add \"Fill Between Many LPE\" to add fill.")) +{ + registerParameter(&numberdashes); + registerParameter(&holefactor); + registerParameter(&splitsegments); + registerParameter(&halfextreme); + registerParameter(&unifysegment); + registerParameter(&message); + numberdashes.param_set_range(2, 999999999); + numberdashes.param_set_increments(1, 1); + numberdashes.param_set_digits(0); + holefactor.param_set_range(-0.99999, 0.99999); + holefactor.param_set_increments(0.01, 0.01); + holefactor.param_set_digits(5); + message.param_set_min_height(30); +} + +LPEDashedStroke::~LPEDashedStroke() = default; + +void +LPEDashedStroke::doBeforeEffect (SPLPEItem const* lpeitem){ +} + +///Calculate the time in curve_in with a real time of A +//TODO: find a better place to it +double +LPEDashedStroke::timeAtLength(double const A, Geom::Path const &segment) +{ + if ( A == 0 || segment[0].isDegenerate()) { + return 0; + } + double t = 1; + t = timeAtLength(A, segment.toPwSb()); + return t; +} + +///Calculate the time in curve_in with a real time of A +//TODO: find a better place to it +double +LPEDashedStroke::timeAtLength(double const A, Geom::Piecewise > pwd2) +{ + if ( A == 0 || pwd2.size() == 0) { + return 0; + } + + double t = pwd2.size(); + std::vector t_roots = roots(Geom::arcLengthSb(pwd2) - A); + if (!t_roots.empty()) { + t = t_roots[0]; + } + return t; +} + +Geom::PathVector +LPEDashedStroke::doEffect_path(Geom::PathVector const & path_in){ + Geom::PathVector const pv = pathv_to_linear_and_cubic_beziers(path_in); + Geom::PathVector result; + for (const auto & path_it : pv) { + if (path_it.empty()) { + continue; + } + Geom::Path::const_iterator curve_it1 = path_it.begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it.begin()); + Geom::Path::const_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(); + } + } + size_t numberdashes_fixed = numberdashes; + if(!splitsegments) { + numberdashes_fixed++; + } + size_t numberholes = numberdashes_fixed - 1; + size_t ammount = numberdashes_fixed + numberholes; + if (halfextreme) { + ammount--; + } + double base = 1/(double)ammount; + double globaldash = base * numberdashes_fixed * (1 + holefactor); + if (halfextreme) { + globaldash = base * (numberdashes_fixed - 1) * (1 + holefactor); + } + double globalhole = 1-globaldash; + double dashpercent = globaldash/numberdashes_fixed; + if (halfextreme) { + dashpercent = globaldash/(numberdashes_fixed -1); + } + double holepercent = globalhole/numberholes; + double dashsize_fixed = 0; + double holesize_fixed = 0; + Geom::Piecewise > pwd2 = path_it.toPwSb(); + double lenght_pwd2 = length (pwd2); + double minlenght = lenght_pwd2; + if(unifysegment) { + while (curve_it1 != curve_endit) { + double lenght_segment = (*curve_it1).length(); + if (lenght_segment < minlenght) { + minlenght = lenght_segment; + dashsize_fixed = (*curve_it1).length() * dashpercent; + holesize_fixed = (*curve_it1).length() * holepercent; + } + ++curve_it1; + ++curve_it2; + } + curve_it1 = path_it.begin(); + curve_it2 = ++(path_it.begin()); + curve_endit = path_it.end_default(); + } + size_t p_index = 0; + size_t start_index = result.size(); + if(splitsegments) { + while (curve_it1 != curve_endit) { + Geom::Path segment = path_it.portion(p_index, p_index + 1); + if(unifysegment) { + double integral; + double fractional = modf((*curve_it1).length()/(dashsize_fixed + holesize_fixed), &integral); + numberdashes_fixed = (size_t)integral + 1; + numberholes = numberdashes_fixed - 1; + ammount = numberdashes_fixed + numberholes; + if (halfextreme) { + ammount--; + } + base = 1/(double)ammount; + globaldash = base * numberdashes_fixed * (1 + holefactor); + if (halfextreme) { + globaldash = base * (numberdashes_fixed - 1) * (1 + holefactor); + } + globalhole = 1-globaldash; + dashpercent = globaldash/numberdashes_fixed; + if (halfextreme) { + dashpercent = globaldash/(numberdashes_fixed -1); + } + holepercent = globalhole/numberholes; + } + double dashsize = (*curve_it1).length() * dashpercent; + double holesize = (*curve_it1).length() * holepercent; + if ((*curve_it1).isLineSegment()) { + if (result.size() && Geom::are_near(segment.initialPoint(),result[result.size()-1].finalPoint())) { + result[result.size()-1].setFinal(segment.initialPoint()); + if (halfextreme) { + result[result.size()-1].append(segment.portion(0.0, dashpercent/2.0)); + } else { + result[result.size()-1].append(segment.portion(0.0, dashpercent)); + } + } else { + if (halfextreme) { + result.push_back(segment.portion(0.0, dashpercent/2.0)); + } else { + result.push_back(segment.portion(0.0, dashpercent)); + } + } + + double start = dashpercent + holepercent; + if (halfextreme) { + start = (dashpercent/2.0) + holepercent; + } + while (start < 1) { + if (start + dashpercent > 1) { + result.push_back(segment.portion(start, 1)); + } else { + result.push_back(segment.portion(start, start + dashpercent)); + } + start += dashpercent + holepercent; + } + } else if (!(*curve_it1).isLineSegment()) { + double start = 0.0; + double end = 0.0; + if (halfextreme) { + end = timeAtLength(dashsize/2.0,segment); + } else { + end = timeAtLength(dashsize,segment); + } + if (result.size() && Geom::are_near(segment.initialPoint(),result[result.size()-1].finalPoint())) { + result[result.size()-1].setFinal(segment.initialPoint()); + result[result.size()-1].append(segment.portion(start, end)); + } else { + result.push_back(segment.portion(start, end)); + } + double startsize = dashsize + holesize; + if (halfextreme) { + startsize = (dashsize/2.0) + holesize; + } + double endsize = startsize + dashsize; + start = timeAtLength(startsize,segment); + end = timeAtLength(endsize,segment); + while (start < 1 && start > 0) { + result.push_back(segment.portion(start, end)); + startsize = endsize + holesize; + endsize = startsize + dashsize; + start = timeAtLength(startsize,segment); + end = timeAtLength(endsize,segment); + } + } + if (curve_it2 == curve_endit) { + if (path_it.closed()) { + Geom::Path end = result[result.size()-1]; + end.setFinal(result[start_index].initialPoint()); + end.append(result[start_index]); + result[start_index] = end; + } + } + p_index ++; + ++curve_it1; + ++curve_it2; + } + } else { + double start = 0.0; + double end = 0.0; + double dashsize = lenght_pwd2 * dashpercent; + double holesize = lenght_pwd2 * holepercent; + if (halfextreme) { + end = timeAtLength(dashsize/2.0,pwd2); + } else { + end = timeAtLength(dashsize,pwd2); + } + result.push_back(path_it.portion(start, end)); + double startsize = dashsize + holesize; + if (halfextreme) { + startsize = (dashsize/2.0) + holesize; + } + double endsize = startsize + dashsize; + start = timeAtLength(startsize,pwd2); + end = timeAtLength(endsize,pwd2); + while (start < path_it.size() && start > 0) { + result.push_back(path_it.portion(start, end)); + startsize = endsize + holesize; + endsize = startsize + dashsize; + start = timeAtLength(startsize,pwd2); + end = timeAtLength(endsize,pwd2); + } + if (path_it.closed()) { + Geom::Path end = result[result.size()-1]; + end.setFinal(result[start_index].initialPoint()); + end.append(result[start_index]); + result[start_index] = end; + } + } + } + return result; +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + 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 : diff --git a/src/live_effects/lpe-dashed-stroke.h b/src/live_effects/lpe-dashed-stroke.h new file mode 100644 index 000000000..3ee18d2c2 --- /dev/null +++ b/src/live_effects/lpe-dashed-stroke.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INKSCAPE_LPE_DASHED_STROKE_H +#define INKSCAPE_LPE_DASHED_STROKE_H + +/* + * Inkscape::LPEDashedStroke + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/message.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEDashedStroke : public Effect { +public: + LPEDashedStroke(LivePathEffectObject *lpeobject); + ~LPEDashedStroke() override; + void doBeforeEffect (SPLPEItem const* lpeitem) override; + Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; + double timeAtLength(double const A, Geom::Path const &segment); + double timeAtLength(double const A, Geom::Piecewise > pwd2); +private: + ScalarParam numberdashes; + ScalarParam holefactor; + BoolParam splitsegments; + BoolParam halfextreme; + BoolParam unifysegment; + MessageParam message; +}; + +} //namespace LivePathEffect +} //namespace Inkscape +#endif diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index 3cd2ae4ee..47474aa00 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -159,6 +159,7 @@ LivePathEffectAdd::LivePathEffectAdd() LPESelectorEffect->signal_enter_notify_event().connect(sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(LPESelectorEffect->gobj()))); LPESelectorEffect->signal_leave_notify_event().connect(sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(LPESelectorEffect->gobj()))); _LPESelectorFlowBox->insert(*LPESelectorEffect, i); + LPESelectorEffect->get_parent()->get_style_context()->add_class(("LPEIndex" + Glib::ustring::format(i)).c_str()); } _visiblelpe = _LPESelectorFlowBox->get_children().size(); _LPEInfo->set_visible(false); @@ -168,7 +169,6 @@ LivePathEffectAdd::LivePathEffectAdd() _LPESelectorEffectInfoEventBox->signal_button_press_event().connect(sigc::mem_fun(*this, &LivePathEffectAdd::hide_pop_description)); _LPESelectorEffectInfoEventBox->signal_enter_notify_event().connect(sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::mouseover), GTK_WIDGET(_LPESelectorEffectInfoEventBox->gobj()))); _LPESelectorEffectInfoEventBox->signal_leave_notify_event().connect(sigc::bind(sigc::mem_fun(*this, &LivePathEffectAdd::mouseout), GTK_WIDGET(_LPESelectorEffectInfoEventBox->gobj()))); - _LPESelectorFlowBox->set_filter_func(sigc::mem_fun(*this, &LivePathEffectAdd::on_filter)); _LPEExperimental->property_active().signal_changed().connect(sigc::mem_fun(*this, &LivePathEffectAdd::reload_effect_list)); _LPEDialogSelector->show_all_children(); } @@ -308,7 +308,16 @@ bool LivePathEffectAdd::apply(GdkEventButton* evt, Glib::RefPtr bu bool LivePathEffectAdd::on_filter(Gtk::FlowBoxChild *child) { - const LivePathEffect::EnumEffectData *data = &converter.data(child->get_index()); + std::vector classes = child->get_style_context()->list_classes(); + int pos = 0; + for (auto childclass:classes) { + size_t s = childclass.find("LPEIndex", 0); + if (s != -1) { + childclass = childclass.erase(0,8); + pos = std::stoi(childclass); + } + } + const LivePathEffect::EnumEffectData *data = &converter.data(pos); bool disable = false; if (_item_type == "group" && !converter.get_on_group(data->id)) { disable = true; @@ -515,11 +524,13 @@ void LivePathEffectAdd::show(SPDesktop *desktop) if( width == width_2 && height == height_2 ){ Gtk::Window *window = desktop->getToplevel(); window->get_size (width, height); + std::cout << "dsdgsgdsdgsgdgdsgsdgsdgds" << std::endl; dial._LPEDialogSelector->resize(std::min( width - 300, 1440), std::min( height - 300, 900)); } dial._applied=false; dial._LPESelectorFlowBox->unset_sort_func(); - dial._LPESelectorFlowBox->invalidate_filter(); + dial._LPESelectorFlowBox->unset_filter_func(); + dial._LPESelectorFlowBox->set_filter_func(sigc::mem_fun(dial, &LivePathEffectAdd::on_filter)); dial._LPESelectorFlowBox->set_sort_func(sigc::mem_fun(dial, &LivePathEffectAdd::on_sort)); Glib::RefPtr< Gtk::Adjustment > vadjust = dial._LPEScrolled->get_vadjustment(); vadjust->set_value(vadjust->get_lower()); -- cgit v1.2.3