1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /** \file
3  * LPE knot effect implementation, see lpe-knot.cpp.
4  */
5 /* Authors:
6  *   Jean-Francois Barraud <jf.barraud@gmail.com>
7  *   Johan Engelen <j.b.c.engelen@alumnus.utwente.nl>
8  *
9  * Copyright (C) Authors 2007-2012
10  *
11  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12  */
13 
14 #ifndef INKSCAPE_LPE_KNOT_H
15 #define INKSCAPE_LPE_KNOT_H
16 
17 
18 #include "live_effects/effect.h"
19 #include "live_effects/lpegroupbbox.h"
20 #include "live_effects/parameter/array.h"
21 #include "live_effects/parameter/hidden.h"
22 #include "live_effects/parameter/parameter.h"
23 //#include "live_effects/parameter/path.h"
24 #include "live_effects/parameter/bool.h"
25 #include "2geom/crossing.h"
26 
27 class SPLPEItem;
28 
29 namespace Inkscape {
30 namespace LivePathEffect {
31 
32 class KnotHolderEntityCrossingSwitcher;
33 
34 // CrossingPoint, CrossingPoints:
35 //   "point oriented" storage of crossing data (needed to find crossing nearest to a click, etc...)
36 //TODO: evaluate how lpeknot-specific that is? Should something like this exist in 2geom?
37 namespace LPEKnotNS {//just in case...
38 struct CrossingPoint {
39   Geom::Point pt;
40   int sign; //+/-1 = positive or neg crossing, 0 = flat.
41   unsigned i, j;  //paths components meeting in this point.
42   unsigned ni, nj;  //this crossing is the ni-th along i, nj-th along j.
43   double ti, tj;  //time along paths.
44 };
45 
46 class CrossingPoints : public  std::vector<CrossingPoint>{
47 public:
CrossingPoints()48   CrossingPoints() : std::vector<CrossingPoint>() {}
49   CrossingPoints(Geom::CrossingSet const &cs, Geom::PathVector const &path);//for self crossings only!
50   CrossingPoints(Geom::PathVector const &paths);
51   CrossingPoints(std::vector<double> const &input);
52   std::vector<double> to_vector();
53   CrossingPoint get(unsigned const i, unsigned const ni);
54   void inherit_signs(CrossingPoints const &from_other, int default_value = 1);
55 };
56 }
57 
58 class LPEKnot : public Effect, GroupBBoxEffect {
59 public:
60   LPEKnot(LivePathEffectObject *lpeobject);
61   ~LPEKnot() override;
62 
63   void doBeforeEffect (SPLPEItem const* lpeitem) override;
64   Geom::PathVector doEffect_path (Geom::PathVector const & input_path) override;
65 
66   /* the knotholder entity classes must be declared friends */
67   friend class KnotHolderEntityCrossingSwitcher;
68   void addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) override;
69 
70 protected:
71   void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec) override;
72   Geom::PathVector supplied_path; //for knotholder business
73 
74 private:
75   void updateSwitcher();
76 
77   ScalarParam interruption_width;
78   BoolParam prop_to_stroke_width;
79   BoolParam both;
80   BoolParam inverse_width;
81   // "add_stroke_width" and "add_other_stroke_width" parameters are not used since Inkscape 1.0,
82   // but changed from bool to hidden parameter to retain backward compatibility and dont show in the UI
83   HiddenParam add_stroke_width;
84   HiddenParam add_other_stroke_width;
85   ScalarParam switcher_size;
86   ArrayParam<double> crossing_points_vector;//svg storage of crossing_points
87 
88   LPEKnotNS::CrossingPoints crossing_points;//topology representation of the knot.
89 
90   Geom::PathVector gpaths;//the collection of all the paths in the object or group.
91   std::vector<double> gstroke_widths;//the collection of all the stroke widths in the object or group.
92 
93   //UI: please, someone, help me to improve this!!
94   unsigned selectedCrossing;//the selected crossing
95   Geom::Point switcher;//where to put the "switcher" helper
96 
97   LPEKnot(const LPEKnot&) = delete;
98   LPEKnot& operator=(const LPEKnot&) = delete;
99 
100 };
101 
102 } //namespace LivePathEffect
103 } //namespace Inkscape
104 
105 #endif
106