Code

Refactoring the snapping API (making it easier to maintain and understand for the...
authorDiederik van Lierop <mailat-signdiedenrezidotnl>
Sat, 9 Jan 2010 21:14:38 +0000 (22:14 +0100)
committerDiederik van Lierop <mailat-signdiedenrezidotnl>
Sat, 9 Jan 2010 21:14:38 +0000 (22:14 +0100)
39 files changed:
src/context-fns.cpp
src/display/snap-indicator.cpp
src/display/snap-indicator.h
src/draw-context.cpp
src/gradient-drag.cpp
src/line-snapper.cpp
src/line-snapper.h
src/nodepath.cpp
src/object-snapper.cpp
src/object-snapper.h
src/satisfied-guide-cns.cpp
src/satisfied-guide-cns.h
src/selection.cpp
src/selection.h
src/seltrans.cpp
src/seltrans.h
src/snap-candidate.h [new file with mode: 0644]
src/snap.cpp
src/snap.h
src/snapped-point.cpp
src/snapped-point.h
src/snapper.cpp
src/snapper.h
src/sp-ellipse.cpp
src/sp-flowtext.cpp
src/sp-image.cpp
src/sp-item-group.cpp
src/sp-item-notify-moveto.cpp
src/sp-item-rm-unsatisfied-cns.cpp
src/sp-item-update-cns.cpp
src/sp-item.cpp
src/sp-item.h
src/sp-offset.cpp
src/sp-rect.cpp
src/sp-shape.cpp
src/sp-spiral.cpp
src/sp-star.cpp
src/sp-text.cpp
src/sp-use.cpp

index 8e4b6384cfdcfca51e35df41b8c43b8df4b58a8d..67a7d6baadcd3e050c8a05ad68bae5363a98c4ad 100644 (file)
@@ -131,12 +131,12 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
             Inkscape::SnappedPoint s[2];
 
             /* Try to snap p[0] (the opposite corner) along the constraint vector */
-            s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE,
-                                     Inkscape::Snapper::ConstraintLine(p[0] - p[1]), false);
+            s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p[0], Inkscape::SNAPSOURCE_HANDLE),
+                                     Inkscape::Snapper::ConstraintLine(p[0] - p[1]));
 
             /* Try to snap p[1] (the dragged corner) along the constraint vector */
-            s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
-                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]), false);
+            s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_HANDLE),
+                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
 
             /* Choose the best snap and update points accordingly */
             if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
@@ -156,8 +156,8 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
 
             /* Our origin is the opposite corner.  Snap the drag point along the constraint vector */
             p[0] = center;
-            snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
-                                          Inkscape::Snapper::ConstraintLine(p[1] - p[0]), false);
+            snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_HANDLE),
+                                          Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
             if (snappoint.getSnapped()) {
                 p[1] = snappoint.getPoint();
             }
@@ -174,8 +174,8 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
 
         Inkscape::SnappedPoint s[2];
 
-        s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE);
-        s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE);
+        s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p[0], Inkscape::SNAPSOURCE_HANDLE));
+        s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_HANDLE));
 
         if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
             if (s[0].getSnapped()) {
@@ -196,7 +196,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
         /* There's no constraint on the corner point, so just snap it to anything */
         p[0] = center;
         p[1] = pt;
-        snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(pt), Inkscape::SNAPSOURCE_HANDLE);
+        snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_HANDLE));
         if (snappoint.getSnapped()) {
             p[1] = snappoint.getPoint();
         }
index 7df9b31ff8c2c9e84a858fa3f9bd8dabc1a3a351..84bc1709bea9d0ea7c01f962b7180674c055889f 100644 (file)
@@ -40,7 +40,7 @@ SnapIndicator::~SnapIndicator()
 }
 
 void
-SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p)
+SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p)
 {
     remove_snaptarget(); //only display one snaptarget at a time
 
@@ -264,7 +264,7 @@ SnapIndicator::remove_snaptarget()
 }
 
 void
-SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p)
+SnapIndicator::set_new_snapsource(Inkscape::SnapCandidatePoint const &p)
 {
     remove_snapsource();
 
@@ -284,7 +284,7 @@ SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p)
                                                         "shape", SP_KNOT_SHAPE_CIRCLE,
                                                         NULL );
 
-        SP_CTRL(canvasitem)->moveto(p.first);
+        SP_CTRL(canvasitem)->moveto(p.getPoint());
         _snapsource = _desktop->add_temporary_canvasitem(canvasitem, 1000);
     }
 }
index 4391ca6d6043a4d05d190ee595ffd6d3b4060bb9..d896042a203018c94c3fe173d3cc6b750912e2a0 100644 (file)
@@ -26,10 +26,10 @@ public:
     SnapIndicator(SPDesktop *desktop);
     virtual ~SnapIndicator();
 
-    void set_new_snaptarget(Inkscape::SnappedPoint const p);
+    void set_new_snaptarget(Inkscape::SnappedPoint const &p);
     void remove_snaptarget();
 
-    void set_new_snapsource(std::pair<Geom::Point, int> const p);
+    void set_new_snapsource(Inkscape::SnapCandidatePoint const &p);
     void remove_snapsource();
 
 protected:
index de9a7c7e509f3e3b8b2a1663e2467a46e1aca476..3334c82de7ef5c23407cfcbac5e2b54a8b4877d6 100644 (file)
@@ -511,9 +511,7 @@ void spdc_endpoint_snap_rotation(SPEventContext const *const ec, Geom::Point &p,
             /* Snap it along best vector */
             SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
             m.setup(SP_EVENT_CONTEXT_DESKTOP(ec));
-            Geom::Point pt2g = to_2geom(p);
-            m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE, Inkscape::Snapper::ConstraintLine(best), false);
-            p = from_2geom(pt2g);
+            m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::Snapper::ConstraintLine(best));
         }
     }
 }
index 98ea35b4eab548ef2561bee2abccd45ef06e4dcf..726f4d78add1f7fdd6e655a9db05bf49d081bcd2 100644 (file)
@@ -596,7 +596,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
 
     m.setup(desktop);
     if (!((state & GDK_SHIFT_MASK) || (state & GDK_CONTROL_MASK))) {
-        Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_OTHER, p, Inkscape::SNAPSOURCE_HANDLE);
+        Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_OTHER, Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_HANDLE));
         if (s.getSnapped()) {
             p = s.getPoint();
             sp_knot_moveto (knot, p);
@@ -659,7 +659,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
                 }
                 if (snap_vector) {
                     Inkscape::Snapper::ConstraintLine cl(dr_snap, p + *snap_vector - dr_snap);
-                    Inkscape::SnappedPoint s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_OTHER, p + *snap_vector, Inkscape::SNAPSOURCE_HANDLE, cl);
+                    Inkscape::SnappedPoint s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_OTHER, Inkscape::SnapCandidatePoint(p + *snap_vector, Inkscape::SNAPSOURCE_HANDLE), cl);
                     if (s.getSnapped()) {
                         s.setTransformation(s.getPoint() - p);
                         sc.points.push_back(s);
@@ -672,7 +672,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
             }
         }
 
-        Inkscape::SnappedPoint bsp = m.findBestSnap(p, Inkscape::SNAPSOURCE_HANDLE, sc, true); // snap indicator will be displayed if needed
+        Inkscape::SnappedPoint bsp = m.findBestSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_HANDLE), sc, true); // snap indicator will be displayed if needed
 
         if (bsp.getSnapped()) {
             p += bsp.getTransformation();
index 31fa07515293bc77a2bdb2069eb2dc822e0d6292..696f92405b3f9d40d0e49820c18cac6a44949abf 100644 (file)
@@ -23,21 +23,17 @@ Inkscape::LineSnapper::LineSnapper(SnapManager *sm, Geom::Coord const d) : Snapp
 
 void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
                                                     Inkscape::SnapPreferences::PointType const &t,
-                                                    Geom::Point const &p,
-                                                    SnapSourceType const &source_type,
-                                                    long source_num,
+                                                    Inkscape::SnapCandidatePoint const &p,
                                                     Geom::OptRect const &/*bbox_to_snap*/,
                                                     std::vector<SPItem const *> const */*it*/,
-                                                    std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const
+                                                    std::vector<Inkscape::SnapCandidatePoint> */*unselected_nodes*/) const
 {
     if (!(_snap_enabled && _snapmanager->snapprefs.getSnapFrom(t)) ) {
         return;
     }
 
     /* Get the lines that we will try to snap to */
-    const LineList lines = _getSnapLines(p);
-
-    // std::cout << "snap point " << p << " to: " << std::endl;
+    const LineList lines = _getSnapLines(p.getPoint());
 
     for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) {
         Geom::Point const p1 = i->second; // point at guide/grid line
@@ -45,17 +41,17 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
         // std::cout << "  line through " << i->second << " with normal " << i->first;
         g_assert(i->first != Geom::Point(0,0)); // we cannot project on an linesegment of zero length
 
-        Geom::Point const p_proj = Geom::projection(p, Geom::Line(p1, p2));
-        Geom::Coord const dist = Geom::L2(p_proj - p);
+        Geom::Point const p_proj = Geom::projection(p.getPoint(), Geom::Line(p1, p2));
+        Geom::Coord const dist = Geom::L2(p_proj - p.getPoint());
         //Store any line that's within snapping range
         if (dist < getSnapperTolerance()) {
-            _addSnappedLine(sc, p_proj, dist, source_type, source_num, i->first, i->second);
+            _addSnappedLine(sc, p_proj, dist, p.getSourceType(), p.getSourceNum(), i->first, i->second);
             // For any line that's within range, we will also look at it's "point on line" p1. For guides
             // this point coincides with its origin; for grids this is of no use, but we cannot
             // discern between grids and guides here
-            Geom::Coord const dist_p1 = Geom::L2(p1 - p);
+            Geom::Coord const dist_p1 = Geom::L2(p1 - p.getPoint());
             if (dist_p1 < getSnapperTolerance()) {
-                _addSnappedLinesOrigin(sc, p1, dist_p1, source_type, source_num);
+                _addSnappedLinesOrigin(sc, p1, dist_p1, p.getSourceType(), p.getSourceNum());
                 // Only relevant for guides; grids don't have an origin per line
                 // Therefore _addSnappedLinesOrigin() will only be implemented for guides
             }
@@ -67,9 +63,7 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
 
 void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
                                                Inkscape::SnapPreferences::PointType const &t,
-                                               Geom::Point const &p,
-                                               SnapSourceType const &source_type,
-                                               long source_num,
+                                               Inkscape::SnapCandidatePoint const &p,
                                                Geom::OptRect const &/*bbox_to_snap*/,
                                                ConstraintLine const &c,
                                                std::vector<SPItem const *> const */*it*/) const
@@ -80,12 +74,12 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
     }
 
     /* Get the lines that we will try to snap to */
-    const LineList lines = _getSnapLines(p);
+    const LineList lines = _getSnapLines(p.getPoint());
 
     for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) {
         if (Geom::L2(c.getDirection()) > 0) { // Can't do a constrained snap without a constraint
             // constraint line
-            Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : p;
+            Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : p.getPoint();
             Geom::Line line1(point_on_line, point_on_line + c.getDirection());
 
             // grid/guide line
@@ -106,19 +100,19 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
 
             if (inters) {
                 Geom::Point t = line1.pointAt((*inters).ta);
-                const Geom::Coord dist = Geom::L2(t - p);
+                const Geom::Coord dist = Geom::L2(t - p.getPoint());
                 if (dist < getSnapperTolerance()) {
                     // When doing a constrained snap, we're already at an intersection.
                     // This snappoint is therefore fully constrained, so there's no need
                     // to look for additional intersections; just return the snapped point
                     // and forget about the line
-                    _addSnappedPoint(sc, t, dist, source_type, source_num);
+                    _addSnappedPoint(sc, t, dist, p.getSourceType(), p.getSourceNum());
                     // For any line that's within range, we will also look at it's "point on line" p1. For guides
                     // this point coincides with its origin; for grids this is of no use, but we cannot
                     // discern between grids and guides here
-                    Geom::Coord const dist_p1 = Geom::L2(p1 - p);
+                    Geom::Coord const dist_p1 = Geom::L2(p1 - p.getPoint());
                     if (dist_p1 < getSnapperTolerance()) {
-                        _addSnappedLinesOrigin(sc, p1, dist_p1, source_type, source_num);
+                        _addSnappedLinesOrigin(sc, p1, dist_p1, p.getSourceType(), p.getSourceNum());
                         // Only relevant for guides; grids don't have an origin per line
                         // Therefore _addSnappedLinesOrigin() will only be implemented for guides
                     }
index af36b8330126cf5331e1b942122118b9f6008aa2..5845e081efd915d7c784743e20c96ea3c4d0976f 100644 (file)
@@ -18,6 +18,7 @@
 
 namespace Inkscape
 {
+class SnapCandidatePoint;
 
 class LineSnapper : public Snapper
 {
@@ -26,18 +27,14 @@ public:
 
   void freeSnap(SnappedConstraints &sc,
                    Inkscape::SnapPreferences::PointType const &t,
-                   Geom::Point const &p,
-                   SnapSourceType const &source_type,
-                   long source_num,
+                   Inkscape::SnapCandidatePoint const &p,
                    Geom::OptRect const &bbox_to_snap,
                    std::vector<SPItem const *> const *it,
-                   std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
+                   std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes) const;
 
   void constrainedSnap(SnappedConstraints &sc,
                           Inkscape::SnapPreferences::PointType const &t,
-                          Geom::Point const &p,
-                          SnapSourceType const &source_type,
-                          long source_num,
+                          Inkscape::SnapCandidatePoint const &p,
                           Geom::OptRect const &bbox_to_snap,
                           ConstraintLine const &c,
                           std::vector<SPItem const *> const *it) const;
index 1881dd72be73b6e2961041fd530782496f8470d7..069b3c5bcb87ad64283c2c7577e605712e0b8913 100644 (file)
@@ -1367,13 +1367,13 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
          * must provide that information. */
 
         // Build a list of the unselected nodes to which the snapper should snap
-        std::vector<std::pair<Geom::Point, int> > unselected_nodes;
+        std::vector<Inkscape::SnapCandidatePoint> unselected_nodes;
         for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
             Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
             for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
                 Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
                 if (!node->selected) {
-                    unselected_nodes.push_back(std::make_pair(to_2geom(node->pos), node->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPTARGET_NODE_SMOOTH : Inkscape::SNAPTARGET_NODE_CUSP));
+                    unselected_nodes.push_back(Inkscape::SnapCandidatePoint(node->pos, Inkscape::SNAPSOURCE_UNDEFINED, node->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPTARGET_NODE_SMOOTH : Inkscape::SNAPTARGET_NODE_CUSP));
                 }
             }
         }
@@ -1409,9 +1409,9 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
                 if (constrained) {
                     Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
                     dedicated_constraint.setPoint(n->pos);
-                    s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type, dedicated_constraint, false);
+                    s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(n->pos + delta, source_type), dedicated_constraint);
                 } else {
-                    s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type);
+                    s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(n->pos + delta, source_type));
                 }
 
                 if (s.getSnapped()) {
@@ -3975,16 +3975,16 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
                 p = n->pos + (scal / linelen) * ndelta;
             }
             if ((state & GDK_SHIFT_MASK) == 0) {
-                s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type, Inkscape::Snapper::ConstraintLine(p, ndelta), false);
+                s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p, source_type), Inkscape::Snapper::ConstraintLine(p, ndelta));
             }
         } else {
             if ((state & GDK_SHIFT_MASK) == 0) {
-                s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
+                s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p, source_type));
             }
         }
     } else {
         if ((state & GDK_SHIFT_MASK) == 0) {
-            s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
+            s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(p, source_type));
         }
     }
 
index 4a70e27063aaa369f6ea1fd348f1d3785d04fc66..11685e25ce6714b1d73d476a00233dd001289999 100644 (file)
 #include "helper/geom-curves.h"
 #include "desktop.h"
 
-Inkscape::SnapCandidate::SnapCandidate(SPItem* item, bool clip_or_mask, Geom::Matrix additional_affine)
-    : item(item), clip_or_mask(clip_or_mask), additional_affine(additional_affine)
-{
-}
-
-Inkscape::SnapCandidate::~SnapCandidate()
-{
-}
-
 Inkscape::ObjectSnapper::ObjectSnapper(SnapManager *sm, Geom::Coord const d)
     : Snapper(sm, d)
 {
-    _candidates = new std::vector<SnapCandidate>;
-    _points_to_snap_to = new std::vector<std::pair<Geom::Point, int> >;
-    _paths_to_snap_to = new std::vector<std::pair<Geom::PathVector*, SnapTargetType> >;
+    _candidates = new std::vector<SnapCandidateItem>;
+    _points_to_snap_to = new std::vector<Inkscape::SnapCandidatePoint>;
+    _paths_to_snap_to = new std::vector<Inkscape::SnapCandidatePath >;
 }
 
 Inkscape::ObjectSnapper::~ObjectSnapper()
@@ -158,7 +149,7 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent,
                         // See if the item is within range
                         if (bbox_to_snap_incl.intersects(*bbox_of_item)) {
                             // This item is within snapping range, so record it as a candidate
-                            _candidates->push_back(SnapCandidate(item, clip_or_mask, additional_affine));
+                            _candidates->push_back(SnapCandidateItem(item, clip_or_mask, additional_affine));
                             // For debugging: print the id of the candidate to the console
                             //SPObject *obj = (SPObject*)item;
                             //std::cout << "Snap candidate added: " << obj->id << std::endl;
@@ -202,7 +193,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
             _getBorderNodes(_points_to_snap_to);
         }
 
-        for (std::vector<SnapCandidate>::const_iterator i = _candidates->begin(); i != _candidates->end(); i++) {
+        for (std::vector<SnapCandidateItem>::const_iterator i = _candidates->begin(); i != _candidates->end(); i++) {
             //Geom::Matrix i2doc(Geom::identity());
             SPItem *root_item = (*i).item;
             if (SP_IS_USE((*i).item)) {
@@ -236,7 +227,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
                     _snapmanager->snapprefs.setSnapIntersectionCS(false);
                 }
 
-                sp_item_snappoints(root_item, true, *_points_to_snap_to, &_snapmanager->snapprefs);
+                sp_item_snappoints(root_item, *_points_to_snap_to, &_snapmanager->snapprefs);
 
                 if (_snapmanager->snapprefs.getSnapToItemPath()) {
                     _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
@@ -258,14 +249,12 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
 
 void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
                                          Inkscape::SnapPreferences::PointType const &t,
-                                         Geom::Point const &p,
-                                         SnapSourceType const &source_type,
-                                         long source_num,
-                                         std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
+                                         Inkscape::SnapCandidatePoint const &p,
+                                         std::vector<SnapCandidatePoint> *unselected_nodes) const
 {
     // Iterate through all nodes, find out which one is the closest to p, and snap to it!
 
-    _collectNodes(t, source_num == 0);
+    _collectNodes(t, p.getSourceNum() == 0);
 
     if (unselected_nodes != NULL) {
         _points_to_snap_to->insert(_points_to_snap_to->end(), unselected_nodes->begin(), unselected_nodes->end());
@@ -274,10 +263,10 @@ void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
     SnappedPoint s;
     bool success = false;
 
-    for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
-        Geom::Coord dist = Geom::L2((*k).first - p);
+    for (std::vector<SnapCandidatePoint>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+        Geom::Coord dist = Geom::L2((*k).getPoint() - p.getPoint());
         if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) {
-            s = SnappedPoint((*k).first, source_type, source_num, static_cast<Inkscape::SnapTargetType>((*k).second), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).getPoint(), p.getSourceType(), p.getSourceNum(), (*k).getTargetType(), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
             success = true;
         }
     }
@@ -298,7 +287,7 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s
     // Although we won't snap to paths here (which would give us under constrained snaps) we can still snap to intersections of paths.
     if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
         _collectPaths(t, true);
-        _snapPaths(sc, t, p, SNAPSOURCE_GUIDE, 0, NULL, NULL);
+        _snapPaths(sc, t, Inkscape::SnapCandidatePoint(p, SNAPSOURCE_GUIDE), NULL, NULL);
         // The paths themselves should be discarded in findBestSnap(), as we should only snap to their intersections
     }
 
@@ -306,13 +295,13 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s
 
     Geom::Coord tol = getSnapperTolerance();
 
-    for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+    for (std::vector<SnapCandidatePoint>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
         // Project each node (*k) on the guide line (running through point p)
-        Geom::Point p_proj = Geom::projection((*k).first, Geom::Line(p, p + Geom::rot90(guide_normal)));
-        Geom::Coord dist = Geom::L2((*k).first - p_proj); // distance from node to the guide
+        Geom::Point p_proj = Geom::projection((*k).getPoint(), Geom::Line(p, p + Geom::rot90(guide_normal)));
+        Geom::Coord dist = Geom::L2((*k).getPoint() - p_proj); // distance from node to the guide
         Geom::Coord dist2 = Geom::L2(p - p_proj); // distance from projection of node on the guide, to the mouse location
         if ((dist < tol && dist2 < tol) || getSnapperAlwaysSnap()) {
-            s = SnappedPoint((*k).first, SNAPSOURCE_GUIDE, 0, static_cast<Inkscape::SnapTargetType>((*k).second), dist, tol, getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).getPoint(), SNAPSOURCE_GUIDE, 0, (*k).getTargetType(), dist, tol, getSnapperAlwaysSnap(), true);
             sc.points.push_back(s);
         }
     }
@@ -349,11 +338,11 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
         if (_snapmanager->snapprefs.getSnapToPageBorder()) {
             Geom::PathVector *border_path = _getBorderPathv();
             if (border_path != NULL) {
-                _paths_to_snap_to->push_back(std::make_pair(border_path, SNAPTARGET_PAGE_BORDER));
+                _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(border_path, SNAPTARGET_PAGE_BORDER));
             }
         }
 
-        for (std::vector<SnapCandidate>::const_iterator i = _candidates->begin(); i != _candidates->end(); i++) {
+        for (std::vector<SnapCandidateItem>::const_iterator i = _candidates->begin(); i != _candidates->end(); i++) {
 
             /* Transform the requested snap point to this item's coordinates */
             Geom::Matrix i2doc(Geom::identity());
@@ -397,7 +386,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
                         if (curve) {
                             // We will get our own copy of the path, which must be freed at some point
                             Geom::PathVector *borderpathv = pathvector_for_curve(root_item, curve, true, true, Geom::identity(), (*i).additional_affine);
-                            _paths_to_snap_to->push_back(std::make_pair(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
+                            _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
                             curve->unref();
                         }
                     }
@@ -414,7 +403,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
                         sp_item_invoke_bbox(root_item, rect, i2doc, TRUE, bbox_type);
                         if (rect) {
                             Geom::PathVector *path = _getPathvFromRect(*rect);
-                            _paths_to_snap_to->push_back(std::make_pair(path, SNAPTARGET_BBOX_EDGE));
+                            _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(path, SNAPTARGET_BBOX_EDGE));
                         }
                     }
                 }
@@ -425,47 +414,40 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
 
 void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
                                      Inkscape::SnapPreferences::PointType const &t,
-                                     Geom::Point const &p,
-                                     SnapSourceType const &source_type,
-                                     long source_num,
-                                     std::vector<std::pair<Geom::Point, int> > *unselected_nodes,
+                                     Inkscape::SnapCandidatePoint const &p,
+                                     std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes,
                                      SPPath const *selected_path) const
 {
-    _collectPaths(t, source_num == 0);
+    _collectPaths(t, p.getSourceNum() == 0);
     // Now we can finally do the real snapping, using the paths collected above
 
     g_assert(_snapmanager->getDesktop() != NULL);
-    Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p);
+    Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p.getPoint());
 
     bool const node_tool_active = _snapmanager->snapprefs.getSnapToItemPath() && selected_path != NULL;
 
-    if (source_num == 0) {
+    if (p.getSourceNum() == 0) {
         /* findCandidates() is used for snapping to both paths and nodes. It ignores the path that is
          * currently being edited, because that path requires special care: when snapping to nodes
          * only the unselected nodes of that path should be considered, and these will be passed on separately.
          * This path must not be ignored however when snapping to the paths, so we add it here
          * manually when applicable.
-         *
-         * Note that this path must be the last in line!
          * */
         if (node_tool_active) {
             SPCurve *curve = curve_for_item(SP_ITEM(selected_path));
             if (curve) {
                 Geom::PathVector *pathv = pathvector_for_curve(SP_ITEM(selected_path), curve, true, true, Geom::identity(), Geom::identity()); // We will get our own copy of the path, which must be freed at some point
-                _paths_to_snap_to->push_back(std::make_pair(pathv, SNAPTARGET_PATH));
+                _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(pathv, SNAPTARGET_PATH, true));
                 curve->unref();
             }
         }
     }
 
-    for (std::vector<std::pair<Geom::PathVector*, SnapTargetType> >::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) {
-        bool const being_edited = (node_tool_active && (*it_p) == _paths_to_snap_to->back());
+    for (std::vector<Inkscape::SnapCandidatePath >::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) {
+        bool const being_edited = node_tool_active && (*it_p).currently_being_edited;
         //if true then this pathvector it_pv is currently being edited in the node tool
 
-        // char * svgd = sp_svg_write_path(**it_p->first);
-        // std::cout << "Dumping the pathvector: " << svgd << std::endl;
-
-        for(Geom::PathVector::iterator it_pv = (it_p->first)->begin(); it_pv != (it_p->first)->end(); ++it_pv) {
+        for(Geom::PathVector::iterator it_pv = (it_p->path_vector)->begin(); it_pv != (it_p->path_vector)->end(); ++it_pv) {
             // Find a nearest point for each curve within this path
             // n curves will return n time values with 0 <= t <= 1
             std::vector<double> anp = (*it_pv).nearestPointPerCurve(p_doc);
@@ -502,7 +484,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
                 if (!being_edited || (c1 && c2)) {
                     Geom::Coord const dist = Geom::distance(sp_doc, p_doc);
                     if (dist < getSnapperTolerance()) {
-                        sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, source_type, source_num, it_p->second));
+                        sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, p.getSourceType(), p.getSourceNum(), it_p->target_type));
                     }
                 }
             }
@@ -511,7 +493,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
 }
 
 /* Returns true if point is coincident with one of the unselected nodes */
-bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const
+bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<Inkscape::SnapCandidatePoint> const *unselected_nodes) const
 {
     if (unselected_nodes == NULL) {
         return false;
@@ -521,8 +503,8 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
         return false;
     }
 
-    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
-        if (Geom::L2(point - (*i).first) < 1e-4) {
+    for (std::vector<Inkscape::SnapCandidatePoint>::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
+        if (Geom::L2(point - (*i).getPoint()) < 1e-4) {
             return true;
         }
     }
@@ -532,18 +514,16 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
 
 void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
                                      Inkscape::SnapPreferences::PointType const &t,
-                                     Geom::Point const &p,
-                                     SnapSourceType const source_type,
-                                     long source_num,
+                                     Inkscape::SnapCandidatePoint const &p,
                                      ConstraintLine const &c) const
 {
 
-    _collectPaths(t, source_num == 0);
+    _collectPaths(t, p.getSourceNum() == 0);
 
     // Now we can finally do the real snapping, using the paths collected above
 
     g_assert(_snapmanager->getDesktop() != NULL);
-    Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p);
+    Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p.getPoint());
 
     Geom::Point direction_vector = c.getDirection();
     if (!is_zero(direction_vector)) {
@@ -553,7 +533,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
     // The intersection point of the constraint line with any path,
     // must lie within two points on the constraintline: p_min_on_cl and p_max_on_cl
     // The distance between those points is twice the snapping tolerance
-    Geom::Point const p_proj_on_cl = p; // projection has already been taken care of in constrainedSnap in the snapmanager;
+    Geom::Point const p_proj_on_cl = p.getPoint(); // projection has already been taken care of in constrainedSnap in the snapmanager;
     Geom::Point const p_min_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_cl - getSnapperTolerance() * direction_vector);
     Geom::Point const p_max_on_cl = _snapmanager->getDesktop()->dt2doc(p_proj_on_cl + getSnapperTolerance() * direction_vector);
 
@@ -563,9 +543,9 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
     cl.appendNew<Geom::LineSegment>(p_max_on_cl);
     clv.push_back(cl);
 
-    for (std::vector<std::pair<Geom::PathVector*, SnapTargetType> >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) {
-        if (k->first) {
-            Geom::CrossingSet cs = Geom::crossings(clv, *(k->first));
+    for (std::vector<Inkscape::SnapCandidatePath >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) {
+        if (k->path_vector) {
+            Geom::CrossingSet cs = Geom::crossings(clv, *(k->path_vector));
             if (cs.size() > 0) {
                 // We need only the first element of cs, because cl is only a single straight linesegment
                 // This first element contains a vector filled with crossings of cl with k->first
@@ -576,7 +556,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
                         // When it's within snapping range, then return it
                         // (within snapping range == between p_min_on_cl and p_max_on_cl == 0 < ta < 1)
                         Geom::Coord dist = Geom::L2(_snapmanager->getDesktop()->dt2doc(p_proj_on_cl) - p_inters);
-                        SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), source_type, source_num, k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+                        SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
                         sc.points.push_back(s);
                     }
                 }
@@ -588,21 +568,19 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
 
 void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
                                             Inkscape::SnapPreferences::PointType const &t,
-                                            Geom::Point const &p,
-                                            SnapSourceType const &source_type,
-                                            long source_num,
+                                            Inkscape::SnapCandidatePoint const &p,
                                             Geom::OptRect const &bbox_to_snap,
                                             std::vector<SPItem const *> const *it,
-                                            std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
+                                            std::vector<SnapCandidatePoint> *unselected_nodes) const
 {
     if (_snap_enabled == false || _snapmanager->snapprefs.getSnapFrom(t) == false ) {
         return;
     }
 
     /* Get a list of all the SPItems that we will try to snap to */
-    if (source_num == 0) {
-        Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p, p);
-        _findCandidates(sp_document_root(_snapmanager->getDocument()), it, source_num == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity());
+    if (p.getSourceNum() == 0) {
+        Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p.getPoint(), p.getPoint());
+        _findCandidates(sp_document_root(_snapmanager->getDocument()), it, p.getSourceNum() == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity());
     }
 
     if (_snapmanager->snapprefs.getSnapToItemNode() || _snapmanager->snapprefs.getSnapSmoothNodes()
@@ -610,7 +588,7 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
         || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints()
         || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()
         || _snapmanager->snapprefs.getIncludeItemCenter()) {
-        _snapNodes(sc, t, p, source_type, source_num, unselected_nodes);
+        _snapNodes(sc, t, p, unselected_nodes);
     }
 
     if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
@@ -628,18 +606,16 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
                 } // else: *it->begin() might be a SPGroup, e.g. when editing a LPE of text that has been converted to a group of paths
                 // as reported in bug #356743. In that case we can just ignore it, i.e. not snap to this item
             }
-            _snapPaths(sc, t, p, source_type, source_num, unselected_nodes, path);
+            _snapPaths(sc, t, p, unselected_nodes, path);
         } else {
-            _snapPaths(sc, t, p, source_type, source_num, NULL, NULL);
+            _snapPaths(sc, t, p, NULL, NULL);
         }
     }
 }
 
 void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
                                                   Inkscape::SnapPreferences::PointType const &t,
-                                                  Geom::Point const &p,
-                                                  SnapSourceType const &source_type,
-                                                  long source_num,
+                                                  Inkscape::SnapCandidatePoint const &p,
                                                   Geom::OptRect const &bbox_to_snap,
                                                   ConstraintLine const &c,
                                                   std::vector<SPItem const *> const *it) const
@@ -649,9 +625,9 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
     }
 
     /* Get a list of all the SPItems that we will try to snap to */
-    if (source_num == 0) {
-        Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p, p);
-        _findCandidates(sp_document_root(_snapmanager->getDocument()), it, source_num == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity());
+    if (p.getSourceNum() == 0) {
+        Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p.getPoint(), p.getPoint());
+        _findCandidates(sp_document_root(_snapmanager->getDocument()), it, p.getSourceNum() == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity());
     }
 
     // A constrained snap, is a snap in only one degree of freedom (specified by the constraint line).
@@ -664,7 +640,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
     // so we will more or less snap to them anyhow.
 
     if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
-        _snapPathsConstrained(sc, t, p, source_type, 0, c);
+        _snapPathsConstrained(sc, t, p, c);
     }
 }
 
@@ -748,8 +724,8 @@ bool Inkscape::ObjectSnapper::GuidesMightSnap() const // almost the same as This
 
 void Inkscape::ObjectSnapper::_clear_paths() const
 {
-    for (std::vector<std::pair<Geom::PathVector*, SnapTargetType> >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) {
-        g_free(k->first);
+    for (std::vector<Inkscape::SnapCandidatePath >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) {
+        g_free(k->path_vector);
     }
     _paths_to_snap_to->clear();
 }
@@ -771,31 +747,31 @@ Geom::PathVector* Inkscape::ObjectSnapper::_getPathvFromRect(Geom::Rect const re
     }
 }
 
-void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const
+void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<SnapCandidatePoint> *points) const
 {
     Geom::Coord w = sp_document_width(_snapmanager->getDocument());
     Geom::Coord h = sp_document_height(_snapmanager->getDocument());
-    points->push_back(std::make_pair(Geom::Point(0,0), SNAPTARGET_PAGE_CORNER));
-    points->push_back(std::make_pair(Geom::Point(0,h), SNAPTARGET_PAGE_CORNER));
-    points->push_back(std::make_pair(Geom::Point(w,h), SNAPTARGET_PAGE_CORNER));
-    points->push_back(std::make_pair(Geom::Point(w,0), SNAPTARGET_PAGE_CORNER));
+    points->push_back(Inkscape::SnapCandidatePoint(Geom::Point(0,0), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
+    points->push_back(Inkscape::SnapCandidatePoint(Geom::Point(0,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
+    points->push_back(Inkscape::SnapCandidatePoint(Geom::Point(w,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
+    points->push_back(Inkscape::SnapCandidatePoint(Geom::Point(w,0), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
 }
 
-void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
+void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<SnapCandidatePoint> *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
 {
     if (bbox) {
         // collect the corners of the bounding box
         for ( unsigned k = 0 ; k < 4 ; k++ ) {
             if (includeCorners) {
-                points->push_back(std::make_pair((bbox->corner(k)), isTarget ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER)));
+                points->push_back(Inkscape::SnapCandidatePoint(bbox->corner(k), Inkscape::SNAPSOURCE_BBOX_CORNER, 0, Inkscape::SNAPTARGET_BBOX_CORNER, *bbox));
             }
             // optionally, collect the midpoints of the bounding box's edges too
             if (includeLineMidpoints) {
-                points->push_back(std::make_pair((bbox->corner(k) + bbox->corner((k+1) % 4))/2, isTarget ? int(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT)));
+                points->push_back(Inkscape::SnapCandidatePoint((bbox->corner(k) + bbox->corner((k+1) % 4))/2, Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT, 0, Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT, *bbox));
             }
         }
         if (includeObjectMidpoints) {
-            points->push_back(std::make_pair(bbox->midpoint(), isTarget ? int(Inkscape::SNAPTARGET_BBOX_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_MIDPOINT)));
+            points->push_back(Inkscape::SnapCandidatePoint(bbox->midpoint(), Inkscape::SNAPSOURCE_BBOX_MIDPOINT, 0, Inkscape::SNAPTARGET_BBOX_MIDPOINT, *bbox));
         }
     }
 }
index 2fcafb79a106b03112ff6864b8ea72a9fd1f3e06..556ff86def386cea8f02ab3a6facb54e9e6e3627 100644 (file)
@@ -17,6 +17,7 @@
 #include "snapper.h"
 #include "sp-path.h"
 #include "splivarot.h"
+#include "snap-candidate.h"
 
 struct SPNamedView;
 struct SPItem;
@@ -25,23 +26,6 @@ struct SPObject;
 namespace Inkscape
 {
 
-class SnapCandidate
-
-{
-public:
-    SnapCandidate(SPItem* item, bool clip_or_mask, Geom::Matrix _additional_affine);
-    ~SnapCandidate();
-
-    SPItem* item;        // An item that is to be considered for snapping to
-    bool clip_or_mask;    // If true, then item refers to a clipping path or a mask
-
-    /* To find out the absolute position of a clipping path or mask, we not only need to know
-     * the transformation of the clipping path or mask itself, but also the transformation of
-     * the object to which the clip or mask is being applied; that transformation is stored here
-     */
-    Geom::Matrix additional_affine;
-};
-
 class ObjectSnapper : public Snapper
 {
 
@@ -72,27 +56,23 @@ public:
 
     void freeSnap(SnappedConstraints &sc,
                   Inkscape::SnapPreferences::PointType const &t,
-                  Geom::Point const &p,
-                  SnapSourceType const &source_type,
-                  long source_num,
+                  Inkscape::SnapCandidatePoint const &p,
                   Geom::OptRect const &bbox_to_snap,
                   std::vector<SPItem const *> const *it,
-                  std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
+                  std::vector<SnapCandidatePoint> *unselected_nodes) const;
 
     void constrainedSnap(SnappedConstraints &sc,
                   Inkscape::SnapPreferences::PointType const &t,
-                  Geom::Point const &p,
-                  SnapSourceType const &source_type,
-                  long source_num,
+                  Inkscape::SnapCandidatePoint const &p,
                   Geom::OptRect const &bbox_to_snap,
                   ConstraintLine const &c,
                   std::vector<SPItem const *> const *it) const;
 
 private:
     //store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap
-    std::vector<SnapCandidate> *_candidates;
-    std::vector<std::pair<Geom::Point, int> > *_points_to_snap_to;
-    std::vector<std::pair<Geom::PathVector*, SnapTargetType> > *_paths_to_snap_to;
+    std::vector<SnapCandidateItem> *_candidates;
+    std::vector<SnapCandidatePoint> *_points_to_snap_to;
+    std::vector<SnapCandidatePath > *_paths_to_snap_to;
 
     void _findCandidates(SPObject* parent,
                        std::vector<SPItem const *> const *it,
@@ -104,10 +84,8 @@ private:
 
     void _snapNodes(SnappedConstraints &sc,
                       Inkscape::SnapPreferences::PointType const &t,
-                      Geom::Point const &p, // in desktop coordinates
-                      SnapSourceType const &source_type,
-                      long source_num,
-                      std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; // in desktop coordinates
+                      Inkscape::SnapCandidatePoint const &p,
+                      std::vector<SnapCandidatePoint> *unselected_nodes) const; // in desktop coordinates
 
     void _snapTranslatingGuideToNodes(SnappedConstraints &sc,
                      Inkscape::SnapPreferences::PointType const &t,
@@ -119,20 +97,16 @@ private:
 
     void _snapPaths(SnappedConstraints &sc,
                       Inkscape::SnapPreferences::PointType const &t,
-                      Geom::Point const &p,    // in desktop coordinates
-                      SnapSourceType const &source_type,
-                      long source_num,
-                      std::vector<std::pair<Geom::Point, int> > *unselected_nodes, // in desktop coordinates
+                      Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
+                      std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes, // in desktop coordinates
                       SPPath const *selected_path) const;
 
     void _snapPathsConstrained(SnappedConstraints &sc,
                  Inkscape::SnapPreferences::PointType const &t,
-                 Geom::Point const &p, // in desktop coordinates
-                 SnapSourceType const source_type,
-                 long source_num,
+                 Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
                  ConstraintLine const &c) const;
 
-    bool isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const;
+    bool isUnselectedNode(Geom::Point const &point, std::vector<Inkscape::SnapCandidatePoint> const *unselected_nodes) const;
 
     void _collectPaths(Inkscape::SnapPreferences::PointType const &t,
                   bool const &first_point) const;
@@ -140,11 +114,11 @@ private:
     void _clear_paths() const;
     Geom::PathVector* _getBorderPathv() const;
     Geom::PathVector* _getPathvFromRect(Geom::Rect const rect) const;
-    void _getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const;
+    void _getBorderNodes(std::vector<SnapCandidatePoint> *points) const;
 
 }; // end of ObjectSnapper class
 
-void getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
+void getBBoxPoints(Geom::OptRect const bbox, std::vector<SnapCandidatePoint> *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
 
 } // end of namespace Inkscape
 
index 505e18675779c6e46bf4ea2dc2add7b7308542fc..dcf635989a14d363079704942ef17fec8a541124 100644 (file)
@@ -6,14 +6,14 @@
 #include <approx-equal.h>
 
 void satisfied_guide_cns(SPDesktop const &desktop,
-                         SnapPointsWithType const &snappoints,
+                         std::vector<Inkscape::SnapCandidatePoint> const &snappoints,
                          std::vector<SPGuideConstraint> &cns)
 {
     SPNamedView const &nv = *sp_desktop_namedview(&desktop);
     for (GSList const *l = nv.guides; l != NULL; l = l->next) {
         SPGuide &g = *SP_GUIDE(l->data);
         for (unsigned int i = 0; i < snappoints.size(); ++i) {
-            if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i].first), 0) ) {
+            if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i].getPoint()), 0) ) {
                 cns.push_back(SPGuideConstraint(&g, i));
             }
         }
index 99229f64c9aafc084c39d888b62ac2ecd0dc7725..7fba2916120f1a9e7093e07f76bf7e4b2d1d72a4 100644 (file)
@@ -9,7 +9,7 @@
 class SPGuideConstraint;
 
 void satisfied_guide_cns(SPDesktop const &desktop,
-                         SnapPointsWithType const &snappoints,
+                         std::vector<Inkscape::SnapCandidatePoint> const &snappoints,
                          std::vector<SPGuideConstraint> &cns);
 
 
index 7b936587c343513760684927f30be54e7179f00b..1e14591fae7474ffb838c274aabdf53f29328b7e 100644 (file)
@@ -426,48 +426,48 @@ boost::optional<Geom::Point> Selection::center() const {
 /**
  * Compute the list of points in the selection that are to be considered for snapping.
  */
-std::vector<std::pair<Geom::Point, int> > Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
+std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
     SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs
     snapprefs_dummy.setIncludeItemCenter(false); // locally disable snapping to the item center
 
-    std::vector<std::pair<Geom::Point, int> > p;
+    std::vector<Inkscape::SnapCandidatePoint> p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
         SPItem *this_item = SP_ITEM(iter->data);
-        sp_item_snappoints(this_item, false, p, &snapprefs_dummy);
+        sp_item_snappoints(this_item, p, &snapprefs_dummy);
 
         //Include the transformation origin for snapping
         //For a selection or group only the overall origin is considered
         if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-            p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
+            p.push_back(Inkscape::SnapCandidatePoint(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
         }
     }
 
     return p;
 }
 
-std::vector<std::pair<Geom::Point, int> > Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
+std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
-    std::vector<std::pair<Geom::Point, int> > p;
+    std::vector<Inkscape::SnapCandidatePoint> p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
-        sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
+        sp_item_snappoints(SP_ITEM(iter->data), p, snapprefs);
     }
 
-    std::vector<std::pair<Geom::Point, int> > pHull;
+    std::vector<Inkscape::SnapCandidatePoint> pHull;
     if (!p.empty()) {
-        std::vector<std::pair<Geom::Point, int> >::iterator i;
-        Geom::RectHull cvh((p.front()).first);
+        std::vector<Inkscape::SnapCandidatePoint>::iterator i;
+        Geom::RectHull cvh((p.front()).getPoint());
         for (i = p.begin(); i != p.end(); i++) {
             // these are the points we get back
-            cvh.add((*i).first);
+            cvh.add((*i).getPoint());
         }
 
         Geom::OptRect rHull = cvh.bounds();
         if (rHull) {
             for ( unsigned i = 0 ; i < 4 ; ++i ) {
-                pHull.push_back(std::make_pair(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
+                pHull.push_back(Inkscape::SnapCandidatePoint(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
             }
         }
     }
index 5e035fb60e3dde7cdc3c23cff953b9b549693b39..b5a511e96f6ffbec9dae54d101d79ba48fb12a0c 100644 (file)
@@ -272,13 +272,13 @@ public:
      * @brief Gets the selection's snap points.
      * @return Selection's snap points
      */
-    std::vector<std::pair<Geom::Point, int> > getSnapPoints(SnapPreferences const *snapprefs) const;
+    std::vector<Inkscape::SnapCandidatePoint> getSnapPoints(SnapPreferences const *snapprefs) const;
 
     /**
      * @brief Gets the snap points of a selection that form a convex hull.
      * @return Selection's convex hull points
      */
-    std::vector<std::pair<Geom::Point, int> > getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
+    std::vector<Inkscape::SnapCandidatePoint> getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
 
     /**
      * @brief Connects a slot to be notified of selection changes
index 8ff00d60ae902f654b23e21055e657220d66f1ed..5b129f8d8b7aefbb987dd385f1f8fc750ee00697 100644 (file)
@@ -295,7 +295,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
     // but as a snap source we still need some nodes though!
     _snap_points.clear();
     _snap_points = selection->getSnapPoints(&local_snapprefs);
-    std::vector<std::pair<Geom::Point, int> > snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
+    std::vector<Inkscape::SnapCandidatePoint> snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
     if (_snap_points.size() > 200) {
         /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes
         An average user would rarely ever try to snap such a large number of nodes anyway, because
@@ -313,11 +313,11 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
     // any other special points
     Geom::Rect snap_points_bbox;
     if ( snap_points_hull.empty() == false ) {
-        std::vector<std::pair<Geom::Point, int> >::iterator i = snap_points_hull.begin();
-        snap_points_bbox = Geom::Rect((*i).first, (*i).first);
+        std::vector<Inkscape::SnapCandidatePoint>::iterator i = snap_points_hull.begin();
+        snap_points_bbox = Geom::Rect((*i).getPoint(), (*i).getPoint());
         i++;
         while (i != snap_points_hull.end()) {
-            snap_points_bbox.expandTo((*i).first);
+            snap_points_bbox.expandTo((*i).getPoint());
             i++;
         }
     }
@@ -381,9 +381,9 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
         }
 
         // Now let's reduce this to a single closest snappoint
-        Geom::Coord dsp    = _snap_points.size()                 == 1 ? Geom::L2((_snap_points.at(0)).first - p) : NR_HUGE;
-        Geom::Coord dbbp   = _bbox_points.size()                 == 1 ? Geom::L2((_bbox_points.at(0)).first - p) : NR_HUGE;
-        Geom::Coord dbbpft = _bbox_points_for_translating.size() == 1 ? Geom::L2((_bbox_points_for_translating.at(0)).first - p) : NR_HUGE;
+        Geom::Coord dsp    = _snap_points.size()                 == 1 ? Geom::L2((_snap_points.at(0)).getPoint() - p) : NR_HUGE;
+        Geom::Coord dbbp   = _bbox_points.size()                 == 1 ? Geom::L2((_bbox_points.at(0)).getPoint() - p) : NR_HUGE;
+        Geom::Coord dbbpft = _bbox_points_for_translating.size() == 1 ? Geom::L2((_bbox_points_for_translating.at(0)).getPoint() - p) : NR_HUGE;
 
         if (translating) {
             _bbox_points.clear();
@@ -1513,6 +1513,7 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state)
                 }
             }
         }
+
         if (best_snapped_point.getSnapped()) {
             _desktop->snapindicator->set_new_snaptarget(best_snapped_point);
         } else {
@@ -1643,15 +1644,15 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineGeom(Geom::Scale const geom_scale)
     return _calcAbsAffineDefault(geom_scale); // this is bogus, but we must return _something_
 }
 
-void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference)
+void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<Inkscape::SnapCandidatePoint> &points, const Geom::Point &reference)
 {
     if (points.size() < 2) return;
 
-    std::pair<Geom::Point, int> closest_point = std::make_pair(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED);
+    Inkscape::SnapCandidatePoint closest_point = Inkscape::SnapCandidatePoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED);
     Geom::Coord closest_dist = NR_HUGE;
 
-    for(std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
-        Geom::Coord dist = Geom::L2((*i).first - reference);
+    for(std::vector<Inkscape::SnapCandidatePoint>::const_iterator i = points.begin(); i != points.end(); i++) {
+        Geom::Coord dist = Geom::L2((*i).getPoint() - reference);
         if (i == points.begin() || dist < closest_dist) {
             closest_point = *i;
             closest_dist = dist;
index d0ac5dccf5a679d49653cc9d7130999a22bb0ac2..8b2810621089b8d4d18ee960df6d452b06d69e4f 100644 (file)
@@ -102,7 +102,7 @@ private:
     Geom::Point _getGeomHandlePos(Geom::Point const &visual_handle_pos);
     Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale);
     Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale);
-    void _keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference);
+    void _keepClosestPointOnly(std::vector<Inkscape::SnapCandidatePoint> &points, const Geom::Point &reference);
     void _display_snapsource();
 
     enum State {
@@ -117,9 +117,9 @@ private:
     std::vector<Geom::Matrix> _items_affines;
     std::vector<Geom::Point> _items_centers;
 
-    std::vector<std::pair<Geom::Point, int> > _snap_points;
-    std::vector<std::pair<Geom::Point, int> > _bbox_points; // the bbox point of the selection as a whole, i.e. max. 4 corners plus optionally some midpoints
-    std::vector<std::pair<Geom::Point, int> > _bbox_points_for_translating; // the bbox points of each selected item, only to be used for translating
+    std::vector<Inkscape::SnapCandidatePoint> _snap_points;
+    std::vector<Inkscape::SnapCandidatePoint> _bbox_points; // the bbox point of the selection as a whole, i.e. max. 4 corners plus optionally some midpoints
+    std::vector<Inkscape::SnapCandidatePoint> _bbox_points_for_translating; // the bbox points of each selected item, only to be used for translating
 
     Inkscape::SelCue _selcue;
 
diff --git a/src/snap-candidate.h b/src/snap-candidate.h
new file mode 100644 (file)
index 0000000..39386c1
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef SEEN_SNAP_CANDIDATE_H
+#define SEEN_SNAP_CANDIDATE_H
+
+/**
+ * \file snap-candidate.h
+ * \brief some utility classes to store various kinds of snap candidates.
+ *
+ * Authors:
+ *   Diederik van Lierop <mail@diedenrezi.nl>
+ *
+ * Copyright (C) 2010 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+//#include "snapped-point.h"
+struct SPItem; // forward declaration
+
+namespace Inkscape {
+
+enum SnapTargetType {
+    SNAPTARGET_UNDEFINED = 0,
+    SNAPTARGET_GRID,
+    SNAPTARGET_GRID_INTERSECTION,
+    SNAPTARGET_GUIDE,
+    SNAPTARGET_GUIDE_INTERSECTION,
+    SNAPTARGET_GUIDE_ORIGIN,
+    SNAPTARGET_GRID_GUIDE_INTERSECTION,
+    SNAPTARGET_NODE_SMOOTH,
+    SNAPTARGET_NODE_CUSP,
+    SNAPTARGET_LINE_MIDPOINT,
+    SNAPTARGET_OBJECT_MIDPOINT,
+    SNAPTARGET_ROTATION_CENTER,
+    SNAPTARGET_HANDLE,
+    SNAPTARGET_PATH,
+    SNAPTARGET_PATH_INTERSECTION,
+    SNAPTARGET_BBOX_CORNER,
+    SNAPTARGET_BBOX_EDGE,
+    SNAPTARGET_BBOX_EDGE_MIDPOINT,
+    SNAPTARGET_BBOX_MIDPOINT,
+    SNAPTARGET_PAGE_BORDER,
+    SNAPTARGET_PAGE_CORNER,
+    SNAPTARGET_CONVEX_HULL_CORNER,
+    SNAPTARGET_ELLIPSE_QUADRANT_POINT,
+    SNAPTARGET_CENTER, // of ellipse
+    SNAPTARGET_CORNER, // of image or of rectangle
+    SNAPTARGET_TEXT_BASELINE,
+    SNAPTARGET_CONSTRAINED_ANGLE
+};
+
+enum SnapSourceType {
+    SNAPSOURCE_UNDEFINED = 0,
+    SNAPSOURCE_BBOX_CORNER,
+    SNAPSOURCE_BBOX_MIDPOINT,
+    SNAPSOURCE_BBOX_EDGE_MIDPOINT,
+    SNAPSOURCE_NODE_SMOOTH,
+    SNAPSOURCE_NODE_CUSP,
+    SNAPSOURCE_LINE_MIDPOINT,
+    SNAPSOURCE_OBJECT_MIDPOINT,
+    SNAPSOURCE_ROTATION_CENTER,
+    SNAPSOURCE_HANDLE,
+    SNAPSOURCE_PATH_INTERSECTION,
+    SNAPSOURCE_GUIDE,
+    SNAPSOURCE_GUIDE_ORIGIN,
+    SNAPSOURCE_CONVEX_HULL_CORNER,
+    SNAPSOURCE_ELLIPSE_QUADRANT_POINT,
+    SNAPSOURCE_CENTER, // of ellipse
+    SNAPSOURCE_CORNER, // of image or of rectangle
+    SNAPSOURCE_TEXT_BASELINE
+};
+
+/// Class to store data for points which are snap candidates, either as a source or as a target
+class SnapCandidatePoint
+{
+public:
+    SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num, Inkscape::SnapTargetType const target, Geom::Rect const &bbox)
+        : _point(point), _source_type(source), _target_type(target), _source_num(source_num), _target_bbox(bbox) {};
+
+    SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, Inkscape::SnapTargetType const target)
+        : _point(point), _source_type(source), _target_type(target)
+    {
+        _source_num = 0;
+        _target_bbox = Geom::Rect();
+    }
+
+    SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num = 0)
+        : _point(point), _source_type(source), _target_type(Inkscape::SNAPTARGET_UNDEFINED), _source_num(source_num) {_target_bbox = Geom::Rect();}
+
+    inline Geom::Point const & getPoint() const {return _point;}
+    inline Inkscape::SnapSourceType getSourceType() const {return _source_type;}
+    inline Inkscape::SnapTargetType getTargetType() const {return _target_type;}
+    inline long getSourceNum() const {return _source_num;}
+    inline Geom::Rect const & getTargetBBox() const {return _target_bbox;}
+
+private:
+    // Coordinates of the point
+    Geom::Point _point;
+
+    // If this SnapCandidatePoint is a snap source, then _source_type must be defined. If it
+    // is a snap target, then _target_type must be defined. If it's yet unknown whether it will
+    // be a source or target, then both may be defined
+    Inkscape::SnapSourceType _source_type;
+    Inkscape::SnapTargetType _target_type;
+
+    //Sequence number of the source point within the set of points that is to be snapped. Starting at zero
+    long _source_num;
+
+    // If this is a target and it belongs to a bounding box, e.g. when the target type is
+    // SNAPTARGET_BBOX_EDGE_MIDPOINT, then _target_bbox stores the relevant bounding box
+    Geom::Rect _target_bbox;
+};
+
+class SnapCandidateItem
+{
+public:
+    SnapCandidateItem(SPItem* item, bool clip_or_mask, Geom::Matrix _additional_affine)
+        : item(item), clip_or_mask(clip_or_mask), additional_affine(additional_affine) {}
+    ~SnapCandidateItem() {};
+
+    SPItem* item;        // An item that is to be considered for snapping to
+    bool clip_or_mask;    // If true, then item refers to a clipping path or a mask
+
+    /* To find out the absolute position of a clipping path or mask, we not only need to know
+     * the transformation of the clipping path or mask itself, but also the transformation of
+     * the object to which the clip or mask is being applied; that transformation is stored here
+     */
+    Geom::Matrix additional_affine;
+}
+;
+
+class SnapCandidatePath
+{
+
+public:
+    SnapCandidatePath(Geom::PathVector* path, SnapTargetType target, bool edited = false)
+        : path_vector(path), target_type(target), currently_being_edited(edited) {}
+    ~SnapCandidatePath() {};
+
+    Geom::PathVector* path_vector;
+    SnapTargetType target_type;
+    bool currently_being_edited; // true for the path that's currently being edited in the node tool (if any)
+
+};
+
+} // end of namespace Inkscape
+
+#endif /* !SEEN_SNAP_CANDIDATE_H */
index bf4c928adb4b4b0348d8949c46c4523e51f69e9a..970f29ece86a0d852758d5a33c355dd8a04b1226 100644 (file)
@@ -13,7 +13,7 @@
  *
  * Copyright (C) 2006-2007 Johan Engelen <johan@shouraizou.nl>
  * Copyrigth (C) 2004      Nathan Hurst
- * Copyright (C) 1999-2009 Authors
+ * Copyright (C) 1999-2010 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -158,24 +158,25 @@ bool SnapManager::gridSnapperMightSnap() const
  *  because the original position should not be touched, then freeSnap() should be
  *  called instead.
  *
- *  PS: SnapManager::setup() must have been called before calling this method,
+ *  PS:
+ *  1) SnapManager::setup() must have been called before calling this method,
  *  but only once for a set of points
+ *  2) Only to be used when a single source point is to be snapped; it assumes
+ *  that source_num = 0, which is inefficient when snapping sets our source points
  *
  *  \param point_type Category of points to which the source point belongs: node, guide or bounding box
  *  \param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred
  *  \param source_type Detailed description of the source type, will be used by the snap indicator
- *  \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero
  *  \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation
  */
 
 void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
                                       Geom::Point &p,
                                       Inkscape::SnapSourceType const source_type,
-                                      long source_num,
                                       Geom::OptRect const &bbox_to_snap) const
 {
-    //TODO: PointType and source_type are somewhat redundant; can't we get rid of the point_type parameter?
-    Inkscape::SnappedPoint const s = freeSnap(point_type, p, source_type, source_num, bbox_to_snap);
+    //TODO: SnapCandidatePoint and point_type are somewhat redundant; can't we get rid of the point_type parameter?
+    Inkscape::SnappedPoint const s = freeSnap(point_type, Inkscape::SnapCandidatePoint(p, source_type), bbox_to_snap);
     s.getPoint(p);
 }
 
@@ -192,22 +193,18 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point
  *  but only once for a set of points
  *
  *  \param point_type Category of points to which the source point belongs: node, guide or bounding box
- *  \param p Current position of the snap source
- *  \param source_type Detailed description of the source type, will be used by the snap indicator
- *  \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero
+ *  \param p Source point to be snapped
  *  \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation
  *  \return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics
  */
 
 
-Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType point_type,
-                                             Geom::Point const &p,
-                                             Inkscape::SnapSourceType const &source_type,
-                                             long source_num,
+Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType const point_type,
+                                             Inkscape::SnapCandidatePoint const &p,
                                              Geom::OptRect const &bbox_to_snap) const
 {
     if (!someSnapperMightSnap()) {
-        return Inkscape::SnappedPoint(p, source_type, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+        return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
     }
 
     std::vector<SPItem const *> *items_to_ignore;
@@ -224,14 +221,14 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
     SnapperList const snappers = getSnappers();
 
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->freeSnap(sc, point_type, p, source_type, source_num, bbox_to_snap, items_to_ignore, _unselected_nodes);
+        (*i)->freeSnap(sc, point_type, p, bbox_to_snap, items_to_ignore, _unselected_nodes);
     }
 
     if (_item_to_ignore) {
         delete items_to_ignore;
     }
 
-    return findBestSnap(p, source_type, sc, false);
+    return findBestSnap(p, sc, false);
 }
 
 /**
@@ -280,9 +277,9 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
                 Geom::Point const t_offset = t + grid->origin;
                 SnappedConstraints sc;
                 // Only the first three parameters are being used for grid snappers
-                snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, 0, Geom::OptRect(), NULL, NULL);
+                snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, Inkscape::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_UNDEFINED),Geom::OptRect(), NULL, NULL);
                 // Find the best snap for this grid, including intersections of the grid-lines
-                Inkscape::SnappedPoint s = findBestSnap(t_offset, Inkscape::SNAPSOURCE_UNDEFINED, sc, false);
+                Inkscape::SnappedPoint s = findBestSnap(Inkscape::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_UNDEFINED), sc, false);
                 if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
                     // use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
                     // doesn't tell us anything about which node to snap
@@ -316,14 +313,17 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
  *  because the original position should not be touched, then constrainedSnap() should
  *  be called instead.
  *
- *  PS: SnapManager::setup() must have been called before calling this method,
+ *  PS:
+ *  1) SnapManager::setup() must have been called before calling this method,
  *  but only once for a set of points
+ *  2) Only to be used when a single source point is to be snapped; it assumes
+ *  that source_num = 0, which is inefficient when snapping sets our source points
+
  *
  *  \param point_type Category of points to which the source point belongs: node, guide or bounding box
  *  \param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred
  *  \param source_type Detailed description of the source type, will be used by the snap indicator
  *  \param constraint The direction or line along which snapping must occur
- *  \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero
  *  \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation
  */
 
@@ -331,10 +331,9 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
                                              Geom::Point &p,
                                              Inkscape::SnapSourceType const source_type,
                                              Inkscape::Snapper::ConstraintLine const &constraint,
-                                             long source_num,
                                              Geom::OptRect const &bbox_to_snap) const
 {
-    Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, source_type, constraint, source_num, bbox_to_snap);
+    Inkscape::SnappedPoint const s = constrainedSnap(point_type, Inkscape::SnapCandidatePoint(p, source_type, 0), constraint, bbox_to_snap);
     s.getPoint(p);
 }
 
@@ -350,22 +349,18 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
  *  but only once for a set of points
  *
  *  \param point_type Category of points to which the source point belongs: node, guide or bounding box
- *  \param p Current position of the snap source
- *  \param source_type Detailed description of the source type, will be used by the snap indicator
+ *  \param p Source point to be snapped
  *  \param constraint The direction or line along which snapping must occur
- *  \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero
  *  \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation
  */
 
-Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
-                                                    Geom::Point const &p,
-                                                    Inkscape::SnapSourceType const &source_type,
+Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::PointType const point_type,
+                                                    Inkscape::SnapCandidatePoint const &p,
                                                     Inkscape::Snapper::ConstraintLine const &constraint,
-                                                    long source_num,
                                                     Geom::OptRect const &bbox_to_snap) const
 {
     if (!someSnapperMightSnap()) {
-        return Inkscape::SnappedPoint(p, source_type, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+        return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
     }
 
     std::vector<SPItem const *> *items_to_ignore;
@@ -380,20 +375,21 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
 
 
     // First project the mouse pointer onto the constraint
-    Geom::Point pp = constraint.projection(p);
+    Geom::Point pp = constraint.projection(p.getPoint());
     // Then try to snap the projected point
+    Inkscape::SnapCandidatePoint candidate(pp, p.getSourceType(), p.getSourceNum(), Inkscape::SNAPTARGET_UNDEFINED, Geom::Rect());
 
     SnappedConstraints sc;
     SnapperList const snappers = getSnappers();
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->constrainedSnap(sc, point_type, pp, source_type, source_num, bbox_to_snap, constraint, items_to_ignore);
+        (*i)->constrainedSnap(sc, point_type, candidate, bbox_to_snap, constraint, items_to_ignore);
     }
 
     if (_item_to_ignore) {
         delete items_to_ignore;
     }
 
-    return findBestSnap(pp, source_type, sc, true);
+    return findBestSnap(candidate, sc, true);
 }
 
 /**
@@ -418,9 +414,9 @@ void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal,
         return;
     }
 
-    Inkscape::SnapSourceType source_type = Inkscape::SNAPSOURCE_GUIDE_ORIGIN;
+    Inkscape::SnapCandidatePoint candidate(p, Inkscape::SNAPSOURCE_GUIDE_ORIGIN);
     if (drag_type == SP_DRAG_ROTATE) {
-        source_type = Inkscape::SNAPSOURCE_GUIDE;
+        candidate = Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_GUIDE);
     }
 
     // Snap to nodes
@@ -433,11 +429,11 @@ void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal,
     SnapperList snappers = getGridSnappers();
     snappers.push_back(&guide);
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, p, source_type, 0, Geom::OptRect(), NULL, NULL);
+        (*i)->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, candidate, Geom::OptRect(), NULL, NULL);
     }
 
     // Snap to intersections of curves, but not to the curves themselves! (see _snapTranslatingGuideToNodes in object-snapper.cpp)
-    Inkscape::SnappedPoint const s = findBestSnap(p, source_type, sc, false, true);
+    Inkscape::SnappedPoint const s = findBestSnap(candidate, sc, false, true);
 
     s.getPoint(p);
 }
@@ -466,23 +462,23 @@ void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline)
         return;
     }
 
-    Inkscape::SnapSourceType source_type = Inkscape::SNAPSOURCE_GUIDE_ORIGIN;
+    Inkscape::SnapCandidatePoint candidate(p, Inkscape::SNAPSOURCE_GUIDE_ORIGIN, Inkscape::SNAPTARGET_UNDEFINED);
 
     // Snap to nodes or paths
     SnappedConstraints sc;
     Inkscape::Snapper::ConstraintLine cl(guideline.point_on_line, Geom::rot90(guideline.normal_to_line));
     if (object.ThisSnapperMightSnap()) {
-        object.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, p, source_type, 0, Geom::OptRect(), cl, NULL);
+        object.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, candidate, Geom::OptRect(), cl, NULL);
     }
 
     // Snap to guides & grid lines
     SnapperList snappers = getGridSnappers();
     snappers.push_back(&guide);
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, p, source_type, 0, Geom::OptRect(), cl, NULL);
+        (*i)->constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_OTHER, candidate, Geom::OptRect(), cl, NULL);
     }
 
-    Inkscape::SnappedPoint const s = findBestSnap(p, source_type, sc, false);
+    Inkscape::SnappedPoint const s = findBestSnap(candidate, sc, false);
     s.getPoint(p);
 }
 
@@ -514,7 +510,7 @@ void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline)
 
 Inkscape::SnappedPoint SnapManager::_snapTransformed(
     Inkscape::SnapPreferences::PointType type,
-    std::vector<std::pair<Geom::Point, int> > const &points,
+    std::vector<Inkscape::SnapCandidatePoint> const &points,
     Geom::Point const &pointer,
     bool constrained,
     Inkscape::Snapper::ConstraintLine const &constraint,
@@ -533,13 +529,14 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
     ** Also used to globally disable all snapping
     */
     if (someSnapperMightSnap() == false) {
-        return Inkscape::SnappedPoint();
+        return Inkscape::SnappedPoint(pointer);
     }
 
-    std::vector<std::pair<Geom::Point, int> > transformed_points;
+    std::vector<Inkscape::SnapCandidatePoint> transformed_points;
     Geom::Rect bbox;
 
-    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
+    long source_num = 0;
+    for (std::vector<Inkscape::SnapCandidatePoint>::const_iterator i = points.begin(); i != points.end(); i++) {
 
         /* Work out the transformed version of this point */
         Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform);
@@ -551,7 +548,8 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
             bbox.expandTo(transformed);
         }
 
-        transformed_points.push_back(std::make_pair(transformed, (*i).second));
+        transformed_points.push_back(Inkscape::SnapCandidatePoint(transformed, (*i).getSourceType(), source_num));
+        source_num++;
     }
 
     /* The current best transformation */
@@ -565,16 +563,16 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
     g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point
     g_assert(best_snapped_point.getAtIntersection() == false);
 
-    std::vector<std::pair<Geom::Point, int> >::const_iterator j = transformed_points.begin();
-    long source_num = 0;
+    std::vector<Inkscape::SnapCandidatePoint>::const_iterator j = transformed_points.begin();
+
 
     // std::cout << std::endl;
-    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
+    for (std::vector<Inkscape::SnapCandidatePoint>::const_iterator i = points.begin(); i != points.end(); i++) {
 
         /* Snap it */
         Inkscape::SnappedPoint snapped_point;
         Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
-        Geom::Point const b = ((*i).first - origin); // vector to original point
+        Geom::Point const b = ((*i).getPoint() - origin); // vector to original point
 
         if (constrained) {
             if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) {
@@ -583,18 +581,18 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                 // calculate that line here
                 dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, b);
             } else if (transformation_type == STRETCH) { // when non-uniform stretching {
-                dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i).first, component_vectors[dim]);
+                dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i).getPoint(), component_vectors[dim]);
             } else if (transformation_type == TRANSLATION) {
                 // When doing a constrained translation, all points will move in the same direction, i.e.
                 // either horizontally or vertically. The lines along which they move are therefore all
                 // parallel, but might not be colinear. Therefore we will have to set the point through
                 // which the constraint-line runs here, for each point individually.
-                dedicated_constraint.setPoint((*i).first);
+                dedicated_constraint.setPoint((*i).getPoint());
             } // else: leave the original constraint, e.g. for skewing
             if (transformation_type == SCALE && !uniform) {
                 g_warning("Non-uniform constrained scaling is not supported!");
             }
-            snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, source_num, bbox);
+            snapped_point = constrainedSnap(type, *j, dedicated_constraint, bbox);
         } else {
             bool const c1 = fabs(b[Geom::X]) < 1e-6;
             bool const c2 = fabs(b[Geom::Y]) < 1e-6;
@@ -603,13 +601,13 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                 // move in that specific direction; therefore it should only snap in that direction, otherwise
                 // we will get snapped points with an invalid transformation
                 dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]);
-                snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, source_num, bbox);
+                snapped_point = constrainedSnap(type, *j, dedicated_constraint, bbox);
             } else {
-                snapped_point = freeSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), source_num, bbox);
+                snapped_point = freeSnap(type, *j, bbox);
             }
         }
         // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl;
-        snapped_point.setPointerDistance(Geom::L2(pointer - (*i).first));
+        snapped_point.setPointerDistance(Geom::L2(pointer - (*i).getPoint()));
 
         Geom::Point result;
         Geom::Point scale_metric(NR_HUGE, NR_HUGE);
@@ -623,7 +621,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
 
             switch (transformation_type) {
                 case TRANSLATION:
-                    result = snapped_point.getPoint() - (*i).first;
+                    result = snapped_point.getPoint() - (*i).getPoint();
                     /* Consider the case in which a box is almost aligned with a grid in both
                      * horizontal and vertical directions. The distance to the intersection of
                      * the grid lines will always be larger then the distance to a single grid
@@ -673,7 +671,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                     snapped_point.setSecondSnapDistance(NR_HUGE);
                     break;
                 case SKEW:
-                    result[0] = (snapped_point.getPoint()[dim] - ((*i).first)[dim]) / (((*i).first)[1 - dim] - origin[1 - dim]); // skew factor
+                    result[0] = (snapped_point.getPoint()[dim] - ((*i).getPoint())[dim]) / (((*i).getPoint())[1 - dim] - origin[1 - dim]); // skew factor
                     result[1] = transformation[1]; // scale factor
                     // Store the metric for this transformation as a virtual distance
                     snapped_point.setSnapDistance(std::abs(result[0] - transformation[0]));
@@ -716,7 +714,6 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
         }
 
         j++;
-        source_num++;
     }
 
     Geom::Coord best_metric;
@@ -755,12 +752,13 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
  */
 
 Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                        std::vector<std::pair<Geom::Point, int> > const &p,
+                                                        std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                         Geom::Point const &pointer,
                                                         Geom::Point const &tr) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -778,13 +776,14 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                               std::vector<std::pair<Geom::Point, int> > const &p,
+                                                               std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                                Geom::Point const &pointer,
                                                                Inkscape::Snapper::ConstraintLine const &constraint,
                                                                Geom::Point const &tr) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -803,13 +802,14 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre
  */
 
 Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                  std::vector<std::pair<Geom::Point, int> > const &p,
+                                                  std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                   Geom::Point const &pointer,
                                                   Geom::Scale const &s,
                                                   Geom::Point const &o) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
@@ -828,14 +828,15 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                         std::vector<std::pair<Geom::Point, int> > const &p,
+                                                         std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                          Geom::Point const &pointer,
                                                          Geom::Scale const &s,
                                                          Geom::Point const &o) const
 {
     // When constrained scaling, only uniform scaling is supported.
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
@@ -855,7 +856,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
-                                                            std::vector<std::pair<Geom::Point, int> > const &p,
+                                                            std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                             Geom::Point const &pointer,
                                                             Geom::Coord const &s,
                                                             Geom::Point const &o,
@@ -863,7 +864,8 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
                                                             bool u) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
@@ -883,7 +885,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
-                                                 std::vector<std::pair<Geom::Point, int> > const &p,
+                                                 std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                  Geom::Point const &pointer,
                                                  Inkscape::Snapper::ConstraintLine const &constraint,
                                                  Geom::Point const &s,
@@ -900,7 +902,8 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
     g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
 
     if (p.size() == 1) {
-        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SKEW, s, o, d, false), (p.at(0)).second));
+        Geom::Point pt = _transformPoint(p.at(0), SKEW, s, o, d, false);
+        _displaySnapsource(point_type, Inkscape::SnapCandidatePoint(pt, p.at(0).getSourceType()));
     }
 
     return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
@@ -910,17 +913,15 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
  * \brief Given a set of possible snap targets, find the best target (which is not necessarily
  * also the nearest target), and show the snap indicator if requested
  *
- * \param p Current position of the snap source
- * \param source_type Detailed description of the source type, will be used by the snap indicator
+ * \param p Source point to be snapped
  * \param sc A structure holding all snap targets that have been found so far
  * \param constrained True if the snap is constrained, e.g. for stretching or for purely horizontal translation.
- * \param noCurves If true, then do consider snapping to intersections of curves, but not to the curves themself
+ * \param noCurves If true, then do consider snapping to intersections of curves, but not to the curves themselves
  * \return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics
  */
 
-Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
-                                                 Inkscape::SnapSourceType const source_type,
-                                                 SnappedConstraints &sc,
+Inkscape::SnappedPoint SnapManager::findBestSnap(Inkscape::SnapCandidatePoint const &p,
+                                                 SnappedConstraints const &sc,
                                                  bool constrained,
                                                  bool noCurves) const
 {
@@ -954,8 +955,8 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
     if (snapprefs.getSnapIntersectionCS()) {
         // search for the closest snapped intersection of curves
         Inkscape::SnappedPoint closestCurvesIntersection;
-        if (getClosestIntersectionCS(sc.curves, p, closestCurvesIntersection, _desktop->dt2doc())) {
-            closestCurvesIntersection.setSource(source_type);
+        if (getClosestIntersectionCS(sc.curves, p.getPoint(), closestCurvesIntersection, _desktop->dt2doc())) {
+            closestCurvesIntersection.setSource(p.getSourceType());
             sp_list.push_back(closestCurvesIntersection);
         }
     }
@@ -982,7 +983,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
         // search for the closest snapped intersection of grid lines
         Inkscape::SnappedPoint closestGridPoint;
         if (getClosestIntersectionSL(sc.grid_lines, closestGridPoint)) {
-            closestGridPoint.setSource(source_type);
+            closestGridPoint.setSource(p.getSourceType());
             closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
             sp_list.push_back(closestGridPoint);
         }
@@ -990,7 +991,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
         // search for the closest snapped intersection of guide lines
         Inkscape::SnappedPoint closestGuidePoint;
         if (getClosestIntersectionSL(sc.guide_lines, closestGuidePoint)) {
-            closestGuidePoint.setSource(source_type);
+            closestGuidePoint.setSource(p.getSourceType());
             closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
             sp_list.push_back(closestGuidePoint);
         }
@@ -999,7 +1000,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
         if (snapprefs.getSnapIntersectionGG()) {
             Inkscape::SnappedPoint closestGridGuidePoint;
             if (getClosestIntersectionSL(sc.grid_lines, sc.guide_lines, closestGridGuidePoint)) {
-                closestGridGuidePoint.setSource(source_type);
+                closestGridGuidePoint.setSource(p.getSourceType());
                 closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
                 sp_list.push_back(closestGridGuidePoint);
             }
@@ -1007,11 +1008,11 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
     }
 
     // now let's see which snapped point gets a thumbs up
-    Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_UNDEFINED, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+    Inkscape::SnappedPoint bestSnappedPoint(p.getPoint());
     // std::cout << "Finding the best snap..." << std::endl;
     for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
         // first find out if this snapped point is within snapping range
-        // std::cout << "sp = " << from_2geom((*i).getPoint());
+        // std::cout << "sp = " << (*i).getPoint() << " | source = " << (*i).getSource() << " | target = " << (*i).getTarget();
         if ((*i).getSnapDistance() <= (*i).getTolerance()) {
             // if it's the first point, or if it is closer than the best snapped point so far
             if (i == sp_list.begin() || bestSnappedPoint.isOtherSnapBetter(*i, false)) {
@@ -1054,7 +1055,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p,
 void SnapManager::setup(SPDesktop const *desktop,
                         bool snapindicator,
                         SPItem const *item_to_ignore,
-                        std::vector<std::pair<Geom::Point, int> > *unselected_nodes,
+                        std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes,
                         SPGuide *guide_to_ignore)
 {
     g_assert(desktop != NULL);
@@ -1085,7 +1086,7 @@ void SnapManager::setup(SPDesktop const *desktop,
 void SnapManager::setup(SPDesktop const *desktop,
                         bool snapindicator,
                         std::vector<SPItem const *> &items_to_ignore,
-                        std::vector<std::pair<Geom::Point, int> > *unselected_nodes,
+                        std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes,
                         SPGuide *guide_to_ignore)
 {
     g_assert(desktop != NULL);
@@ -1114,7 +1115,7 @@ SPDocument *SnapManager::getDocument() const
  * \return The position of the point after transformation
  */
 
-Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
+Geom::Point SnapManager::_transformPoint(Inkscape::SnapCandidatePoint const &p,
                                         Transformation const transformation_type,
                                         Geom::Point const &transformation,
                                         Geom::Point const &origin,
@@ -1125,10 +1126,10 @@ Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
     Geom::Point transformed;
     switch (transformation_type) {
         case TRANSLATION:
-            transformed = p.first + transformation;
+            transformed = p.getPoint() + transformation;
             break;
         case SCALE:
-            transformed = (p.first - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
+            transformed = (p.getPoint() - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
             break;
         case STRETCH:
         {
@@ -1139,15 +1140,15 @@ Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
                 s[dim] = transformation[dim];
                 s[1 - dim] = 1;
             }
-            transformed = ((p.first - origin) * s) + origin;
+            transformed = ((p.getPoint() - origin) * s) + origin;
             break;
         }
         case SKEW:
             // Apply the skew factor
-            transformed[dim] = (p.first)[dim] + transformation[0] * ((p.first)[1 - dim] - origin[1 - dim]);
+            transformed[dim] = (p.getPoint())[dim] + transformation[0] * ((p.getPoint())[1 - dim] - origin[1 - dim]);
             // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed.
             // Apply that scale factor here
-            transformed[1-dim] = (p.first - origin)[1 - dim] * transformation[1] + origin[1 - dim];
+            transformed[1-dim] = (p.getPoint() - origin)[1 - dim] * transformation[1] + origin[1 - dim];
             break;
         default:
             g_assert_not_reached();
@@ -1163,7 +1164,7 @@ Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
  * \param p The transformed position of the source point, paired with an identifier of the type of the snap source.
  */
 
-void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const {
+void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Inkscape::SnapCandidatePoint const &p) const {
 
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     if (prefs->getBool("/options/snapclosestonly/value")) {
index 413b753d125d6f14f24b5725fb69f9bc7ee55697..40bf0996eab577f9833f073fcd0e90330d667d61 100644 (file)
@@ -20,7 +20,7 @@
  *
  * Copyright (C) 2006-2007 Johan Engelen <johan@shouraizou.nl>
  * Copyright (C) 2000-2002 Lauris Kaplinski
- * Copyright (C) 2000-2009 Authors
+ * Copyright (C) 2000-2010 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -69,13 +69,13 @@ public:
     void setup(SPDesktop const *desktop,
             bool snapindicator = true,
             SPItem const *item_to_ignore = NULL,
-            std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL,
+            std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
             SPGuide *guide_to_ignore = NULL);
 
     void setup(SPDesktop const *desktop,
             bool snapindicator,
             std::vector<SPItem const *> &items_to_ignore,
-            std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL,
+            std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
             SPGuide *guide_to_ignore = NULL);
 
     // freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a
@@ -83,14 +83,10 @@ public:
     void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
                                 Geom::Point &p,
                                 Inkscape::SnapSourceType const source_type,
-                                long source_num = 0,
                                 Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
-
-    Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type,
-                                    Geom::Point const &p,
-                                    Inkscape::SnapSourceType const &source_type,
-                                    long source_num = 0,
+    Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType const point_type,
+                                    Inkscape::SnapCandidatePoint const &p,
                                     Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const;
 
     Geom::Point multipleOfGridPitch(Geom::Point const &t) const;
@@ -101,44 +97,41 @@ public:
                                     Geom::Point &p,
                                     Inkscape::SnapSourceType const source_type,
                                     Inkscape::Snapper::ConstraintLine const &constraint,
-                                    long source_num = 0,
                                     Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
-    Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
-                                           Geom::Point const &p,
-                                           Inkscape::SnapSourceType const &source_type,
+    Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType const point_type,
+                                           Inkscape::SnapCandidatePoint const &p,
                                            Inkscape::Snapper::ConstraintLine const &constraint,
-                                           long source_num = 0,
                                            Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
     void guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, SPGuideDragType drag_type) const;
     void guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const;
 
     Inkscape::SnappedPoint freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                               std::vector<std::pair<Geom::Point, int> > const &p,
+                                               std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                Geom::Point const &pointer,
                                                Geom::Point const &tr) const;
 
     Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                      std::vector<std::pair<Geom::Point, int> > const &p,
+                                                      std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                       Geom::Point const &pointer,
                                                       Inkscape::Snapper::ConstraintLine const &constraint,
                                                       Geom::Point const &tr) const;
 
     Inkscape::SnappedPoint freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                         std::vector<std::pair<Geom::Point, int> > const &p,
+                                         std::vector<Inkscape::SnapCandidatePoint> const &p,
                                          Geom::Point const &pointer,
                                          Geom::Scale const &s,
                                          Geom::Point const &o) const;
 
     Inkscape::SnappedPoint constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                std::vector<std::pair<Geom::Point, int> > const &p,
+                                                std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                 Geom::Point const &pointer,
                                                 Geom::Scale const &s,
                                                 Geom::Point const &o) const;
 
     Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
-                                                  std::vector<std::pair<Geom::Point, int> > const &p,
+                                                  std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                   Geom::Point const &pointer,
                                                   Geom::Coord const &s,
                                                   Geom::Point const &o,
@@ -146,7 +139,7 @@ public:
                                                   bool uniform) const;
 
     Inkscape::SnappedPoint constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
-                                               std::vector<std::pair<Geom::Point, int> > const &p,
+                                               std::vector<Inkscape::SnapCandidatePoint> const &p,
                                                Geom::Point const &pointer,
                                                Inkscape::Snapper::ConstraintLine const &constraint,
                                                Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor
@@ -167,7 +160,7 @@ public:
 
     bool getSnapIndicator() const {return _snapindicator;}
 
-    Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained, bool noCurves = false) const;
+    Inkscape::SnappedPoint findBestSnap(Inkscape::SnapCandidatePoint const &p, SnappedConstraints const &sc, bool constrained, bool noCurves = false) const;
 
 protected:
     SPNamedView const *_named_view;
@@ -178,13 +171,13 @@ private:
     SPGuide *_guide_to_ignore; ///< A guide that should not be snapped to, e.g. the guide that is currently being dragged
     SPDesktop const *_desktop;
     bool _snapindicator; ///< When true, an indicator will be drawn at the position that was being snapped to
-    std::vector<std::pair<Geom::Point, int> > *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored
+    std::vector<Inkscape::SnapCandidatePoint> *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored
     //TODO: Make _unselected_nodes type safe; in the line above int is used for Inkscape::SnapTargetType, but if I remember
     //correctly then in other cases the int is being used for Inkscape::SnapSourceType, or for both. How to make
     //this type safe?
 
     Inkscape::SnappedPoint _snapTransformed(Inkscape::SnapPreferences::PointType type,
-                                            std::vector<std::pair<Geom::Point, int> > const &points,
+                                            std::vector<Inkscape::SnapCandidatePoint> const &points,
                                             Geom::Point const &pointer,
                                             bool constrained,
                                             Inkscape::Snapper::ConstraintLine const &constraint,
@@ -194,14 +187,14 @@ private:
                                             Geom::Dim2 dim,
                                             bool uniform) const;
 
-    Geom::Point _transformPoint(std::pair<Geom::Point, int> const &p,
+    Geom::Point _transformPoint(Inkscape::SnapCandidatePoint const &p,
                                             Transformation const transformation_type,
                                             Geom::Point const &transformation,
                                             Geom::Point const &origin,
                                             Geom::Dim2 const dim,
                                             bool const uniform) const;
 
-    void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const;
+    void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Inkscape::SnapCandidatePoint const &p) const;
 };
 
 #endif /* !SEEN_SNAP_H */
index 102e761b9ef2cadcb319ab0dcd7d64fe205d89da..e3559d655f96821baf97903962a832f2f6bff030 100644 (file)
@@ -25,6 +25,24 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
+    _target_bbox = Geom::Rect();
+}
+
+Inkscape::SnappedPoint::SnappedPoint(Inkscape::SnapCandidatePoint const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
+    : _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
+{
+    _point = p.getPoint();
+    _source = p.getSourceType();
+    _source_num = p.getSourceNum();
+    _at_intersection = false;
+    _fully_constrained = fully_constrained;
+    _second_distance = NR_HUGE;
+    _second_tolerance = 1;
+    _second_always_snap = false;
+    _transformation = Geom::Point(1,1);
+    _pointer_distance = NR_HUGE;
+    _target_bbox = Geom::Rect();
+
 }
 
 Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2)
@@ -35,6 +53,7 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const
     // isOtherSnapBetter. We don't want a division by zero.
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
+    _target_bbox = Geom::Rect();
 }
 
 Inkscape::SnappedPoint::SnappedPoint()
@@ -53,6 +72,26 @@ Inkscape::SnappedPoint::SnappedPoint()
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
+    _target_bbox = Geom::Rect();
+}
+
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p)
+{
+    _point = p;
+    _source = SNAPSOURCE_UNDEFINED,
+    _source_num = 0,
+    _target = SNAPTARGET_UNDEFINED,
+    _at_intersection = false;
+    _fully_constrained = false;
+    _distance = NR_HUGE;
+    _tolerance = 1;
+    _always_snap = false;
+    _second_distance = NR_HUGE;
+    _second_tolerance = 1;
+    _second_always_snap = false;
+    _transformation = Geom::Point(1,1);
+    _pointer_distance = NR_HUGE;
+    _target_bbox = Geom::Rect();
 }
 
 Inkscape::SnappedPoint::~SnappedPoint()
@@ -69,7 +108,7 @@ void Inkscape::SnappedPoint::getPoint(Geom::Point &p) const
 }
 
 // search for the closest snapped point
-bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoint &result)
+bool getClosestSP(std::list<Inkscape::SnappedPoint> const &list, Inkscape::SnappedPoint &result)
 {
     bool success = false;
 
@@ -86,6 +125,10 @@ bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoin
 bool Inkscape::SnappedPoint::isOtherSnapBetter(Inkscape::SnappedPoint const &other_one, bool weighted) const
 {
 
+    if (!other_one.getSnapped()) {
+        return false;
+    }
+
     double dist_other = other_one.getSnapDistance();
     double dist_this = getSnapDistance();
 
index c793ffa8d97ca5141728817fb2a0010551e603a7..1497802c089048acde7d80c5f1afd3cd7f782a53 100644 (file)
 #include <list>
 #include <libnr/nr-values.h> //Because of NR_HUGE
 #include <2geom/geom.h>
+#include <snap-candidate.h>
 
 namespace Inkscape
 {
 
-enum SnapTargetType {
-    SNAPTARGET_UNDEFINED = 0,
-    SNAPTARGET_GRID,
-    SNAPTARGET_GRID_INTERSECTION,
-    SNAPTARGET_GUIDE,
-    SNAPTARGET_GUIDE_INTERSECTION,
-    SNAPTARGET_GUIDE_ORIGIN,
-    SNAPTARGET_GRID_GUIDE_INTERSECTION,
-    SNAPTARGET_NODE_SMOOTH,
-    SNAPTARGET_NODE_CUSP,
-    SNAPTARGET_LINE_MIDPOINT,
-    SNAPTARGET_OBJECT_MIDPOINT,
-    SNAPTARGET_ROTATION_CENTER,
-    SNAPTARGET_HANDLE,
-    SNAPTARGET_PATH,
-    SNAPTARGET_PATH_INTERSECTION,
-    SNAPTARGET_BBOX_CORNER,
-    SNAPTARGET_BBOX_EDGE,
-    SNAPTARGET_BBOX_EDGE_MIDPOINT,
-    SNAPTARGET_BBOX_MIDPOINT,
-    SNAPTARGET_PAGE_BORDER,
-    SNAPTARGET_PAGE_CORNER,
-    SNAPTARGET_CONVEX_HULL_CORNER,
-    SNAPTARGET_ELLIPSE_QUADRANT_POINT,
-    SNAPTARGET_CENTER, // of ellipse
-    SNAPTARGET_CORNER, // of image or of rectangle
-    SNAPTARGET_TEXT_BASELINE,
-    SNAPTARGET_CONSTRAINED_ANGLE
-};
-
-enum SnapSourceType {
-    SNAPSOURCE_UNDEFINED = 0,
-    SNAPSOURCE_BBOX_CORNER,
-    SNAPSOURCE_BBOX_MIDPOINT,
-    SNAPSOURCE_BBOX_EDGE_MIDPOINT,
-    SNAPSOURCE_NODE_SMOOTH,
-    SNAPSOURCE_NODE_CUSP,
-    SNAPSOURCE_LINE_MIDPOINT,
-    SNAPSOURCE_OBJECT_MIDPOINT,
-    SNAPSOURCE_ROTATION_CENTER,
-    SNAPSOURCE_HANDLE,
-    SNAPSOURCE_PATH_INTERSECTION,
-    SNAPSOURCE_GUIDE,
-    SNAPSOURCE_GUIDE_ORIGIN,
-    SNAPSOURCE_CONVEX_HULL_CORNER,
-    SNAPSOURCE_ELLIPSE_QUADRANT_POINT,
-    SNAPSOURCE_CENTER, // of ellipse
-    SNAPSOURCE_CORNER, // of image or of rectangle
-    SNAPSOURCE_TEXT_BASELINE
-};
-
-
 /// Class describing the result of an attempt to snap.
 class SnappedPoint
 {
 
 public:
     SnappedPoint();
+    SnappedPoint(Geom::Point const &p);
     SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2);
     SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
+    SnappedPoint(SnapCandidatePoint const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
     ~SnappedPoint();
 
     Geom::Coord getSnapDistance() const {return _distance;}
@@ -114,6 +65,8 @@ public:
     void setTransformation(Geom::Point const t) {_transformation = t;}
     void setTarget(SnapTargetType const target) {_target = target;}
     SnapTargetType getTarget() const {return _target;}
+    void setTargetBBox(Geom::Rect const target) {_target_bbox = target;}
+    Geom::Rect & getTargetBBox() {return _target_bbox;}
     void setSource(SnapSourceType const source) {_source = source;}
     SnapSourceType getSource() const {return _source;}
     long getSourceNum() const {return _source_num;}
@@ -164,13 +117,15 @@ protected:
     bool _second_always_snap;
     /* The transformation (translation, scale, skew, or stretch) from the original point to the snapped point */
     Geom::Point _transformation;
+    /* The bounding box we've snapped to (when applicable); will be used by the snapindicator */
+    Geom::Rect _target_bbox;
     /* Distance from the un-transformed point to the mouse pointer, measured at the point in time when dragging started */
     Geom::Coord _pointer_distance;
 };
 
 }// end of namespace Inkscape
 
-bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoint &result);
+bool getClosestSP(std::list<Inkscape::SnappedPoint> const &list, Inkscape::SnappedPoint &result);
 
 #endif /* !SEEN_SNAPPEDPOINT_H */
 
index 751b663e30f8393fbc83dc0d5f211a6fc892abe1..fb7281c30bfb14647ab83f69b7cf5aa8bd4ffa8d 100644 (file)
@@ -19,9 +19,9 @@
  *  \param d Snap tolerance.
  */
 Inkscape::Snapper::Snapper(SnapManager *sm, Geom::Coord const /*t*/) :
-       _snapmanager(sm),
-       _snap_enabled(true),
-       _snap_visible_only(true)
+    _snapmanager(sm),
+    _snap_enabled(true),
+    _snap_visible_only(true)
 {
     g_assert(_snapmanager != NULL);
 }
index dcc0fbb8146499662c2a49794a7298b9ce80057d..dbbf7ebe9477b790459f1242e9b86030a9f8cfa5 100644 (file)
@@ -20,6 +20,7 @@
 #include "snapped-line.h"
 #include "snapped-curve.h"
 #include "snap-preferences.h"
+#include "snap-candidate.h"
 
 struct SnappedConstraints {
     std::list<Inkscape::SnappedPoint> points;
@@ -34,7 +35,6 @@ struct SPItem;
 
 namespace Inkscape
 {
-
 /// Parent for classes that can snap points to something
 class Snapper
 {
@@ -59,12 +59,10 @@ public:
 
     virtual void freeSnap(SnappedConstraints &/*sc*/,
                           SnapPreferences::PointType const &/*t*/,
-                          Geom::Point const &/*p*/,
-                          SnapSourceType const &/*source_type*/,
-                          long /*source_num*/,
+                          Inkscape::SnapCandidatePoint const &/*p*/,
                           Geom::OptRect const &/*bbox_to_snap*/,
                           std::vector<SPItem const *> const */*it*/,
-                          std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const {};
+                          std::vector<SnapCandidatePoint> */*unselected_nodes*/) const {};
 
     class ConstraintLine
     {
@@ -104,9 +102,7 @@ public:
 
     virtual void constrainedSnap(SnappedConstraints &/*sc*/,
                                  SnapPreferences::PointType const &/*t*/,
-                                 Geom::Point const &/*p*/,
-                                 SnapSourceType const &/*source_type*/,
-                                 long /*source_num*/,
+                                 Inkscape::SnapCandidatePoint const &/*p*/,
                                  Geom::OptRect const &/*bbox_to_snap*/,
                                  ConstraintLine const &/*c*/,
                                  std::vector<SPItem const *> const */*it*/) const {};
index 12ba0ed0e05f2bd54e3e23890b9b8dca12792ff7..88fc59f17d12543bcb1fbe8b73d7df16aadd4b7d 100644 (file)
 #include <glibmm/i18n.h>
 #include <2geom/transforms.h>
 #include <2geom/pathvector.h>
-
 #include "document.h"
 #include "sp-ellipse.h"
-
 #include "preferences.h"
+#include "snap-candidate.h"
 
 /* Common parent class */
 
@@ -73,7 +72,7 @@ static void sp_genericellipse_init(SPGenericEllipse *ellipse);
 
 static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags);
 
-static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_genericellipse_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_genericellipse_set_shape(SPShape *shape);
 static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -270,15 +269,15 @@ static void sp_genericellipse_set_shape(SPShape *shape)
     curve->unref();
 }
 
-static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_genericellipse_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_GENERICELLIPSE(item));
 
     // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
-       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
-               return;
-       }
+    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+        return;
+    }
 
     SPGenericEllipse *ellipse = SP_GENERICELLIPSE(item);
     sp_genericellipse_normalize(ellipse);
@@ -305,19 +304,19 @@ static void sp_genericellipse_snappoints(SPItem const *item, bool const target,
     // Snap to the 4 quadrant points of the ellipse, but only if the arc
     // spans far enough to include them
     if (snapprefs->getSnapToItemNode()) { //TODO: Make a separate snap option toggle for this?
-               double angle = 0;
-               for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
-                       if (angle >= ellipse->start && angle <= ellipse->end) {
-                               pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
-                               p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT) : int(Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT)));
-                       }
-               }
+        double angle = 0;
+        for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
+            if (angle >= ellipse->start && angle <= ellipse->end) {
+                pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+                p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT, Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT));
+            }
+        }
     }
 
     // Add the centre, if we have a closed slice or when explicitly asked for
     if ((snapprefs->getSnapToItemNode() && slice && ellipse->closed) || snapprefs->getSnapObjectMidpoints()) {
-       pt = Geom::Point(cx, cy) * i2d;
-       p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_CENTER) : int(Inkscape::SNAPSOURCE_CENTER)));
+        pt = Geom::Point(cx, cy) * i2d;
+        p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_CENTER, Inkscape::SNAPTARGET_CENTER));
     }
 
     // And if we have a slice, also snap to the endpoints
@@ -325,12 +324,12 @@ static void sp_genericellipse_snappoints(SPItem const *item, bool const target,
         // Add the start point, if it's not coincident with a quadrant point
         if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
             pt = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
-            p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
+            p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
         }
         // Add the end point, if it's not coincident with a quadrant point
         if (fmod(ellipse->end, M_PI_2) != 0.0 ) {
             pt = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
-            p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
+            p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
         }
     }
 }
index 53bcd425db5916718ba4d13679614310615cde5d..b01146d60a3797408a608e4f7f058e717e0aa9fc 100644 (file)
@@ -49,7 +49,7 @@ static void sp_flowtext_set(SPObject *object, unsigned key, gchar const *value);
 static void sp_flowtext_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
 static void sp_flowtext_print(SPItem *item, SPPrintContext *ctx);
 static gchar *sp_flowtext_description(SPItem *item);
-static void sp_flowtext_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_flowtext_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 static NRArenaItem *sp_flowtext_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags);
 static void sp_flowtext_hide(SPItem *item, unsigned key);
 
@@ -384,7 +384,7 @@ static gchar *sp_flowtext_description(SPItem *item)
     }
 }
 
-static void sp_flowtext_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_flowtext_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     // Choose a point on the baseline for snapping from or to, with the horizontal position
     // of this point depending on the text alignment (left vs. right)
@@ -392,8 +392,7 @@ static void sp_flowtext_snappoints(SPItem const *item, bool const target, SnapPo
     if (layout != NULL && layout->outputExists()) {
         boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
         if (pt) {
-            int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE);
-            p.push_back(std::make_pair((*pt) * sp_item_i2d_affine(item), type));
+            p.push_back(Inkscape::SnapCandidatePoint((*pt) * sp_item_i2d_affine(item), Inkscape::SNAPSOURCE_TEXT_BASELINE, Inkscape::SNAPTARGET_TEXT_BASELINE));
         }
     }
 }
index e3f70814269a6b1f1672995bbd927f5a86be4ebd..daf5e9e88577c98ac51fd2677973a6fb6c78ed39 100644 (file)
@@ -44,7 +44,7 @@
 #include <glibmm/i18n.h>
 #include "xml/quote.h"
 #include <xml/repr.h>
-
+#include "snap-candidate.h"
 #include "libnr/nr-matrix-fns.h"
 
 #include "io/sys.h"
@@ -86,7 +86,7 @@ static Inkscape::XML::Node *sp_image_write (SPObject *object, Inkscape::XML::Doc
 static void sp_image_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
 static void sp_image_print (SPItem * item, SPPrintContext *ctx);
 static gchar * sp_image_description (SPItem * item);
-static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_image_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static Geom::Matrix sp_image_set_transform (SPItem *item, Geom::Matrix const &xform);
 static void sp_image_set_curve(SPImage *image);
@@ -1332,7 +1332,7 @@ sp_image_update_canvas_image (SPImage *image)
     }
 }
 
-static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_image_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     /* An image doesn't have any nodes to snap, but still we want to be able snap one image
     to another. Therefore we will create some snappoints at the corner, similar to a rect. If
@@ -1354,12 +1354,10 @@ static void sp_image_snappoints(SPItem const *item, bool const target, SnapPoint
         double const x1 = x0 + image.width.computed;
         double const y1 = y0 + image.height.computed;
         Geom::Matrix const i2d (sp_item_i2d_affine (item));
-        Geom::Point pt;
-        int type = target ? int(Inkscape::SNAPTARGET_CORNER) : int(Inkscape::SNAPSOURCE_CORNER);
-        p.push_back(std::make_pair(Geom::Point(x0, y0) * i2d, type));
-        p.push_back(std::make_pair(Geom::Point(x0, y1) * i2d, type));
-        p.push_back(std::make_pair(Geom::Point(x1, y1) * i2d, type));
-        p.push_back(std::make_pair(Geom::Point(x1, y0) * i2d, type));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x0, y0) * i2d, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x0, y1) * i2d, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x1, y1) * i2d, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(x1, y0) * i2d, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
     }
 }
 
index 3845be23219b8ceb8e51a69cafa1f403e42dd6ff..a773bd4a24df825b54f987dce126f3dace9c072a 100644 (file)
@@ -69,7 +69,7 @@ static void sp_group_print (SPItem * item, SPPrintContext *ctx);
 static gchar * sp_group_description (SPItem * item);
 static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static void sp_group_hide (SPItem * item, unsigned int key);
-static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_group_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_group_update_patheffect(SPLPEItem *lpeitem, bool write);
 static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write);
@@ -320,14 +320,14 @@ sp_group_hide (SPItem *item, unsigned int key)
     SP_GROUP(item)->group->hide(key);
 }
 
-static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_group_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     for (SPObject const *o = sp_object_first_child(SP_OBJECT(item));
          o != NULL;
          o = SP_OBJECT_NEXT(o))
     {
         if (SP_IS_ITEM(o)) {
-            sp_item_snappoints(SP_ITEM(o), target, p, snapprefs);
+            sp_item_snappoints(SP_ITEM(o), p, snapprefs);
         }
     }
 }
index 0bc08a2355d84f9ad0fb5143b3b0ce8fb7ddd226..628d7795643f0eaec41b9b48846bae32b953bc39 100644 (file)
@@ -24,11 +24,11 @@ void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoin
     double const dir_lensq(dot(dir, dir));
     g_return_if_fail( dir_lensq != 0 );
 
-    SnapPointsWithType snappoints;
-    sp_item_snappoints(&item, false, snappoints, NULL);
+    std::vector<Inkscape::SnapCandidatePoint> snappoints;
+    sp_item_snappoints(&item, snappoints, NULL);
     g_return_if_fail( snappoint_ix < int(snappoints.size()) );
 
-    double const pos0 = dot(dir, snappoints[snappoint_ix].first);
+    double const pos0 = dot(dir, snappoints[snappoint_ix].getPoint());
     /// \todo effic: skip if mv_g is already satisfied.
 
     /* Translate along dir to make dot(dir, snappoints(item)[snappoint_ix]) == position. */
index 2464532413d2a32cf687267fe0471d53b4df05f4..792a9d3bf046f2cd47373408eb9afdcf4f2e90b5 100644 (file)
@@ -14,14 +14,14 @@ void sp_item_rm_unsatisfied_cns(SPItem &item)
     if (item.constraints.empty()) {
         return;
     }
-    SnapPointsWithType snappoints;
-    sp_item_snappoints(&item, false, snappoints, NULL);
+    std::vector<Inkscape::SnapCandidatePoint> snappoints;
+    sp_item_snappoints(&item, snappoints, NULL);
     for (unsigned i = item.constraints.size(); i--;) {
         g_assert( i < item.constraints.size() );
         SPGuideConstraint const &cn = item.constraints[i];
         int const snappoint_ix = cn.snappoint_ix;
         g_assert( snappoint_ix < int(snappoints.size()) );
-        if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix].first), 0) ) {
+        if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix].getPoint()), 0) ) {
             remove_last(cn.g->attached_items, SPGuideAttachment(&item, cn.snappoint_ix));
             g_assert( i < item.constraints.size() );
             vector<SPGuideConstraint>::iterator const ei(&item.constraints[i]);
index bebd6502199dab5b9939e014c976d9191a079875..51da1679d344255eca65864de1536070f7c98b5b 100644 (file)
@@ -9,8 +9,8 @@ using std::vector;
 
 void sp_item_update_cns(SPItem &item, SPDesktop const &desktop)
 {
-    SnapPointsWithType snappoints;
-    sp_item_snappoints(&item, false, snappoints, NULL);
+    std::vector<Inkscape::SnapCandidatePoint> snappoints;
+    sp_item_snappoints(&item, snappoints, NULL);
     /* TODO: Implement the ordering. */
     vector<SPGuideConstraint> found_cns;
     satisfied_guide_cns(desktop, snappoints, found_cns);
index 1a5ca6f772a72f7ba94fd99c153062bdabf9502b..c28940fca6af8ee9ba3153ddf2320931763f4ad6 100644 (file)
@@ -90,7 +90,7 @@ static void sp_item_update(SPObject *object, SPCtx *ctx, guint flags);
 static Inkscape::XML::Node *sp_item_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
 
 static gchar *sp_item_private_description(SPItem *item);
-static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_item_private_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem);
 static SPItemView *sp_item_view_list_remove(SPItemView *list, SPItemView *view);
@@ -949,7 +949,7 @@ Geom::OptRect sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type)
     return rect;
 }
 
-static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_item_private_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     /* This will only be called if the derived class doesn't override this.
      * see for example sp_genericellipse_snappoints in sp-ellipse.cpp
@@ -962,16 +962,15 @@ static void sp_item_private_snappoints(SPItem const *item, bool const target, Sn
         Geom::Point p1, p2;
         p1 = bbox->min();
         p2 = bbox->max();
-        int type = target ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER);
-        p.push_back(std::make_pair(p1, type));
-        p.push_back(std::make_pair(Geom::Point(p1[Geom::X], p2[Geom::Y]), type));
-        p.push_back(std::make_pair(p2, type));
-        p.push_back(std::make_pair(Geom::Point(p2[Geom::X], p1[Geom::Y]), type));
+        p.push_back(Inkscape::SnapCandidatePoint(p1, Inkscape::SNAPSOURCE_BBOX_CORNER, Inkscape::SNAPTARGET_BBOX_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(p1[Geom::X], p2[Geom::Y]), Inkscape::SNAPSOURCE_BBOX_CORNER, Inkscape::SNAPTARGET_BBOX_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(p2, Inkscape::SNAPSOURCE_BBOX_CORNER, Inkscape::SNAPTARGET_BBOX_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(p2[Geom::X], p1[Geom::Y]), Inkscape::SNAPSOURCE_BBOX_CORNER, Inkscape::SNAPTARGET_BBOX_CORNER));
     }
 
 }
 
-void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+void sp_item_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert (item != NULL);
     g_assert (SP_IS_ITEM(item));
@@ -979,12 +978,12 @@ void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithTyp
     // Get the snappoints of the item
     SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(item);
     if (item_class.snappoints) {
-        item_class.snappoints(item, target, p, snapprefs);
+        item_class.snappoints(item, p, snapprefs);
     }
 
     // Get the snappoints at the item's center
     if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-       p.push_back(std::make_pair(item->getCenter(), target ? int(Inkscape::SNAPTARGET_ROTATION_CENTER) : int(Inkscape::SNAPSOURCE_ROTATION_CENTER)));
+        p.push_back(Inkscape::SnapCandidatePoint(item->getCenter(), Inkscape::SNAPSOURCE_ROTATION_CENTER, Inkscape::SNAPTARGET_ROTATION_CENTER));
     }
 
     // Get the snappoints of clipping paths and mask, if any
@@ -999,15 +998,15 @@ void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithTyp
             // obj is a group object, the children are the actual clippers
             for (SPObject *child = (*o)->children ; child ; child = child->next) {
                 if (SP_IS_ITEM(child)) {
-                       SnapPointsWithType p_clip_or_mask;
+                    std::vector<Inkscape::SnapCandidatePoint> p_clip_or_mask;
                     // Please note the recursive call here!
-                    sp_item_snappoints(SP_ITEM(child), target, p_clip_or_mask, snapprefs);
+                    sp_item_snappoints(SP_ITEM(child), p_clip_or_mask, snapprefs);
                     // Take into account the transformation of the item being clipped or masked
-                    for (SnapPointsWithType::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
+                    for (std::vector<Inkscape::SnapCandidatePoint>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
                         // All snappoints are in desktop coordinates, but the item's transformation is
                         // in document coordinates. Hence the awkward construction below
-                        Geom::Point pt = desktop->dt2doc((*p_orig).first) * sp_item_i2d_affine(item);
-                        p.push_back(std::make_pair(pt, (*p_orig).second));
+                        Geom::Point pt = desktop->dt2doc((*p_orig).getPoint()) * sp_item_i2d_affine(item);
+                        p.push_back(Inkscape::SnapCandidatePoint(pt, (*p_orig).getSourceType(), (*p_orig).getTargetType()));
                     }
                 }
             }
index 639a1b4a2a18d1d0c601cc41706281ce25d9a04d..faf64846e4ae40691f8ef807364fb734e1106d80 100644 (file)
 #include <2geom/forward.h>
 #include <libnr/nr-convert2geom.h>
 #include <snap-preferences.h>
-#include <snapped-point.h>
+#include "snap-candidate.h"
 
 class SPGuideConstraint;
 struct SPClipPathReference;
 struct SPMaskReference;
 struct SPAvoidRef;
 struct SPPrintContext;
-namespace Inkscape { class URIReference; }
+namespace Inkscape { class URIReference;}
 
 enum {
     SP_EVENT_INVALID,
@@ -171,8 +171,6 @@ private:
     mutable EvaluatedStatus _evaluated_status;
 };
 
-typedef std::vector<std::pair<Geom::Point, int> > SnapPointsWithType; // int is either of these enums: Inkscape::SnapTargetType or Inkscape::SnapSourceType
-
 /// The SPItem vtable.
 struct SPItemClass {
     SPObjectClass parent_class;
@@ -193,7 +191,7 @@ struct SPItemClass {
     /** Write to an iterator the points that should be considered for snapping
      * as the item's `nodes'.
      */
-    void (* snappoints) (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+    void (* snappoints) (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
     /** Apply the transform optimally, and return any residual transformation */
     Geom::Matrix (* set_transform)(SPItem *item, Geom::Matrix const &transform);
@@ -226,7 +224,7 @@ unsigned int sp_item_display_key_new(unsigned int numkeys);
 NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 void sp_item_invoke_hide(SPItem *item, unsigned int key);
 
-void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+void sp_item_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 void sp_item_adjust_pattern(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
 void sp_item_adjust_gradient(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
index ae0f7bf19ea48bebe09cc7ccf91f12f6958aff74..556778676cd2ada7055f69738aa946ef919bc5f2 100644 (file)
@@ -83,7 +83,7 @@ static void sp_offset_update (SPObject * object, SPCtx * ctx, guint flags);
 static void sp_offset_release (SPObject * object);
 
 static gchar *sp_offset_description (SPItem * item);
-static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_offset_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 static void sp_offset_set_shape (SPShape * shape);
 
 static void refresh_offset_source(SPOffset* offset);
@@ -718,10 +718,10 @@ sp_offset_set_shape(SPShape *shape)
 /**
  * Virtual snappoints function.
  */
-static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_offset_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     if (((SPItemClass *) parent_class)->snappoints) {
-        ((SPItemClass *) parent_class)->snappoints (item, target, p, snapprefs);
+        ((SPItemClass *) parent_class)->snappoints (item, p, snapprefs);
     }
 }
 
index aa026abb3eab890ab17824a6b3a06fd275de0661..d42fd0e9f3d30b74b0320b03e9e122b98dc3f58b 100644 (file)
@@ -46,7 +46,7 @@ static Geom::Matrix sp_rect_set_transform(SPItem *item, Geom::Matrix const &xfor
 static void sp_rect_convert_to_guides(SPItem *item);
 
 static void sp_rect_set_shape(SPShape *shape);
-static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_rect_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static SPShapeClass *parent_class;
 
@@ -552,7 +552,7 @@ sp_rect_get_visible_height(SPRect *rect)
 /**
  * Sets the snappoint p to the unrounded corners of the rectangle
  */
-static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_rect_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     /* This method overrides sp_shape_snappoints, which is the default for any shape. The default method
     returns all eight points along the path of a rounded rectangle, but not the real corners. Snapping
@@ -565,9 +565,9 @@ static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPoints
     g_assert(SP_IS_RECT(item));
 
     // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
-       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
-               return;
-       }
+    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+        return;
+    }
 
     SPRect *rect = SP_RECT(item);
 
@@ -578,28 +578,23 @@ static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPoints
     Geom::Point p2 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d;
     Geom::Point p3 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
 
-    int type;
-
     if (snapprefs->getSnapToItemNode()) {
-       type = target ? int(Inkscape::SNAPTARGET_CORNER) : int(Inkscape::SNAPSOURCE_CORNER);
-       p.push_back(std::make_pair(p0, type));
-       p.push_back(std::make_pair(p1, type));
-       p.push_back(std::make_pair(p2, type));
-       p.push_back(std::make_pair(p3, type));
+        p.push_back(Inkscape::SnapCandidatePoint(p0, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(p1, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(p2, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
+        p.push_back(Inkscape::SnapCandidatePoint(p3, Inkscape::SNAPSOURCE_CORNER, Inkscape::SNAPTARGET_CORNER));
     }
 
-       if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
-               type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
-               p.push_back(std::make_pair((p0 + p1)/2, type));
-               p.push_back(std::make_pair((p1 + p2)/2, type));
-               p.push_back(std::make_pair((p2 + p3)/2, type));
-               p.push_back(std::make_pair((p3 + p0)/2, type));
-       }
-
-       if (snapprefs->getSnapObjectMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
-               type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
-               p.push_back(std::make_pair((p0 + p2)/2, type));
-       }
+    if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+        p.push_back(Inkscape::SnapCandidatePoint((p0 + p1)/2, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+        p.push_back(Inkscape::SnapCandidatePoint((p1 + p2)/2, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+        p.push_back(Inkscape::SnapCandidatePoint((p2 + p3)/2, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+        p.push_back(Inkscape::SnapCandidatePoint((p3 + p0)/2, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+    }
+
+    if (snapprefs->getSnapObjectMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+        p.push_back(Inkscape::SnapCandidatePoint((p0 + p2)/2, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
+    }
 
 }
 
index 519002e9e1b43c6944a890fcb02b499da2ed1800..de564813720785f7671fb1a8b66885bfc7b07a3a 100644 (file)
@@ -68,7 +68,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &
 void sp_shape_print (SPItem * item, SPPrintContext * ctx);
 static NRArenaItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static void sp_shape_hide (SPItem *item, unsigned int key);
-static void sp_shape_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_shape_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai);
 
@@ -1149,7 +1149,7 @@ sp_shape_set_curve_insync (SPShape *shape, SPCurve *curve, unsigned int owner)
 /**
  * Return all nodes in a path that are to be considered for snapping
  */
-static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_shape_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_SHAPE(item));
@@ -1161,7 +1161,7 @@ static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPoint
 
     // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
     if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
-       return;
+        return;
     }
 
     Geom::PathVector const &pathv = shape->curve->get_pathvector();
@@ -1170,20 +1170,16 @@ static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPoint
 
     Geom::Matrix const i2d (sp_item_i2d_affine (item));
 
-    int type;
-
-       if (snapprefs->getSnapObjectMidpoints()) {
-               Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item));
-               if (bbox) {
-                       type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
-                       p.push_back(std::make_pair(bbox->midpoint(), type));
-               }
-       }
+    if (snapprefs->getSnapObjectMidpoints()) {
+        Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item));
+        if (bbox) {
+            p.push_back(Inkscape::SnapCandidatePoint(bbox->midpoint(), Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
+        }
+    }
 
     for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
         if (snapprefs->getSnapToItemNode()) {
-               type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
-               p.push_back(std::make_pair(path_it->initialPoint() * i2d, type));
+            p.push_back(Inkscape::SnapCandidatePoint(path_it->initialPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
         }
 
         Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
@@ -1202,17 +1198,15 @@ static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPoint
             bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
 
             if (c1 || c2) {
-               type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
-                               p.push_back(std::make_pair(curve_it1->finalPoint() * i2d, type));
+                p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
             }
 
-                       // Consider midpoints of line segments for snapping
-                       if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
-                               if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
-                                       type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
-                                       p.push_back(std::make_pair(Geom::middle_point(*line_segment) * i2d, type));
-                               }
-                       }
+            // Consider midpoints of line segments for snapping
+            if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+                if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
+                    p.push_back(Inkscape::SnapCandidatePoint(Geom::middle_point(*line_segment) * i2d, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+                }
+            }
 
             ++curve_it1;
             ++curve_it2;
@@ -1226,8 +1220,7 @@ static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPoint
             if (cs.size() > 0) { // There might be multiple intersections...
                 for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); i++) {
                     Geom::Point p_ix = (*path_it).pointAt((*i).ta);
-                    type = target ? int(Inkscape::SNAPTARGET_PATH_INTERSECTION) : int(Inkscape::SNAPSOURCE_PATH_INTERSECTION);
-                    p.push_back(std::make_pair(p_ix * i2d, type));
+                    p.push_back(Inkscape::SnapCandidatePoint(p_ix * i2d, Inkscape::SNAPSOURCE_PATH_INTERSECTION, Inkscape::SNAPTARGET_PATH_INTERSECTION));
                 }
             }
         }
index 6297153327939f3b71f5100d4675add5a31ac9ed..11e84d9b221c7748803ce94f0080d0c9fc98fffb 100644 (file)
@@ -37,7 +37,7 @@ static void sp_spiral_set (SPObject *object, unsigned int key, const gchar *valu
 static void sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags);
 
 static gchar * sp_spiral_description (SPItem * item);
-static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_spiral_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_spiral_set_shape (SPShape *shape);
 static void sp_spiral_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -52,24 +52,24 @@ static SPShapeClass *parent_class;
 GType
 sp_spiral_get_type (void)
 {
-       static GType spiral_type = 0;
-
-       if (!spiral_type) {
-               GTypeInfo spiral_info = {
-                       sizeof (SPSpiralClass),
-                       NULL,   /* base_init */
-                       NULL,   /* base_finalize */
-                       (GClassInitFunc) sp_spiral_class_init,
-                       NULL,   /* class_finalize */
-                       NULL,   /* class_data */
-                       sizeof (SPSpiral),
-                       16,     /* n_preallocs */
-                       (GInstanceInitFunc) sp_spiral_init,
-                       NULL,   /* value_table */
-               };
-               spiral_type = g_type_register_static (SP_TYPE_SHAPE, "SPSpiral", &spiral_info, (GTypeFlags)0);
-       }
-       return spiral_type;
+    static GType spiral_type = 0;
+
+    if (!spiral_type) {
+        GTypeInfo spiral_info = {
+            sizeof (SPSpiralClass),
+            NULL,    /* base_init */
+            NULL,    /* base_finalize */
+            (GClassInitFunc) sp_spiral_class_init,
+            NULL,    /* class_finalize */
+            NULL,    /* class_data */
+            sizeof (SPSpiral),
+            16,    /* n_preallocs */
+            (GInstanceInitFunc) sp_spiral_init,
+            NULL,    /* value_table */
+        };
+        spiral_type = g_type_register_static (SP_TYPE_SHAPE, "SPSpiral", &spiral_info, (GTypeFlags)0);
+    }
+    return spiral_type;
 }
 
 /**
@@ -78,27 +78,27 @@ sp_spiral_get_type (void)
 static void
 sp_spiral_class_init (SPSpiralClass *klass)
 {
-       GObjectClass * gobject_class;
-       SPObjectClass * sp_object_class;
-       SPItemClass * item_class;
-       SPLPEItemClass * lpe_item_class;
-       SPShapeClass *shape_class;
+    GObjectClass * gobject_class;
+    SPObjectClass * sp_object_class;
+    SPItemClass * item_class;
+    SPLPEItemClass * lpe_item_class;
+    SPShapeClass *shape_class;
 
-       gobject_class = (GObjectClass *) klass;
-       sp_object_class = (SPObjectClass *) klass;
-       item_class = (SPItemClass *) klass;
-       lpe_item_class = (SPLPEItemClass *) klass;
-       shape_class = (SPShapeClass *) klass;
+    gobject_class = (GObjectClass *) klass;
+    sp_object_class = (SPObjectClass *) klass;
+    item_class = (SPItemClass *) klass;
+    lpe_item_class = (SPLPEItemClass *) klass;
+    shape_class = (SPShapeClass *) klass;
 
-       parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
+    parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
 
-       sp_object_class->build = sp_spiral_build;
-       sp_object_class->write = sp_spiral_write;
-       sp_object_class->set = sp_spiral_set;
-       sp_object_class->update = sp_spiral_update;
+    sp_object_class->build = sp_spiral_build;
+    sp_object_class->write = sp_spiral_write;
+    sp_object_class->set = sp_spiral_set;
+    sp_object_class->update = sp_spiral_update;
 
-       item_class->description = sp_spiral_description;
-       item_class->snappoints = sp_spiral_snappoints;
+    item_class->description = sp_spiral_description;
+    item_class->snappoints = sp_spiral_snappoints;
 
     lpe_item_class->update_patheffect = sp_spiral_update_patheffect;
 
@@ -111,13 +111,13 @@ sp_spiral_class_init (SPSpiralClass *klass)
 static void
 sp_spiral_init (SPSpiral * spiral)
 {
-       spiral->cx         = 0.0;
-       spiral->cy         = 0.0;
-       spiral->exp        = 1.0;
-       spiral->revo       = 3.0;
-       spiral->rad        = 1.0;
-       spiral->arg        = 0.0;
-       spiral->t0         = 0.0;
+    spiral->cx         = 0.0;
+    spiral->cy         = 0.0;
+    spiral->exp        = 1.0;
+    spiral->revo       = 3.0;
+    spiral->rad        = 1.0;
+    spiral->arg        = 0.0;
+    spiral->t0         = 0.0;
 }
 
 /**
@@ -126,16 +126,16 @@ sp_spiral_init (SPSpiral * spiral)
 static void
 sp_spiral_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr)
 {
-       if (((SPObjectClass *) parent_class)->build)
-               ((SPObjectClass *) parent_class)->build (object, document, repr);
-
-       sp_object_read_attr (object, "sodipodi:cx");
-       sp_object_read_attr (object, "sodipodi:cy");
-       sp_object_read_attr (object, "sodipodi:expansion");
-       sp_object_read_attr (object, "sodipodi:revolution");
-       sp_object_read_attr (object, "sodipodi:radius");
-       sp_object_read_attr (object, "sodipodi:argument");
-       sp_object_read_attr (object, "sodipodi:t0");
+    if (((SPObjectClass *) parent_class)->build)
+        ((SPObjectClass *) parent_class)->build (object, document, repr);
+
+    sp_object_read_attr (object, "sodipodi:cx");
+    sp_object_read_attr (object, "sodipodi:cy");
+    sp_object_read_attr (object, "sodipodi:expansion");
+    sp_object_read_attr (object, "sodipodi:revolution");
+    sp_object_read_attr (object, "sodipodi:radius");
+    sp_object_read_attr (object, "sodipodi:argument");
+    sp_object_read_attr (object, "sodipodi:t0");
 }
 
 /**
@@ -144,25 +144,25 @@ sp_spiral_build (SPObject * object, SPDocument * document, Inkscape::XML::Node *
 static Inkscape::XML::Node *
 sp_spiral_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
 {
-       SPSpiral *spiral = SP_SPIRAL (object);
-
-       if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
-               repr = xml_doc->createElement("svg:path");
-       }
-
-       if (flags & SP_OBJECT_WRITE_EXT) {
-               /* Fixme: we may replace these attributes by
-                * sodipodi:spiral="cx cy exp revo rad arg t0"
-                */
-               repr->setAttribute("sodipodi:type", "spiral");
-               sp_repr_set_svg_double(repr, "sodipodi:cx", spiral->cx);
-               sp_repr_set_svg_double(repr, "sodipodi:cy", spiral->cy);
-               sp_repr_set_svg_double(repr, "sodipodi:expansion", spiral->exp);
-               sp_repr_set_svg_double(repr, "sodipodi:revolution", spiral->revo);
-               sp_repr_set_svg_double(repr, "sodipodi:radius", spiral->rad);
-               sp_repr_set_svg_double(repr, "sodipodi:argument", spiral->arg);
-               sp_repr_set_svg_double(repr, "sodipodi:t0", spiral->t0);
-       }
+    SPSpiral *spiral = SP_SPIRAL (object);
+
+    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+        repr = xml_doc->createElement("svg:path");
+    }
+
+    if (flags & SP_OBJECT_WRITE_EXT) {
+        /* Fixme: we may replace these attributes by
+         * sodipodi:spiral="cx cy exp revo rad arg t0"
+         */
+        repr->setAttribute("sodipodi:type", "spiral");
+        sp_repr_set_svg_double(repr, "sodipodi:cx", spiral->cx);
+        sp_repr_set_svg_double(repr, "sodipodi:cy", spiral->cy);
+        sp_repr_set_svg_double(repr, "sodipodi:expansion", spiral->exp);
+        sp_repr_set_svg_double(repr, "sodipodi:revolution", spiral->revo);
+        sp_repr_set_svg_double(repr, "sodipodi:radius", spiral->rad);
+        sp_repr_set_svg_double(repr, "sodipodi:argument", spiral->arg);
+        sp_repr_set_svg_double(repr, "sodipodi:t0", spiral->t0);
+    }
 
      // make sure the curve is rebuilt with all up-to-date parameters
      sp_spiral_set_shape ((SPShape *) spiral);
@@ -190,61 +190,61 @@ sp_spiral_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::X
 static void
 sp_spiral_set (SPObject *object, unsigned int key, const gchar *value)
 {
-       SPSpiral *spiral;
-       SPShape  *shape;
-
-       spiral = SP_SPIRAL (object);
-       shape  = SP_SHAPE (object);
-
-       /// \todo fixme: we should really collect updates
-       switch (key) {
-       case SP_ATTR_SODIPODI_CX:
-               if (!sp_svg_length_read_computed_absolute (value, &spiral->cx)) {
-                       spiral->cx = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_CY:
-               if (!sp_svg_length_read_computed_absolute (value, &spiral->cy)) {
-                       spiral->cy = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_EXPANSION:
-               if (value) {
-                       /** \todo
+    SPSpiral *spiral;
+    SPShape  *shape;
+
+    spiral = SP_SPIRAL (object);
+    shape  = SP_SHAPE (object);
+
+    /// \todo fixme: we should really collect updates
+    switch (key) {
+    case SP_ATTR_SODIPODI_CX:
+        if (!sp_svg_length_read_computed_absolute (value, &spiral->cx)) {
+            spiral->cx = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_CY:
+        if (!sp_svg_length_read_computed_absolute (value, &spiral->cy)) {
+            spiral->cy = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_EXPANSION:
+        if (value) {
+            /** \todo
                          * FIXME: check that value looks like a (finite)
                          * number. Create a routine that uses strtod, and
                          * accepts a default value (if strtod finds an error).
                          * N.B. atof/sscanf/strtod consider "nan" and "inf"
                          * to be valid numbers.
                          */
-                       spiral->exp = g_ascii_strtod (value, NULL);
-                       spiral->exp = CLAMP (spiral->exp, 0.0, 1000.0);
-               } else {
-                       spiral->exp = 1.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_REVOLUTION:
-               if (value) {
-                       spiral->revo = g_ascii_strtod (value, NULL);
-                       spiral->revo = CLAMP (spiral->revo, 0.05, 1024.0);
-               } else {
-                       spiral->revo = 3.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_RADIUS:
-               if (!sp_svg_length_read_computed_absolute (value, &spiral->rad)) {
-                       spiral->rad = MAX (spiral->rad, 0.001);
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_ARGUMENT:
-               if (value) {
-                       spiral->arg = g_ascii_strtod (value, NULL);
-                       /** \todo
+            spiral->exp = g_ascii_strtod (value, NULL);
+            spiral->exp = CLAMP (spiral->exp, 0.0, 1000.0);
+        } else {
+            spiral->exp = 1.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_REVOLUTION:
+        if (value) {
+            spiral->revo = g_ascii_strtod (value, NULL);
+            spiral->revo = CLAMP (spiral->revo, 0.05, 1024.0);
+        } else {
+            spiral->revo = 3.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_RADIUS:
+        if (!sp_svg_length_read_computed_absolute (value, &spiral->rad)) {
+            spiral->rad = MAX (spiral->rad, 0.001);
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_ARGUMENT:
+        if (value) {
+            spiral->arg = g_ascii_strtod (value, NULL);
+            /** \todo
                          * FIXME: We still need some bounds on arg, for
                          * numerical reasons. E.g., we don't want inf or NaN,
                          * nor near-infinite numbers. I'm inclined to take
@@ -252,32 +252,32 @@ sp_spiral_set (SPObject *object, unsigned int key, const gchar *value)
                          * which use atan2 - revo*2*pi, which typically
                          * results in very negative arg.
                          */
-               } else {
-                       spiral->arg = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_T0:
-               if (value) {
-                       spiral->t0 = g_ascii_strtod (value, NULL);
-                       spiral->t0 = CLAMP (spiral->t0, 0.0, 0.999);
-                       /** \todo
+        } else {
+            spiral->arg = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_T0:
+        if (value) {
+            spiral->t0 = g_ascii_strtod (value, NULL);
+            spiral->t0 = CLAMP (spiral->t0, 0.0, 0.999);
+            /** \todo
                          * Have shared constants for the allowable bounds for
                          * attributes. There was a bug here where we used -1.0
                          * as the minimum (which leads to NaN via, e.g.,
                          * pow(-1.0, 0.5); see sp_spiral_get_xy for
                          * requirements.
                          */
-               } else {
-                       spiral->t0 = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       default:
-               if (((SPObjectClass *) parent_class)->set)
-                       ((SPObjectClass *) parent_class)->set (object, key, value);
-               break;
-       }
+        } else {
+            spiral->t0 = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    default:
+        if (((SPObjectClass *) parent_class)->set)
+            ((SPObjectClass *) parent_class)->set (object, key, value);
+        break;
+    }
 }
 
 /**
@@ -286,12 +286,12 @@ sp_spiral_set (SPObject *object, unsigned int key, const gchar *value)
 static void
 sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags)
 {
-       if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-               sp_shape_set_shape ((SPShape *) object);
-       }
+    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
+        sp_shape_set_shape ((SPShape *) object);
+    }
 
-       if (((SPObjectClass *) parent_class)->update)
-               ((SPObjectClass *) parent_class)->update (object, ctx, flags);
+    if (((SPObjectClass *) parent_class)->update)
+        ((SPObjectClass *) parent_class)->update (object, ctx, flags);
 }
 
 static void
@@ -320,9 +320,9 @@ sp_spiral_update_patheffect(SPLPEItem *lpeitem, bool write)
 static gchar *
 sp_spiral_description (SPItem * item)
 {
-       // TRANSLATORS: since turn count isn't an integer, please adjust the
-       // string as needed to deal with an localized plural forms.
-       return g_strdup_printf (_("<b>Spiral</b> with %3f turns"), SP_SPIRAL(item)->revo);
+    // TRANSLATORS: since turn count isn't an integer, please adjust the
+    // string as needed to deal with an localized plural forms.
+    return g_strdup_printf (_("<b>Spiral</b> with %3f turns"), SP_SPIRAL(item)->revo);
 }
 
 
@@ -335,34 +335,34 @@ sp_spiral_description (SPItem * item)
  **/
 static void
 sp_spiral_fit_and_draw (SPSpiral const *spiral,
-                       SPCurve  *c,
-                       double dstep,
-                       Geom::Point darray[],
-                       Geom::Point const &hat1,
-                       Geom::Point &hat2,
-                       double *t)
+            SPCurve     *c,
+            double dstep,
+            Geom::Point darray[],
+            Geom::Point const &hat1,
+            Geom::Point &hat2,
+            double *t)
 {
 #define BEZIER_SIZE   4
 #define FITTING_MAX_BEZIERS 4
 #define BEZIER_LENGTH (BEZIER_SIZE * FITTING_MAX_BEZIERS)
-       g_assert (dstep > 0);
-       g_assert (is_unit_vector (hat1));
-
-       Geom::Point bezier[BEZIER_LENGTH];
-       double d;
-       int depth, i;
-
-       for (d = *t, i = 0; i <= SAMPLE_SIZE; d += dstep, i++) {
-               darray[i] = sp_spiral_get_xy(spiral, d);
-
-               /* Avoid useless adjacent dups.  (Otherwise we can have all of darray filled with
-                  the same value, which upsets chord_length_parameterize.) */
-               if ((i != 0)
-                   && (darray[i] == darray[i - 1])
-                   && (d < 1.0)) {
-                       i--;
-                       d += dstep;
-                       /** We mustn't increase dstep for subsequent values of
+    g_assert (dstep > 0);
+    g_assert (is_unit_vector (hat1));
+
+    Geom::Point bezier[BEZIER_LENGTH];
+    double d;
+    int depth, i;
+
+    for (d = *t, i = 0; i <= SAMPLE_SIZE; d += dstep, i++) {
+        darray[i] = sp_spiral_get_xy(spiral, d);
+
+        /* Avoid useless adjacent dups.  (Otherwise we can have all of darray filled with
+           the same value, which upsets chord_length_parameterize.) */
+        if ((i != 0)
+            && (darray[i] == darray[i - 1])
+            && (d < 1.0)) {
+            i--;
+            d += dstep;
+            /** We mustn't increase dstep for subsequent values of
                          * i: for large spiral.exp values, rate of growth
                          * increases very rapidly.
                          */
@@ -378,48 +378,48 @@ sp_spiral_fit_and_draw (SPSpiral const *spiral,
                          * value for next iteration to avoid the problem
                          * mentioned above.
                          */
-               }
-       }
+        }
+    }
 
-       double const next_t = d - 2 * dstep;
-       /* == t + (SAMPLE_SIZE - 1) * dstep, in absence of dups. */
+    double const next_t = d - 2 * dstep;
+    /* == t + (SAMPLE_SIZE - 1) * dstep, in absence of dups. */
 
-       hat2 = -sp_spiral_get_tangent (spiral, next_t);
+    hat2 = -sp_spiral_get_tangent (spiral, next_t);
 
-       /** \todo
+    /** \todo
          * We should use better algorithm to specify maximum error.
          */
-       depth = Geom::bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE,
-                                         hat1, hat2,
-                                         SPIRAL_TOLERANCE*SPIRAL_TOLERANCE,
-                                         FITTING_MAX_BEZIERS);
-       g_assert(depth * BEZIER_SIZE <= gint(G_N_ELEMENTS(bezier)));
+    depth = Geom::bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE,
+                      hat1, hat2,
+                      SPIRAL_TOLERANCE*SPIRAL_TOLERANCE,
+                      FITTING_MAX_BEZIERS);
+    g_assert(depth * BEZIER_SIZE <= gint(G_N_ELEMENTS(bezier)));
 #ifdef SPIRAL_DEBUG
-       if (*t == spiral->t0 || *t == 1.0)
-               g_print ("[%s] depth=%d, dstep=%g, t0=%g, t=%g, arg=%g\n",
-                        debug_state, depth, dstep, spiral->t0, *t, spiral->arg);
+    if (*t == spiral->t0 || *t == 1.0)
+        g_print ("[%s] depth=%d, dstep=%g, t0=%g, t=%g, arg=%g\n",
+             debug_state, depth, dstep, spiral->t0, *t, spiral->arg);
 #endif
-       if (depth != -1) {
-               for (i = 0; i < 4*depth; i += 4) {
-                       c->curveto(bezier[i + 1],
-                                         bezier[i + 2],
-                                         bezier[i + 3]);
-               }
-       } else {
+    if (depth != -1) {
+        for (i = 0; i < 4*depth; i += 4) {
+            c->curveto(bezier[i + 1],
+                      bezier[i + 2],
+                      bezier[i + 3]);
+        }
+    } else {
 #ifdef SPIRAL_VERBOSE
-               g_print ("cant_fit_cubic: t=%g\n", *t);
+        g_print ("cant_fit_cubic: t=%g\n", *t);
 #endif
-               for (i = 1; i < SAMPLE_SIZE; i++)
-                       c->lineto(darray[i]);
-       }
-       *t = next_t;
-       g_assert (is_unit_vector (hat2));
+        for (i = 1; i < SAMPLE_SIZE; i++)
+            c->lineto(darray[i]);
+    }
+    *t = next_t;
+    g_assert (is_unit_vector (hat2));
 }
 
 static void
 sp_spiral_set_shape (SPShape *shape)
 {
-       SPSpiral *spiral = SP_SPIRAL(shape);
+    SPSpiral *spiral = SP_SPIRAL(shape);
 
     if (sp_lpe_item_has_broken_path_effect(SP_LPE_ITEM(shape))) {
         g_warning ("The spiral shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as spiral will remove the bad LPE");
@@ -433,40 +433,40 @@ sp_spiral_set_shape (SPShape *shape)
         return;
     }
 
-       Geom::Point darray[SAMPLE_SIZE + 1];
-       double t;
+    Geom::Point darray[SAMPLE_SIZE + 1];
+    double t;
 
-       SP_OBJECT (spiral)->requestModified(SP_OBJECT_MODIFIED_FLAG);
+    SP_OBJECT (spiral)->requestModified(SP_OBJECT_MODIFIED_FLAG);
 
-       SPCurve *c = new SPCurve ();
+    SPCurve *c = new SPCurve ();
 
 #ifdef SPIRAL_VERBOSE
-       g_print ("cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n",
-                spiral->cx,
-                spiral->cy,
-                spiral->exp,
-                spiral->revo,
-                spiral->rad,
-                spiral->arg,
-                spiral->t0);
+    g_print ("cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n",
+         spiral->cx,
+         spiral->cy,
+         spiral->exp,
+         spiral->revo,
+         spiral->rad,
+         spiral->arg,
+         spiral->t0);
 #endif
 
-       /* Initial moveto. */
-       c->moveto(sp_spiral_get_xy(spiral, spiral->t0));
+    /* Initial moveto. */
+    c->moveto(sp_spiral_get_xy(spiral, spiral->t0));
 
-       double const tstep = SAMPLE_STEP / spiral->revo;
-       double const dstep = tstep / (SAMPLE_SIZE - 1);
+    double const tstep = SAMPLE_STEP / spiral->revo;
+    double const dstep = tstep / (SAMPLE_SIZE - 1);
 
-       Geom::Point hat1 = sp_spiral_get_tangent (spiral, spiral->t0);
-       Geom::Point hat2;
-       for (t = spiral->t0; t < (1.0 - tstep);) {
-               sp_spiral_fit_and_draw (spiral, c, dstep, darray, hat1, hat2, &t);
+    Geom::Point hat1 = sp_spiral_get_tangent (spiral, spiral->t0);
+    Geom::Point hat2;
+    for (t = spiral->t0; t < (1.0 - tstep);) {
+        sp_spiral_fit_and_draw (spiral, c, dstep, darray, hat1, hat2, &t);
 
-               hat1 = -hat2;
-       }
-       if ((1.0 - t) > SP_EPSILON)
-               sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0),
-                                       darray, hat1, hat2, &t);
+        hat1 = -hat2;
+    }
+    if ((1.0 - t) > SP_EPSILON)
+        sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0),
+                    darray, hat1, hat2, &t);
 
     /* Reset the shape'scurve to the "original_curve"
      * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
@@ -487,59 +487,58 @@ sp_spiral_set_shape (SPShape *shape)
  */
 void
 sp_spiral_position_set       (SPSpiral          *spiral,
-                    gdouble            cx,
-                    gdouble            cy,
-                    gdouble            exp,
-                    gdouble            revo,
-                    gdouble            rad,
-                    gdouble            arg,
-                    gdouble            t0)
+             gdouble            cx,
+             gdouble            cy,
+             gdouble            exp,
+             gdouble            revo,
+             gdouble            rad,
+             gdouble            arg,
+             gdouble            t0)
 {
-       g_return_if_fail (spiral != NULL);
-       g_return_if_fail (SP_IS_SPIRAL (spiral));
+    g_return_if_fail (spiral != NULL);
+    g_return_if_fail (SP_IS_SPIRAL (spiral));
 
-       /** \todo
+    /** \todo
          * Consider applying CLAMP or adding in-bounds assertions for
          * some of these parameters.
          */
-       spiral->cx         = cx;
-       spiral->cy         = cy;
-       spiral->exp        = exp;
-       spiral->revo       = revo;
-       spiral->rad        = MAX (rad, 0.0);
-       spiral->arg        = arg;
-       spiral->t0         = CLAMP(t0, 0.0, 0.999);
-
-       ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+    spiral->cx         = cx;
+    spiral->cy         = cy;
+    spiral->exp        = exp;
+    spiral->revo       = revo;
+    spiral->rad        = MAX (rad, 0.0);
+    spiral->arg        = arg;
+    spiral->t0         = CLAMP(t0, 0.0, 0.999);
+
+    ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
 /**
  * Virtual snappoints callback.
  */
-static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_spiral_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
-       // We will determine the spiral's midpoint ourselves, instead of trusting on the base class
-       // Therefore setSnapObjectMidpoints() is set to false temporarily
-       Inkscape::SnapPreferences local_snapprefs = *snapprefs;
-       local_snapprefs.setSnapObjectMidpoints(false);
-
-       if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
-       }
-
-       // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
-       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
-               return;
-       }
-
-       if (snapprefs->getSnapObjectMidpoints()) {
-               Geom::Matrix const i2d (sp_item_i2d_affine (item));
-               SPSpiral *spiral = SP_SPIRAL(item);
-               int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
-               p.push_back(std::make_pair(Geom::Point(spiral->cx, spiral->cy) * i2d, type));
-               // This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
-               // in the object snapper. In that case we will get a duplicate!
-       }
+    // We will determine the spiral's midpoint ourselves, instead of trusting on the base class
+    // Therefore setSnapObjectMidpoints() is set to false temporarily
+    Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+    local_snapprefs.setSnapObjectMidpoints(false);
+
+    if (((SPItemClass *) parent_class)->snappoints) {
+        ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+    }
+
+    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+        return;
+    }
+
+    if (snapprefs->getSnapObjectMidpoints()) {
+        Geom::Matrix const i2d (sp_item_i2d_affine (item));
+        SPSpiral *spiral = SP_SPIRAL(item);
+        p.push_back(Inkscape::SnapCandidatePoint(Geom::Point(spiral->cx, spiral->cy) * i2d, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
+        // This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
+        // in the object snapper. In that case we will get a duplicate!
+    }
 }
 
 /**
@@ -552,19 +551,19 @@ static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPoin
  */
 Geom::Point sp_spiral_get_xy (SPSpiral const *spiral, gdouble t)
 {
-       g_assert (spiral != NULL);
-       g_assert (SP_IS_SPIRAL(spiral));
-       g_assert (spiral->exp >= 0.0);
-       /* Otherwise we get NaN for t==0. */
-       g_assert (spiral->exp <= 1000.0);
-       /* Anything much more results in infinities.  Even allowing 1000 is somewhat overkill. */
-       g_assert (t >= 0.0);
-       /* Any callers passing -ve t will have a bug for non-integral values of exp. */
-
-       double const rad = spiral->rad * pow(t, (double) spiral->exp);
-       double const arg = 2.0 * M_PI * spiral->revo * t + spiral->arg;
-
-       return Geom::Point(rad * cos (arg) + spiral->cx,
+    g_assert (spiral != NULL);
+    g_assert (SP_IS_SPIRAL(spiral));
+    g_assert (spiral->exp >= 0.0);
+    /* Otherwise we get NaN for t==0. */
+    g_assert (spiral->exp <= 1000.0);
+    /* Anything much more results in infinities.  Even allowing 1000 is somewhat overkill. */
+    g_assert (t >= 0.0);
+    /* Any callers passing -ve t will have a bug for non-integral values of exp. */
+
+    double const rad = spiral->rad * pow(t, (double) spiral->exp);
+    double const arg = 2.0 * M_PI * spiral->revo * t + spiral->arg;
+
+    return Geom::Point(rad * cos (arg) + spiral->cx,
                            rad * sin (arg) + spiral->cy);
 }
 
@@ -581,58 +580,58 @@ Geom::Point sp_spiral_get_xy (SPSpiral const *spiral, gdouble t)
 static Geom::Point
 sp_spiral_get_tangent (SPSpiral const *spiral, gdouble t)
 {
-       Geom::Point ret(1.0, 0.0);
-       g_return_val_if_fail (( ( spiral != NULL )
-                               && SP_IS_SPIRAL(spiral) ),
-                             ret);
-       g_assert (t >= 0.0);
-       g_assert (spiral->exp >= 0.0);
-       /* See above for comments on these assertions. */
-
-       double const t_scaled = 2.0 * M_PI * spiral->revo * t;
-       double const arg = t_scaled + spiral->arg;
-       double const s = sin (arg);
-       double const c = cos (arg);
-
-       if (spiral->exp == 0.0) {
-               ret = Geom::Point(-s, c);
-       } else if (t_scaled == 0.0) {
-               ret = Geom::Point(c, s);
-       } else {
-               Geom::Point unrotated(spiral->exp, t_scaled);
-               double const s_len = L2 (unrotated);
-               g_assert (s_len != 0);
-               /** \todo
+    Geom::Point ret(1.0, 0.0);
+    g_return_val_if_fail (( ( spiral != NULL )
+                && SP_IS_SPIRAL(spiral) ),
+                  ret);
+    g_assert (t >= 0.0);
+    g_assert (spiral->exp >= 0.0);
+    /* See above for comments on these assertions. */
+
+    double const t_scaled = 2.0 * M_PI * spiral->revo * t;
+    double const arg = t_scaled + spiral->arg;
+    double const s = sin (arg);
+    double const c = cos (arg);
+
+    if (spiral->exp == 0.0) {
+        ret = Geom::Point(-s, c);
+    } else if (t_scaled == 0.0) {
+        ret = Geom::Point(c, s);
+    } else {
+        Geom::Point unrotated(spiral->exp, t_scaled);
+        double const s_len = L2 (unrotated);
+        g_assert (s_len != 0);
+        /** \todo
                  * Check that this isn't being too hopeful of the hypot
                  * function.  E.g. test with numbers around 2**-1070
                  * (denormalized numbers), preferably on a few different
                  * platforms.  However, njh says that the usual implementation
                  * does handle both very big and very small numbers.
                  */
-               unrotated /= s_len;
+        unrotated /= s_len;
 
-               /* ret = spiral->exp * (c, s) + t_scaled * (-s, c);
-                  alternatively ret = (spiral->exp, t_scaled) * (( c, s),
-                                                                 (-s, c)).*/
-               ret = Geom::Point(dot(unrotated, Geom::Point(c, -s)),
+        /* ret = spiral->exp * (c, s) + t_scaled * (-s, c);
+           alternatively ret = (spiral->exp, t_scaled) * (( c, s),
+                                  (-s, c)).*/
+        ret = Geom::Point(dot(unrotated, Geom::Point(c, -s)),
                                   dot(unrotated, Geom::Point(s, c)));
-               /* ret should already be approximately normalized: the
-                  matrix ((c, -s), (s, c)) is orthogonal (it just
-                  rotates by arg), and unrotated has been normalized,
-                  so ret is already of unit length other than numerical
-                  error in the above matrix multiplication. */
+        /* ret should already be approximately normalized: the
+           matrix ((c, -s), (s, c)) is orthogonal (it just
+           rotates by arg), and unrotated has been normalized,
+           so ret is already of unit length other than numerical
+           error in the above matrix multiplication. */
 
-               /** \todo
+        /** \todo
                  * I haven't checked how important it is for ret to be very
                  * near unit length; we could get rid of the below.
                  */
 
-               ret.normalize();
-               /* Proof that ret length is non-zero: see above.  (Should be near 1.) */
-       }
+        ret.normalize();
+        /* Proof that ret length is non-zero: see above.  (Should be near 1.) */
+    }
 
-       g_assert (is_unit_vector (ret));
-       return ret;
+    g_assert (is_unit_vector (ret));
+    return ret;
 }
 
 /**
@@ -641,13 +640,13 @@ sp_spiral_get_tangent (SPSpiral const *spiral, gdouble t)
 void
 sp_spiral_get_polar (SPSpiral const *spiral, gdouble t, gdouble *rad, gdouble *arg)
 {
-       g_return_if_fail (spiral != NULL);
-       g_return_if_fail (SP_IS_SPIRAL(spiral));
+    g_return_if_fail (spiral != NULL);
+    g_return_if_fail (SP_IS_SPIRAL(spiral));
 
-       if (rad)
-               *rad = spiral->rad * pow(t, (double) spiral->exp);
-       if (arg)
-               *arg = 2.0 * M_PI * spiral->revo * t + spiral->arg;
+    if (rad)
+        *rad = spiral->rad * pow(t, (double) spiral->exp);
+    if (arg)
+        *arg = 2.0 * M_PI * spiral->revo * t + spiral->arg;
 }
 
 /**
@@ -656,19 +655,19 @@ sp_spiral_get_polar (SPSpiral const *spiral, gdouble t, gdouble *rad, gdouble *a
 bool
 sp_spiral_is_invalid (SPSpiral const *spiral)
 {
-       gdouble rad;
-
-       sp_spiral_get_polar (spiral, 0.0, &rad, NULL);
-       if (rad < 0.0 || rad > SP_HUGE) {
-               g_print ("rad(t=0)=%g\n", rad);
-               return TRUE;
-       }
-       sp_spiral_get_polar (spiral, 1.0, &rad, NULL);
-       if (rad < 0.0 || rad > SP_HUGE) {
-               g_print ("rad(t=1)=%g\n", rad);
-               return TRUE;
-       }
-       return FALSE;
+    gdouble rad;
+
+    sp_spiral_get_polar (spiral, 0.0, &rad, NULL);
+    if (rad < 0.0 || rad > SP_HUGE) {
+        g_print ("rad(t=0)=%g\n", rad);
+        return TRUE;
+    }
+    sp_spiral_get_polar (spiral, 1.0, &rad, NULL);
+    if (rad < 0.0 || rad > SP_HUGE) {
+        g_print ("rad(t=1)=%g\n", rad);
+        return TRUE;
+    }
+    return FALSE;
 }
 
 /*
index 9cffd952ca2c72bb2ea91ec0b26ebdc4a9eb1933..6bced87e8a7aa4d5a2510daf14f40da2f801a3f3 100644 (file)
@@ -41,7 +41,7 @@ static void sp_star_set (SPObject *object, unsigned int key, const gchar *value)
 static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags);
 
 static gchar * sp_star_description (SPItem * item);
-static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_star_set_shape (SPShape *shape);
 static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -51,230 +51,230 @@ static SPShapeClass *parent_class;
 GType
 sp_star_get_type (void)
 {
-       static GType type = 0;
-
-       if (!type) {
-               GTypeInfo info = {
-                       sizeof (SPStarClass),
-                       NULL, NULL,
-                       (GClassInitFunc) sp_star_class_init,
-                       NULL, NULL,
-                       sizeof (SPStar),
-                       16,
-                       (GInstanceInitFunc) sp_star_init,
-                       NULL,   /* value_table */
-               };
-               type = g_type_register_static (SP_TYPE_SHAPE, "SPStar", &info, (GTypeFlags)0);
-       }
-       return type;
+    static GType type = 0;
+
+    if (!type) {
+        GTypeInfo info = {
+            sizeof (SPStarClass),
+            NULL, NULL,
+            (GClassInitFunc) sp_star_class_init,
+            NULL, NULL,
+            sizeof (SPStar),
+            16,
+            (GInstanceInitFunc) sp_star_init,
+            NULL,    /* value_table */
+        };
+        type = g_type_register_static (SP_TYPE_SHAPE, "SPStar", &info, (GTypeFlags)0);
+    }
+    return type;
 }
 
 static void
 sp_star_class_init (SPStarClass *klass)
 {
-       GObjectClass * gobject_class;
-       SPObjectClass * sp_object_class;
-       SPItemClass * item_class;
-       SPLPEItemClass * lpe_item_class;
-       SPShapeClass * shape_class;
+    GObjectClass * gobject_class;
+    SPObjectClass * sp_object_class;
+    SPItemClass * item_class;
+    SPLPEItemClass * lpe_item_class;
+    SPShapeClass * shape_class;
 
-       gobject_class = (GObjectClass *) klass;
-       sp_object_class = (SPObjectClass *) klass;
-       item_class = (SPItemClass *) klass;
-       lpe_item_class = (SPLPEItemClass *) klass;
-       shape_class = (SPShapeClass *) klass;
+    gobject_class = (GObjectClass *) klass;
+    sp_object_class = (SPObjectClass *) klass;
+    item_class = (SPItemClass *) klass;
+    lpe_item_class = (SPLPEItemClass *) klass;
+    shape_class = (SPShapeClass *) klass;
 
-       parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
+    parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
 
-       sp_object_class->build = sp_star_build;
-       sp_object_class->write = sp_star_write;
-       sp_object_class->set = sp_star_set;
-       sp_object_class->update = sp_star_update;
+    sp_object_class->build = sp_star_build;
+    sp_object_class->write = sp_star_write;
+    sp_object_class->set = sp_star_set;
+    sp_object_class->update = sp_star_update;
 
-       item_class->description = sp_star_description;
-       item_class->snappoints = sp_star_snappoints;
+    item_class->description = sp_star_description;
+    item_class->snappoints = sp_star_snappoints;
 
     lpe_item_class->update_patheffect = sp_star_update_patheffect;
 
-       shape_class->set_shape = sp_star_set_shape;
+    shape_class->set_shape = sp_star_set_shape;
 }
 
 static void
 sp_star_init (SPStar * star)
 {
-       star->sides = 5;
-       star->center = Geom::Point(0, 0);
-       star->r[0] = 1.0;
-       star->r[1] = 0.001;
-       star->arg[0] = star->arg[1] = 0.0;
-       star->flatsided = 0;
-       star->rounded = 0.0;
-       star->randomized = 0.0;
+    star->sides = 5;
+    star->center = Geom::Point(0, 0);
+    star->r[0] = 1.0;
+    star->r[1] = 0.001;
+    star->arg[0] = star->arg[1] = 0.0;
+    star->flatsided = 0;
+    star->rounded = 0.0;
+    star->randomized = 0.0;
 }
 
 static void
 sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr)
 {
-       if (((SPObjectClass *) parent_class)->build)
-               ((SPObjectClass *) parent_class)->build (object, document, repr);
-
-       sp_object_read_attr (object, "sodipodi:cx");
-       sp_object_read_attr (object, "sodipodi:cy");
-       sp_object_read_attr (object, "sodipodi:sides");
-       sp_object_read_attr (object, "sodipodi:r1");
-       sp_object_read_attr (object, "sodipodi:r2");
-       sp_object_read_attr (object, "sodipodi:arg1");
-       sp_object_read_attr (object, "sodipodi:arg2");
-       sp_object_read_attr (object, "inkscape:flatsided");
-       sp_object_read_attr (object, "inkscape:rounded");
-       sp_object_read_attr (object, "inkscape:randomized");
+    if (((SPObjectClass *) parent_class)->build)
+        ((SPObjectClass *) parent_class)->build (object, document, repr);
+
+    sp_object_read_attr (object, "sodipodi:cx");
+    sp_object_read_attr (object, "sodipodi:cy");
+    sp_object_read_attr (object, "sodipodi:sides");
+    sp_object_read_attr (object, "sodipodi:r1");
+    sp_object_read_attr (object, "sodipodi:r2");
+    sp_object_read_attr (object, "sodipodi:arg1");
+    sp_object_read_attr (object, "sodipodi:arg2");
+    sp_object_read_attr (object, "inkscape:flatsided");
+    sp_object_read_attr (object, "inkscape:rounded");
+    sp_object_read_attr (object, "inkscape:randomized");
 }
 
 static Inkscape::XML::Node *
 sp_star_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
 {
-       SPStar *star = SP_STAR (object);
-
-       if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
-               repr = xml_doc->createElement("svg:path");
-       }
-
-       if (flags & SP_OBJECT_WRITE_EXT) {
-               repr->setAttribute("sodipodi:type", "star");
-               sp_repr_set_int (repr, "sodipodi:sides", star->sides);
-               sp_repr_set_svg_double(repr, "sodipodi:cx", star->center[Geom::X]);
-               sp_repr_set_svg_double(repr, "sodipodi:cy", star->center[Geom::Y]);
-               sp_repr_set_svg_double(repr, "sodipodi:r1", star->r[0]);
-               sp_repr_set_svg_double(repr, "sodipodi:r2", star->r[1]);
-               sp_repr_set_svg_double(repr, "sodipodi:arg1", star->arg[0]);
-               sp_repr_set_svg_double(repr, "sodipodi:arg2", star->arg[1]);
-               sp_repr_set_boolean (repr, "inkscape:flatsided", star->flatsided);
-               sp_repr_set_svg_double(repr, "inkscape:rounded", star->rounded);
-               sp_repr_set_svg_double(repr, "inkscape:randomized", star->randomized);
-       }
+    SPStar *star = SP_STAR (object);
+
+    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
+        repr = xml_doc->createElement("svg:path");
+    }
+
+    if (flags & SP_OBJECT_WRITE_EXT) {
+        repr->setAttribute("sodipodi:type", "star");
+        sp_repr_set_int (repr, "sodipodi:sides", star->sides);
+        sp_repr_set_svg_double(repr, "sodipodi:cx", star->center[Geom::X]);
+        sp_repr_set_svg_double(repr, "sodipodi:cy", star->center[Geom::Y]);
+        sp_repr_set_svg_double(repr, "sodipodi:r1", star->r[0]);
+        sp_repr_set_svg_double(repr, "sodipodi:r2", star->r[1]);
+        sp_repr_set_svg_double(repr, "sodipodi:arg1", star->arg[0]);
+        sp_repr_set_svg_double(repr, "sodipodi:arg2", star->arg[1]);
+        sp_repr_set_boolean (repr, "inkscape:flatsided", star->flatsided);
+        sp_repr_set_svg_double(repr, "inkscape:rounded", star->rounded);
+        sp_repr_set_svg_double(repr, "inkscape:randomized", star->randomized);
+    }
 
     sp_star_set_shape ((SPShape *) star);
     char *d = sp_svg_write_path (((SPShape *) star)->curve->get_pathvector());
     repr->setAttribute("d", d);
     g_free (d);
 
-       if (((SPObjectClass *) (parent_class))->write)
-               ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
+    if (((SPObjectClass *) (parent_class))->write)
+        ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
 
-       return repr;
+    return repr;
 }
 
 static void
 sp_star_set (SPObject *object, unsigned int key, const gchar *value)
 {
-       SVGLength::Unit unit;
-
-       SPStar *star = SP_STAR (object);
-
-       /* fixme: we should really collect updates */
-       switch (key) {
-       case SP_ATTR_SODIPODI_SIDES:
-               if (value) {
-                       star->sides = atoi (value);
-                       star->sides = NR_CLAMP(star->sides, 3, 1024);
-               } else {
-                       star->sides = 5;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_CX:
-               if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::X]) ||
-                   (unit == SVGLength::EM) ||
-                   (unit == SVGLength::EX) ||
-                   (unit == SVGLength::PERCENT)) {
-                       star->center[Geom::X] = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_CY:
-               if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::Y]) ||
-                   (unit == SVGLength::EM) ||
-                   (unit == SVGLength::EX) ||
-                   (unit == SVGLength::PERCENT)) {
-                       star->center[Geom::Y] = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_R1:
-               if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[0]) ||
-                   (unit == SVGLength::EM) ||
-                   (unit == SVGLength::EX) ||
-                   (unit == SVGLength::PERCENT)) {
-                       star->r[0] = 1.0;
-               }
-               /* fixme: Need CLAMP (Lauris) */
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_R2:
-               if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[1]) ||
-                   (unit == SVGLength::EM) ||
-                   (unit == SVGLength::EX) ||
-                   (unit == SVGLength::PERCENT)) {
-                       star->r[1] = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               return;
-       case SP_ATTR_SODIPODI_ARG1:
-               if (value) {
-                       star->arg[0] = g_ascii_strtod (value, NULL);
-               } else {
-                       star->arg[0] = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_SODIPODI_ARG2:
-               if (value) {
-                       star->arg[1] = g_ascii_strtod (value, NULL);
-               } else {
-                       star->arg[1] = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_INKSCAPE_FLATSIDED:
-               if (value && !strcmp (value, "true"))
-                       star->flatsided = true;
-               else star->flatsided = false;
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_INKSCAPE_ROUNDED:
-               if (value) {
-                       star->rounded = g_ascii_strtod (value, NULL);
-               } else {
-                       star->rounded = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       case SP_ATTR_INKSCAPE_RANDOMIZED:
-               if (value) {
-                       star->randomized = g_ascii_strtod (value, NULL);
-               } else {
-                       star->randomized = 0.0;
-               }
-               object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-               break;
-       default:
-               if (((SPObjectClass *) parent_class)->set)
-                       ((SPObjectClass *) parent_class)->set (object, key, value);
-               break;
-       }
+    SVGLength::Unit unit;
+
+    SPStar *star = SP_STAR (object);
+
+    /* fixme: we should really collect updates */
+    switch (key) {
+    case SP_ATTR_SODIPODI_SIDES:
+        if (value) {
+            star->sides = atoi (value);
+            star->sides = NR_CLAMP(star->sides, 3, 1024);
+        } else {
+            star->sides = 5;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_CX:
+        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::X]) ||
+            (unit == SVGLength::EM) ||
+            (unit == SVGLength::EX) ||
+            (unit == SVGLength::PERCENT)) {
+            star->center[Geom::X] = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_CY:
+        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[Geom::Y]) ||
+            (unit == SVGLength::EM) ||
+            (unit == SVGLength::EX) ||
+            (unit == SVGLength::PERCENT)) {
+            star->center[Geom::Y] = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_R1:
+        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[0]) ||
+            (unit == SVGLength::EM) ||
+            (unit == SVGLength::EX) ||
+            (unit == SVGLength::PERCENT)) {
+            star->r[0] = 1.0;
+        }
+        /* fixme: Need CLAMP (Lauris) */
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_R2:
+        if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[1]) ||
+            (unit == SVGLength::EM) ||
+            (unit == SVGLength::EX) ||
+            (unit == SVGLength::PERCENT)) {
+            star->r[1] = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        return;
+    case SP_ATTR_SODIPODI_ARG1:
+        if (value) {
+            star->arg[0] = g_ascii_strtod (value, NULL);
+        } else {
+            star->arg[0] = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_SODIPODI_ARG2:
+        if (value) {
+            star->arg[1] = g_ascii_strtod (value, NULL);
+        } else {
+            star->arg[1] = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_INKSCAPE_FLATSIDED:
+        if (value && !strcmp (value, "true"))
+            star->flatsided = true;
+        else star->flatsided = false;
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_INKSCAPE_ROUNDED:
+        if (value) {
+            star->rounded = g_ascii_strtod (value, NULL);
+        } else {
+            star->rounded = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    case SP_ATTR_INKSCAPE_RANDOMIZED:
+        if (value) {
+            star->randomized = g_ascii_strtod (value, NULL);
+        } else {
+            star->randomized = 0.0;
+        }
+        object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+        break;
+    default:
+        if (((SPObjectClass *) parent_class)->set)
+            ((SPObjectClass *) parent_class)->set (object, key, value);
+        break;
+    }
 }
 
 static void
 sp_star_update (SPObject *object, SPCtx *ctx, guint flags)
 {
-       if (flags & (SP_OBJECT_MODIFIED_FLAG |
-                    SP_OBJECT_STYLE_MODIFIED_FLAG |
-                    SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-               sp_shape_set_shape ((SPShape *) object);
-       }
-
-       if (((SPObjectClass *) parent_class)->update)
-               ((SPObjectClass *) parent_class)->update (object, ctx, flags);
+    if (flags & (SP_OBJECT_MODIFIED_FLAG |
+             SP_OBJECT_STYLE_MODIFIED_FLAG |
+             SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
+        sp_shape_set_shape ((SPShape *) object);
+    }
+
+    if (((SPObjectClass *) parent_class)->update)
+        ((SPObjectClass *) parent_class)->update (object, ctx, flags);
 }
 
 static void
@@ -306,13 +306,13 @@ sp_star_description (SPItem *item)
     // make calls to ngettext because the pluralization may be different
     // for various numbers >=3.  The singular form is used as the index.
     if (star->flatsided == false )
-       return g_strdup_printf (ngettext("<b>Star</b> with %d vertex",
-                                        "<b>Star</b> with %d vertices",
-                                        star->sides), star->sides);
+    return g_strdup_printf (ngettext("<b>Star</b> with %d vertex",
+                         "<b>Star</b> with %d vertices",
+                     star->sides), star->sides);
     else
         return g_strdup_printf (ngettext("<b>Polygon</b> with %d vertex",
-                                        "<b>Polygon</b> with %d vertices",
-                                        star->sides), star->sides);
+                         "<b>Polygon</b> with %d vertices",
+                     star->sides), star->sides);
 }
 
 /**
@@ -321,7 +321,7 @@ Returns a unit-length vector at 90 degrees to the direction from o to n
 static Geom::Point
 rot90_rel (Geom::Point o, Geom::Point n)
 {
-       return ((1/Geom::L2(n - o)) * Geom::Point ((n - o)[Geom::Y],  (o - n)[Geom::X]));
+    return ((1/Geom::L2(n - o)) * Geom::Point ((n - o)[Geom::Y],  (o - n)[Geom::X]));
 }
 
 /**
@@ -333,12 +333,12 @@ Obvious (but acceptable for my purposes) limits to uniqueness:
 static guint32
 point_unique_int (Geom::Point o)
 {
-       return ((guint32)
-       65536 *
-               (((int) floor (o[Geom::X] * 64)) % 1024 + ((int) floor (o[Geom::X] * 1024)) % 64)
-       +
-               (((int) floor (o[Geom::Y] * 64)) % 1024 + ((int) floor (o[Geom::Y] * 1024)) % 64)
-       );
+    return ((guint32)
+    65536 *
+        (((int) floor (o[Geom::X] * 64)) % 1024 + ((int) floor (o[Geom::X] * 1024)) % 64)
+    +
+             (((int) floor (o[Geom::Y] * 64)) % 1024 + ((int) floor (o[Geom::Y] * 1024)) % 64)
+    );
 }
 
 /**
@@ -349,7 +349,7 @@ i.e. it is guaranteed to go through all integers < 2^32 (see http://random.mat.s
 static inline guint32
 lcg_next(guint32 const prev)
 {
-       return (guint32) ( 69069 * prev + 1 );
+    return (guint32) ( 69069 * prev + 1 );
 }
 
 /**
@@ -357,68 +357,68 @@ Returns a random number in the range [-0.5, 0.5) from the given seed, stepping t
 */
 static double
 rnd (guint32 const seed, unsigned steps) {
-       guint32 lcg = seed;
-       for (; steps > 0; steps --)
-               lcg = lcg_next (lcg);
+    guint32 lcg = seed;
+    for (; steps > 0; steps --)
+        lcg = lcg_next (lcg);
 
-       return ( lcg / 4294967296. ) - 0.5;
+    return ( lcg / 4294967296. ) - 0.5;
 }
 
 static Geom::Point
 sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ)
 {
-       // the point whose neighboring curve handle we're calculating
-       Geom::Point o = sp_star_get_xy (star, point, index);
-
-       // indices of previous and next points
-       gint pi = (index > 0)? (index - 1) : (star->sides - 1);
-       gint ni = (index < star->sides - 1)? (index + 1) : 0;
-
-       // the other point type
-       SPStarPoint other = (point == SP_STAR_POINT_KNOT2? SP_STAR_POINT_KNOT1 : SP_STAR_POINT_KNOT2);
-
-       // the neighbors of o; depending on flatsided, they're either the same type (polygon) or the other type (star)
-       Geom::Point prev = (star->flatsided? sp_star_get_xy (star, point, pi) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT2? index : pi));
-       Geom::Point next = (star->flatsided? sp_star_get_xy (star, point, ni) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT1? index : ni));
-
-       // prev-next midpoint
-       Geom::Point mid =  0.5 * (prev + next);
-
-       // point to which we direct the bissector of the curve handles;
-       // it's far enough outside the star on the perpendicular to prev-next through mid
-       Geom::Point biss =  mid + 100000 * rot90_rel (mid, next);
-
-       // lengths of vectors to prev and next
-       gdouble prev_len = Geom::L2 (prev - o);
-       gdouble next_len = Geom::L2 (next - o);
-
-       // unit-length vector perpendicular to o-biss
-       Geom::Point rot = rot90_rel (o, biss);
-
-       // multiply rot by star->rounded coefficient and the distance to the star point; flip for next
-       Geom::Point ret;
-       if (previ) {
-               ret = (star->rounded * prev_len) * rot;
-       } else {
-               ret = (star->rounded * next_len * -1) * rot;
-       }
-
-       if (star->randomized == 0) {
-               // add the vector to o to get the final curvepoint
-               return o + ret;
-       } else {
-               // the seed corresponding to the exact point
-               guint32 seed = point_unique_int (o);
-
-               // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector
-               ret = ret * Geom::Matrix (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3)));
-               ret *= ( 1 + star->randomized * rnd (seed, 4));
-
-               // the randomized corner point
-               Geom::Point o_randomized = sp_star_get_xy (star, point, index, true);
-
-               return o_randomized + ret;
-       }
+    // the point whose neighboring curve handle we're calculating
+    Geom::Point o = sp_star_get_xy (star, point, index);
+
+    // indices of previous and next points
+    gint pi = (index > 0)? (index - 1) : (star->sides - 1);
+    gint ni = (index < star->sides - 1)? (index + 1) : 0;
+
+    // the other point type
+    SPStarPoint other = (point == SP_STAR_POINT_KNOT2? SP_STAR_POINT_KNOT1 : SP_STAR_POINT_KNOT2);
+
+    // the neighbors of o; depending on flatsided, they're either the same type (polygon) or the other type (star)
+    Geom::Point prev = (star->flatsided? sp_star_get_xy (star, point, pi) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT2? index : pi));
+    Geom::Point next = (star->flatsided? sp_star_get_xy (star, point, ni) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT1? index : ni));
+
+    // prev-next midpoint
+    Geom::Point mid =  0.5 * (prev + next);
+
+    // point to which we direct the bissector of the curve handles;
+    // it's far enough outside the star on the perpendicular to prev-next through mid
+    Geom::Point biss =  mid + 100000 * rot90_rel (mid, next);
+
+    // lengths of vectors to prev and next
+    gdouble prev_len = Geom::L2 (prev - o);
+    gdouble next_len = Geom::L2 (next - o);
+
+    // unit-length vector perpendicular to o-biss
+    Geom::Point rot = rot90_rel (o, biss);
+
+    // multiply rot by star->rounded coefficient and the distance to the star point; flip for next
+    Geom::Point ret;
+    if (previ) {
+        ret = (star->rounded * prev_len) * rot;
+    } else {
+        ret = (star->rounded * next_len * -1) * rot;
+    }
+
+    if (star->randomized == 0) {
+        // add the vector to o to get the final curvepoint
+        return o + ret;
+    } else {
+        // the seed corresponding to the exact point
+        guint32 seed = point_unique_int (o);
+
+        // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector
+        ret = ret * Geom::Matrix (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3)));
+        ret *= ( 1 + star->randomized * rnd (seed, 4));
+
+        // the randomized corner point
+        Geom::Point o_randomized = sp_star_get_xy (star, point, index, true);
+
+        return o_randomized + ret;
+    }
 }
 
 
@@ -428,7 +428,7 @@ sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ)
 static void
 sp_star_set_shape (SPShape *shape)
 {
-       SPStar *star = SP_STAR (shape);
+    SPStar *star = SP_STAR (shape);
 
     // perhaps we should convert all our shapes into LPEs without source path
     // and with knotholders for parameters, then this situation will be handled automatically
@@ -445,67 +445,67 @@ sp_star_set_shape (SPShape *shape)
         return;
     }
 
-       SPCurve *c = new SPCurve ();
-
-       gint sides = star->sides;
-       bool not_rounded = (fabs (star->rounded) < 1e-4);
-
-       // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized;
-       // other places that call that function (e.g. the knotholder) need the exact point
-
-       // draw 1st segment
-       c->moveto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
-       if (star->flatsided == false) {
-               if (not_rounded) {
-                       c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
-               } else {
-                       c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT),
-                               sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV),
-                               sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
-               }
-       }
-
-       // draw all middle segments
-       for (gint i = 1; i < sides; i++) {
-               if (not_rounded) {
-                       c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
-               } else {
-                       if (star->flatsided == false) {
-                               c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT),
-                                               sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
-                                               sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
-                       } else {
-                               c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT),
-                                               sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
-                                               sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
-                       }
-               }
-               if (star->flatsided == false) {
-
-                       if (not_rounded) {
+    SPCurve *c = new SPCurve ();
+
+    gint sides = star->sides;
+    bool not_rounded = (fabs (star->rounded) < 1e-4);
+
+    // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized;
+    // other places that call that function (e.g. the knotholder) need the exact point
+
+    // draw 1st segment
+    c->moveto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
+    if (star->flatsided == false) {
+        if (not_rounded) {
+            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
+        } else {
+            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT),
+                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV),
+                sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true));
+        }
+    }
+
+    // draw all middle segments
+    for (gint i = 1; i < sides; i++) {
+        if (not_rounded) {
+            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
+        } else {
+            if (star->flatsided == false) {
+                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT),
+                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
+                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
+            } else {
+                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT),
+                        sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV),
+                        sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true));
+            }
+        }
+        if (star->flatsided == false) {
+
+            if (not_rounded) {
                        c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
-                       } else {
-                               c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT),
-                                       sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV),
-                                       sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
-                       }
-               }
-       }
-
-       // draw last segment
-               if (not_rounded) {
-                       c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
-               } else {
-                       if (star->flatsided == false) {
-                       c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT),
-                               sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
-                               sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
-                       } else {
-                       c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT),
-                               sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
-                               sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
-                       }
-               }
+            } else {
+                c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT),
+                    sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV),
+                    sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true));
+            }
+        }
+    }
+
+    // draw last segment
+        if (not_rounded) {
+            c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
+        } else {
+            if (star->flatsided == false) {
+            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT),
+                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
+                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
+            } else {
+            c->curveto(sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT),
+                sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV),
+                sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
+            }
+        }
 
     c->closepath();
 
@@ -526,46 +526,45 @@ sp_star_set_shape (SPShape *shape)
 void
 sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized)
 {
-       g_return_if_fail (star != NULL);
-       g_return_if_fail (SP_IS_STAR (star));
-
-       star->sides = NR_CLAMP(sides, 3, 1024);
-       star->center = center;
-       star->r[0] = MAX (r1, 0.001);
-       if (isflat == false) {
-               star->r[1] = NR_CLAMP(r2, 0.0, star->r[0]);
-       } else {
-               star->r[1] = NR_CLAMP( r1*cos(M_PI/sides) ,0.0, star->r[0] );
-       }
-       star->arg[0] = arg1;
-       star->arg[1] = arg2;
-       star->flatsided = isflat;
-       star->rounded = rounded;
-       star->randomized = randomized;
-       SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+    g_return_if_fail (star != NULL);
+    g_return_if_fail (SP_IS_STAR (star));
+
+    star->sides = NR_CLAMP(sides, 3, 1024);
+    star->center = center;
+    star->r[0] = MAX (r1, 0.001);
+    if (isflat == false) {
+        star->r[1] = NR_CLAMP(r2, 0.0, star->r[0]);
+    } else {
+        star->r[1] = NR_CLAMP( r1*cos(M_PI/sides) ,0.0, star->r[0] );
+    }
+    star->arg[0] = arg1;
+    star->arg[1] = arg2;
+    star->flatsided = isflat;
+    star->rounded = rounded;
+    star->randomized = randomized;
+    SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
-static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_star_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
-       // We will determine the star's midpoint ourselves, instead of trusting on the base class
-       // Therefore setSnapObjectMidpoints() is set to false temporarily
-       Inkscape::SnapPreferences local_snapprefs = *snapprefs;
-       local_snapprefs.setSnapObjectMidpoints(false);
-
-       if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
-       }
-
-       // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
-       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
-               return;
-       }
-
-       if (snapprefs->getSnapObjectMidpoints()) {
-               Geom::Matrix const i2d (sp_item_i2d_affine (item));
-               int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
-               p.push_back(std::make_pair(SP_STAR(item)->center * i2d, type));
-       }
+    // We will determine the star's midpoint ourselves, instead of trusting on the base class
+    // Therefore setSnapObjectMidpoints() is set to false temporarily
+    Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+    local_snapprefs.setSnapObjectMidpoints(false);
+
+    if (((SPItemClass *) parent_class)->snappoints) {
+        ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+    }
+
+    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+        return;
+    }
+
+    if (snapprefs->getSnapObjectMidpoints()) {
+        Geom::Matrix const i2d (sp_item_i2d_affine (item));
+        p.push_back(Inkscape::SnapCandidatePoint(SP_STAR(item)->center * i2d,Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
+    }
 }
 
 /**
@@ -582,26 +581,26 @@ static void sp_star_snappoints(SPItem const *item, bool const target, SnapPoints
 Geom::Point
 sp_star_get_xy (SPStar *star, SPStarPoint point, gint index, bool randomized)
 {
-       gdouble darg = 2.0 * M_PI / (double) star->sides;
-
-       double arg = star->arg[point];
-       arg += index * darg;
-
-       Geom::Point xy = star->r[point] * Geom::Point(cos(arg), sin(arg)) + star->center;
-
-       if (!randomized || star->randomized == 0) {
-               // return the exact point
-               return xy;
-       } else { // randomize the point
-               // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary
-               guint32 seed = point_unique_int (xy);
-               // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter
-               double range = 2 * MAX (star->r[0], star->r[1]);
-               // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2
-               Geom::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2));
-               // add the shift to the exact point
-               return xy + shift;
-       }
+    gdouble darg = 2.0 * M_PI / (double) star->sides;
+
+    double arg = star->arg[point];
+    arg += index * darg;
+
+    Geom::Point xy = star->r[point] * Geom::Point(cos(arg), sin(arg)) + star->center;
+
+    if (!randomized || star->randomized == 0) {
+        // return the exact point
+        return xy;
+    } else { // randomize the point
+        // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary
+        guint32 seed = point_unique_int (xy);
+        // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter
+        double range = 2 * MAX (star->r[0], star->r[1]);
+        // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2
+        Geom::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2));
+        // add the shift to the exact point
+        return xy + shift;
+    }
 }
 
 /*
index b45f8cbb607d3a67d6aac7f7f39bc2384364a0d1..55da52f1a3269b09cc0ea23ea7ae45ed507a1cd2 100644 (file)
@@ -74,7 +74,7 @@ static void sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &t
 static NRArenaItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, unsigned flags);
 static void sp_text_hide (SPItem *item, unsigned key);
 static char *sp_text_description (SPItem *item);
-static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_text_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 static Geom::Matrix sp_text_set_transform(SPItem *item, Geom::Matrix const &xform);
 static void sp_text_print (SPItem *item, SPPrintContext *gpc);
 
@@ -434,7 +434,7 @@ sp_text_description(SPItem *item)
     return ret;
 }
 
-static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_text_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     // Choose a point on the baseline for snapping from or to, with the horizontal position
     // of this point depending on the text alignment (left vs. right)
@@ -442,8 +442,7 @@ static void sp_text_snappoints(SPItem const *item, bool const target, SnapPoints
     if (layout != NULL && layout->outputExists()) {
         boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
         if (pt) {
-            int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE);
-            p.push_back(std::make_pair((*pt) * sp_item_i2d_affine(item), type));
+            p.push_back(Inkscape::SnapCandidatePoint((*pt) * sp_item_i2d_affine(item), Inkscape::SNAPSOURCE_TEXT_BASELINE, Inkscape::SNAPTARGET_TEXT_BASELINE));
         }
     }
 }
index 76930086cc64dae64d4ccb1a492a43a9a368ec44..7962390c24304cf214f04cc40d14ce04a55127ae 100644 (file)
@@ -52,7 +52,7 @@ static void sp_use_update(SPObject *object, SPCtx *ctx, guint flags);
 static void sp_use_modified(SPObject *object, guint flags);
 
 static void sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
-static void sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
 static void sp_use_print(SPItem *item, SPPrintContext *ctx);
 static gchar *sp_use_description(SPItem *item);
 static NRArenaItem *sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags);
@@ -742,7 +742,7 @@ sp_use_get_original(SPUse *use)
 }
 
 static void
-sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert (item != NULL);
     g_assert (SP_IS_ITEM(item));
@@ -755,7 +755,7 @@ sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p,
 
     SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(root);
     if (item_class.snappoints) {
-        item_class.snappoints(root, target, p, snapprefs);
+        item_class.snappoints(root, p, snapprefs);
     }
 }