Code

Groundwork to snap to intersections, e.g. intersections of gridlines with guidelines...
authordvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 3 Nov 2007 14:48:50 +0000 (14:48 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 3 Nov 2007 14:48:50 +0000 (14:48 +0000)
20 files changed:
src/display/canvas-axonomgrid.cpp
src/display/canvas-axonomgrid.h
src/display/canvas-grid.cpp
src/display/canvas-grid.h
src/geom.cpp
src/geom.h
src/guide-snapper.cpp
src/guide-snapper.h
src/line-snapper.cpp
src/line-snapper.h
src/object-snapper.cpp
src/object-snapper.h
src/snap.cpp
src/snap.h
src/snapped-line.cpp [new file with mode: 0644]
src/snapped-line.h [new file with mode: 0644]
src/snapped-point.cpp
src/snapped-point.h
src/snapper.cpp
src/snapper.h

index c00e2ea8fa724e8aea4ac48d7bf44f7fb2769d9e..66c9cc1fac3a8b4858cdb6eb89bb196fdc1d17cc 100644 (file)
@@ -650,6 +650,13 @@ CanvasAxonomGridSnapper::_getSnapLines(NR::Point const &p) const
     return s;
 }
 
+void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const 
+{
+       SnappedInfiniteLine dummy = SnappedInfiniteLine(snapped_point, snapped_distance, normal_to_line, point_on_line);
+       sc.grid_lines.push_back(dummy);
+}
+
+
 
 }; // namespace Inkscape
 
index 157982416a2c58fe9572d6969d2848ad0faf5cf0..68c011d3050b0a467ec7cb13139bced71e2af581 100644 (file)
@@ -92,7 +92,8 @@ public:
 
 private:    
     LineList _getSnapLines(NR::Point const &p) const;
-    
+    void _addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, const NR::Point point_on_line) const;
+
     CanvasAxonomGrid *grid;
 }; 
 
index e9eabad10d22891429ee897744b0f84f2c426115..d3cbf9153cc15a3ab689614ff22cf433028d41d3 100644 (file)
@@ -850,6 +850,11 @@ CanvasXYGridSnapper::_getSnapLines(NR::Point const &p) const
     return s;
 }
 
+void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const 
+{
+       SnappedInfiniteLine dummy = SnappedInfiniteLine(snapped_point, snapped_distance, normal_to_line, point_on_line);
+       sc.grid_lines.push_back(dummy);
+}
 
 
 
index 40e37c44f8cf1d2e4c93031d846b125cb62c0d30..ec5e52c9060ccce17f04322816a82872c3f24c0c 100644 (file)
@@ -162,7 +162,7 @@ public:
 
 private:
     LineList _getSnapLines(NR::Point const &p) const;
-
+    void _addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, const NR::Point point_on_line) const;
     CanvasXYGrid *grid;
 };
 
index e59b0f30233ae211b981c5986b3b98d2503c5c97..5072b0c0e942a5972891a86d136322cdfa3fdcce 100644 (file)
@@ -17,7 +17,7 @@
  * intersection; otherwise, \a result remains unchanged.
  *
  * This function finds the intersection of the two lines (infinite)
- * defined by n0.X = d0 and x1.X = d1.  The algorithm is as follows:
+ * defined by n0.X = d0 and n1.X = d1.  The algorithm is as follows:
  * To compute the intersection point use Cramer's rule:
  * (see http://en.wikipedia.org/wiki/Cramer%27s_rule)
  * \verbatim
index d00a4e37c3b1fb7b892c71ebc72d442fe512319d..27e2533a2a8be639e49c00c8c4b60bf16d1f0412 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef SEEN_GEOM_H
+#define SEEN_GEOM_H
+
 /**
  *  \file geom.h
  *  \brief Various geometrical calculations
@@ -28,3 +31,5 @@ enum IntersectorKind {
 IntersectorKind intersector_line_intersection(NR::Point const &n0, double const d0,
                                              NR::Point const &n1, double const d1,
                                              NR::Point &result);
+                                            
+#endif /* !SEEN_GEOM_H */
index decfaf3cfd0eade4c6fee7ff2da5ea9530f1bf7d..51b5e7680542d9c61471cbb9fc2dea60b4f48fd1 100644 (file)
@@ -52,6 +52,12 @@ bool Inkscape::GuideSnapper::ThisSnapperMightSnap() const
     return _named_view == NULL ? false : (_enabled && _snap_from != 0 && _named_view->showguides);
 }
 
+void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const
+{
+       SnappedInfiniteLine dummy = SnappedInfiniteLine(snapped_point, snapped_distance, normal_to_line, point_on_line);
+       sc.guide_lines.push_back(dummy);
+}
+
 /*
   Local Variables:
   mode:c++
index 15f484711623325a6477b54ddb028db6c3154dd6..0605bdb97daad193fa0b06294e27df2477f36645 100644 (file)
@@ -28,12 +28,12 @@ namespace Inkscape
 class GuideSnapper : public LineSnapper
 {
 public:
-    GuideSnapper(SPNamedView const *nv, NR::Coord const d);
-    
+    GuideSnapper(SPNamedView const *nv, NR::Coord const d);    
     bool ThisSnapperMightSnap() const;
 
 private:
-    LineList _getSnapLines(NR::Point const &p) const;
+    LineList _getSnapLines(NR::Point const &p) const;    
+    void _addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const;
 };
 
 }
index cf46671c88602b21d67780833263cbaf49208d4e..3b91fb015df57c6b73d12eaf511c98e40972f668 100644 (file)
@@ -2,74 +2,65 @@
 #include "libnr/nr-point-fns.h"
 #include "geom.h"
 #include "line-snapper.h"
+#include "snapped-line.cpp"
 
 Inkscape::LineSnapper::LineSnapper(SPNamedView const *nv, NR::Coord const d) : Snapper(nv, d)
 {
 
 }
 
-Inkscape::SnappedPoint Inkscape::LineSnapper::_doFreeSnap(Inkscape::Snapper::PointType const &t,
+void Inkscape::LineSnapper::_doFreeSnap(SnappedConstraints &sc,
+                                                                                                       Inkscape::Snapper::PointType const &t,
                                                                                                        NR::Point const &p,
                                                                                                        bool const &f,
                                                        std::vector<NR::Point> &points_to_snap,
                                                     std::list<SPItem const *> const &it) const
 {
-    /* Snap along x (ie to vertical lines) */
-    Inkscape::SnappedPoint const v = _doConstrainedSnap(t, p, f, points_to_snap, component_vectors[NR::X], it);
-    /* Snap along y (ie to horizontal lines) */
-    Inkscape::SnappedPoint const h = _doConstrainedSnap(t, p, f, points_to_snap, component_vectors[NR::Y], it);
+    /* Snap along x (i.e. to vertical lines) */
+    _doConstrainedSnap(sc, t, p, f, points_to_snap, component_vectors[NR::X], it);
+    /* Snap along y (i.e. to horizontal lines) */
+    _doConstrainedSnap(sc, t, p, f, points_to_snap, component_vectors[NR::Y], it);
 
-    /* If we snapped to both, combine the two results.  This is so that, for example,
-    ** we snap nicely to the intersection of two guidelines.
-    */
-    if (v.getDistance() < NR_HUGE && h.getDistance() < NR_HUGE) {
-        return SnappedPoint(NR::Point(v.getPoint()[NR::X], h.getPoint()[NR::Y]), hypot(v.getDistance(), h.getDistance()));
-    }
-
-    /* If we snapped to a vertical line, return that */
-    if (v.getDistance() < NR_HUGE) {
-        return v;
-    }
-
-    /* Otherwise just return any horizontal snap; if we didn't snap to that either
-    ** we haven't snapped to anything.
-    */
-    return h;
 }
 
-Inkscape::SnappedPoint Inkscape::LineSnapper::_doConstrainedSnap(Inkscape::Snapper::PointType const &t, 
+void Inkscape::LineSnapper::_doConstrainedSnap(SnappedConstraints &sc,
+                                                                                                       Inkscape::Snapper::PointType const &t, 
                                                                                                        NR::Point const &p,
                                                     bool const &f,
                                                        std::vector<NR::Point> &points_to_snap,
                                                                ConstraintLine const &c,
                                                     std::list<SPItem const *> const &it) const
+
 {
     Inkscape::SnappedPoint s = SnappedPoint(p, NR_HUGE);
 
     /* Get the lines that we will try to snap to */
     const LineList lines = _getSnapLines(p);
-
+    
     for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) {
 
         /* Normal to the line we're trying to snap along */
         NR::Point const n(NR::rot90(NR::unit_vector(c.getDirection())));
 
-        /* Constant term of the line we're trying to snap along */
-        NR::Coord const q = dot(n, c.hasPoint() ? c.getPoint() : p);
+        NR::Point const point_on_line = c.hasPoint() ? c.getPoint() : p;
+        
+        /* Constant term of the line we're trying to snap along */        
+        NR::Coord const q = dot(n, point_on_line);
 
         /* Try to intersect this line with the target line */
-        NR::Point t = p;
+        NR::Point t = NR::Point(NR_HUGE, NR_HUGE);
         IntersectorKind const k = intersector_line_intersection(n, q, component_vectors[i->first], i->second, t);
-
+               
         if (k == INTERSECTS) {
             const NR::Coord dist = L2(t - p);
-            if (dist < getDistance() && dist < s.getDistance() ) {
-                s = SnappedPoint(t, dist);
+            //Store any line that's within snapping range
+            if (dist < getDistance()) {                
+                _addSnappedLine(sc, t, dist, c.getDirection(), t);
+                //SnappedInfiniteLine dummy = SnappedInfiniteLine(t, dist, c.getDirection(), t);
+                //sc.infinite_lines.push_back(dummy);
             }
         }
     }
-
-    return s;
 }
 
 /*
index 5d93c858e59a19f6c16357f908c58f7b65913283..a15e6ae2dc5ab6adbda34b69da1d1309d0f31ffd 100644 (file)
@@ -25,13 +25,15 @@ protected:
   typedef std::list<std::pair<NR::Dim2, NR::Coord> > LineList;
 
 private:
-  SnappedPoint _doFreeSnap(Inkscape::Snapper::PointType const &t,
+  void _doFreeSnap(SnappedConstraints &sc,
+                                       Inkscape::Snapper::PointType const &t,
                                        NR::Point const &p,
                                        bool const &first_point,
                     std::vector<NR::Point> &points_to_snap,
                     std::list<SPItem const *> const &it) const;
   
-  SnappedPoint _doConstrainedSnap(Inkscape::Snapper::PointType const &t,
+  void _doConstrainedSnap(SnappedConstraints &sc,
+                                       Inkscape::Snapper::PointType const &t,
                                        NR::Point const &p,
                                        bool const &first_point,
                     std::vector<NR::Point> &points_to_snap,
@@ -43,6 +45,8 @@ private:
    *  \return List of lines that we should try snapping to.
    */
   virtual LineList _getSnapLines(NR::Point const &p) const = 0;
+  
+  virtual void _addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const = 0;
 };
 
 }
index 53f04f8c42986497fd3c7ecfbd1de66a9568205d..10f75e5c49758a19cb885a368fb8dc8542a67b1a 100644 (file)
@@ -113,16 +113,13 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* r,
 }
 
 
-void Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
+bool Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
                                                                                 Inkscape::SnappedPoint &s,
                                          NR::Point const &p,
                                          bool const &first_point,
                                          DimensionToSnap const snap_dim) const
 {
-    /* FIXME: this seems like a hack.  Perhaps Snappers should be
-    ** in SPDesktop rather than SPNamedView?
-    */
-    SPDesktop const *desktop = SP_ACTIVE_DESKTOP;
+    bool success = false;
     
     // Determine the type of bounding box we should snap to
     SPItem::BBoxType bbox_type = SPItem::GEOMETRIC_BBOX; 
@@ -194,16 +191,20 @@ void Inkscape::ObjectSnapper::_snapNodes(Inkscape::Snapper::PointType const &t,
         
         if (dist < getDistance() && dist < s.getDistance()) {
             s = SnappedPoint(snapped_point, dist);
+            success = true;
         }       
     }
+    
+    return success;
 }
 
 
-void Inkscape::ObjectSnapper::_snapPaths(Inkscape::Snapper::PointType const &t,
+bool Inkscape::ObjectSnapper::_snapPaths(Inkscape::Snapper::PointType const &t,
                                                                                 Inkscape::SnappedPoint &s,
                                          NR::Point const &p,
                                          bool const &first_point) const
 {
+    bool success = false;
     /* FIXME: this seems like a hack.  Perhaps Snappers should be
     ** in SPDesktop rather than SPNamedView?
     */
@@ -314,21 +315,25 @@ void Inkscape::ObjectSnapper::_snapPaths(Inkscape::Snapper::PointType const &t,
                    NR::Coord const dist = NR::L2(o_dt - p);
                    if (dist < getDistance() && dist < s.getDistance()) {
                        s = SnappedPoint(o_dt, dist);
+                       success = true;
                    }
                }
         }        
     }
+    
+    return success;
 }
 
 
-Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doFreeSnap(Inkscape::Snapper::PointType const &t,
-                                                                                                                       NR::Point const &p,
-                                                                                                                       bool const &first_point,
-                                                                       std::vector<NR::Point> &points_to_snap,
-                                                            std::list<SPItem const *> const &it) const
+void Inkscape::ObjectSnapper::_doFreeSnap(SnappedConstraints &sc,
+                                                                                       Inkscape::Snapper::PointType const &t,
+                                                                                       NR::Point const &p,
+                                                                                       bool const &first_point,
+                                                               std::vector<NR::Point> &points_to_snap,
+                                               std::list<SPItem const *> const &it) const
 {
     if ( NULL == _named_view ) {
-        return SnappedPoint(p, NR_HUGE);
+        return;
     }
 
     /* Get a list of all the SPItems that we will try to snap to */
@@ -337,30 +342,35 @@ Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doFreeSnap(Inkscape::Snapper::P
        }
 
        SnappedPoint s(p, NR_HUGE);
+       bool snapped_to_node = false;
+       bool snapped_to_path = false;
 
     if (_snap_to_itemnode || _snap_to_bboxnode) {
-        _snapNodes(t, s, p, first_point, SNAP_XY);
+        snapped_to_node = _snapNodes(t, s, p, first_point, SNAP_XY);
     }
     if (_snap_to_itempath || _snap_to_bboxpath) {
-        _snapPaths(t, s, p, first_point);
+        snapped_to_path = _snapPaths(t, s, p, first_point);
     }
 
-    return s;
+    if (snapped_to_node || snapped_to_path) {
+       sc.points.push_back(s);
+    }
 }
 
 
 
-Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doConstrainedSnap(Inkscape::Snapper::PointType const &t,
-                                                                                                                                  NR::Point const &p,
-                                                                                                                                  bool const &first_point,
-                                                                                  std::vector<NR::Point> &points_to_snap,
-                                                                   ConstraintLine const &c,
-                                                                   std::list<SPItem const *> const &it) const
+void Inkscape::ObjectSnapper::_doConstrainedSnap(SnappedConstraints &sc,
+                                                                                                  Inkscape::Snapper::PointType const &t,
+                                                                                                  NR::Point const &p,
+                                                                                                  bool const &first_point,
+                                                                                  std::vector<NR::Point> &points_to_snap,
+                                                                  ConstraintLine const &c,
+                                                                  std::list<SPItem const *> const &it) const
 {
     /* FIXME: this needs implementing properly; I think we have to do the
     ** intersection of c with the objects.
     */
-    return _doFreeSnap(t, p, first_point, points_to_snap, it);
+    _doFreeSnap(sc, t, p, first_point, points_to_snap, it);
 }
 
 
index e473e3fe90dfb1655d7eb7ba8ad35943afe4337c..5b2e6f37d0616bb0aecd49613d368bbec2839a45 100644 (file)
@@ -17,7 +17,6 @@
 #include "sp-path.h"
 #include "splivarot.h"
 
-
 struct SPNamedView;
 struct SPItem;
 struct SPObject;
@@ -88,13 +87,15 @@ private:
   std::vector<SPItem*> *_candidates; 
   std::vector<NR::Point> *_points_to_snap_to;
   std::vector<Path*> *_paths_to_snap_to;
-  SnappedPoint _doFreeSnap(Inkscape::Snapper::PointType const &t,
+  void _doFreeSnap(SnappedConstraints &sc,
+                                       Inkscape::Snapper::PointType const &t,
                                        NR::Point const &p,
                                        bool const &first_point,
                     std::vector<NR::Point> &points_to_snap,
                                        std::list<SPItem const *> const &it) const;
 
-  SnappedPoint _doConstrainedSnap(Inkscape::Snapper::PointType const &t,
+  void _doConstrainedSnap(SnappedConstraints &sc,
+                                       Inkscape::Snapper::PointType const &t,
                                        NR::Point const &p,
                                        bool const &first_point,                                                                                
                                        std::vector<NR::Point> &points_to_snap,
@@ -107,13 +108,13 @@ private:
                                std::vector<NR::Point> &points_to_snap,
                                DimensionToSnap const snap_dim) const;
   
-  void _snapNodes(Inkscape::Snapper::PointType const &t,
+  bool _snapNodes(Inkscape::Snapper::PointType const &t,
                                        Inkscape::SnappedPoint &s, 
                                        NR::Point const &p, 
                                        bool const &first_point,
                                        DimensionToSnap const snap_dim) const;
                                        
-  void _snapPaths(Inkscape::Snapper::PointType const &t, 
+  bool _snapPaths(Inkscape::Snapper::PointType const &t, 
                                        Inkscape::SnappedPoint &s, 
                                        NR::Point const &p,
                                        bool const &first_point) const;
index 1529dc40d7ab21c50dc6f5aebc228237e678cf77..486507ce67fdd6aae8cc0dd312ee0e61c60166b3 100644 (file)
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include <utility>
+
 #include "sp-namedview.h"
 #include "snap.h"
+#include "snapped-line.h"
 
 #include <libnr/nr-point-fns.h>
 #include <libnr/nr-scale-ops.h>
@@ -182,29 +185,6 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t,
     return freeSnap(t, p, true, points_to_snap, lit);
 }
 
-
-/**
- *  Try to snap a point to any interested snappers.
- *
- *  \param t Type of point.
- *  \param p Point.
- *  \param first_point If true then this point is the first one from a whole bunch of points 
- *  \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation 
- *  \param it List of items to ignore when snapping.
- *  \return Snapped point.
- */
- Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t,
-                                             NR::Point const &p,
-                                             bool const &first_point,
-                                             std::vector<NR::Point> &points_to_snap,
-                                             std::list<SPItem const *> const &it) const
-{
-    SnapperList const snappers = getSnappers();
-
-       return freeSnap(t, p, first_point, points_to_snap, it, snappers);
-}
-
 /**
  *  Try to snap a point to any of the specified snappers.
  *
@@ -221,19 +201,18 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t,
                                              NR::Point const &p,
                                              bool const &first_point,
                                              std::vector<NR::Point> &points_to_snap,
-                                             std::list<SPItem const *> const &it,
-                                             SnapperList const &snappers) const
+                                             std::list<SPItem const *> const &it) const
 {
-    Inkscape::SnappedPoint r(p, NR_HUGE);
+    
+    SnappedConstraints sc;        
+    
+    SnapperList const snappers = getSnappers();
 
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        Inkscape::SnappedPoint const s = (*i)->freeSnap(t, p, first_point, points_to_snap, it);
-        if (s.getDistance() < r.getDistance()) {
-            r = s;
-        }
+        (*i)->freeSnap(sc, t, p, first_point, points_to_snap, it);
     }
 
-    return r;
+    return findBestSnap(p, sc);
 }
 
 /**
@@ -273,22 +252,19 @@ SnapManager::freeSnapAlways( Inkscape::Snapper::PointType t,
                              std::list<SPItem const *> const &it,
                              SnapperList &snappers )
 {
-    Inkscape::SnappedPoint r(p, NR_HUGE);
+    
+    SnappedConstraints sc;                
 
     for (SnapperList::iterator i = snappers.begin(); i != snappers.end(); i++) {
         gdouble const curr_gridsnap = (*i)->getDistance();
         const_cast<Inkscape::Snapper*> (*i)->setDistance(NR_HUGE);
         std::vector<NR::Point> points_to_snap;
        points_to_snap.push_back(p);    
-        Inkscape::SnappedPoint const s = (*i)->freeSnap(t, p, true, points_to_snap, it);
+        (*i)->freeSnap(sc, t, p, true, points_to_snap, it);
         const_cast<Inkscape::Snapper*> (*i)->setDistance(curr_gridsnap);
-
-        if (s.getDistance() < r.getDistance()) {
-            r = s;
-        }
     }
 
-    return r;
+    return findBestSnap(p, sc);
 }
 
 
@@ -340,17 +316,15 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType
                                                     Inkscape::Snapper::ConstraintLine const &c,
                                                     std::list<SPItem const *> const &it) const
 {
-    Inkscape::SnappedPoint r(p, NR_HUGE);
-
+    
+       SnappedConstraints sc;
+        
     SnapperList const snappers = getSnappers();
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        Inkscape::SnappedPoint const s = (*i)->constrainedSnap(t, p, first_point, points_to_snap, c, it);
-        if (s.getDistance() < r.getDistance()) {
-            r = s;
-        }
+        (*i)->constrainedSnap(sc, t, p, first_point, points_to_snap, c, it);
     }
 
-    return r;
+    return findBestSnap(p, sc);
 }
 
 Inkscape::SnappedPoint SnapManager::guideSnap(NR::Point const &p,
@@ -456,7 +430,7 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
 
        std::vector<NR::Point>::const_iterator j = transformed_points.begin();
 
-    for (std::vector<NR::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+       for (std::vector<NR::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
         
         /* Snap it */
         Inkscape::SnappedPoint const snapped = constrained ?
@@ -471,7 +445,16 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
             switch (transformation_type) {
                 case TRANSLATION:
                     result = snapped.getPoint() - *i;
-                    metric = NR::L2(result);
+                    /* 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
+                     * line. If we prefer snapping to an intersection instead of to a single 
+                     * grid line, then we cannot use "metric = NR::L2(result)". Therefore the
+                     * snapped distance will be used as a metric. Please note that the snapped
+                     * distance is defined as the distance to the nearest line of the intersection,
+                     * and not to the intersection itself! 
+                     */
+                    metric = snapped.getDistance(); //used to be: metric = NR::L2(result);
                     break;
                 case SCALE:
                 {
@@ -483,11 +466,11 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
                 }
                 case STRETCH:
                 {
-                    for (int j = 0; j < 2; j++) {
-                        if (uniform || j == dim) {
-                            result[j] = (snapped.getPoint()[dim] - origin[dim]) / ((*i)[dim] - origin[dim]);
+                    for (int a = 0; a < 2; a++) {
+                        if (uniform || a == dim) {
+                            result[a] = (snapped.getPoint()[dim] - origin[dim]) / ((*i)[dim] - origin[dim]);
                         } else {
-                            result[j] = 1;
+                            result[a] = 1;
                         }
                     }
                     metric = std::abs(result[dim] - transformation[dim]);
@@ -502,7 +485,7 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
             }
 
             /* Note it if it's the best so far */
-            if (metric < best_metric) {
+            if ((metric < best_metric) || ((metric == best_metric) && snapped.getAtIntersection() == true)) {
                 best_transformation = result;
                 best_metric = metric;
             }
@@ -510,7 +493,7 @@ std::pair<NR::Point, bool> SnapManager::_snapTransformed(
         
         j++;
     }
-
+    
     // Using " < 1e6" instead of " < NR::HUGE" for catching some rounding errors
     // These rounding errors might be caused by NRRects, see bug #1584301
     return std::make_pair(best_transformation, best_metric < 1e6);
@@ -671,6 +654,81 @@ std::pair<NR::Coord, bool> SnapManager::freeSnapSkew(Inkscape::Snapper::PointTyp
    return std::make_pair(r.first[d], r.second);
 }
 
+Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedConstraints &sc) const
+{
+       NR::Coord const guide_sens = guide.getDistance();
+       NR::Coord grid_sens = 0;
+       
+       SnapManager::SnapperList const gs = getGridSnappers();
+       SnapperList::const_iterator i = gs.begin();
+       if (i != gs.end()) {            
+               grid_sens = (*i)->getDistance();
+       }
+       
+       // Store all snappoints, optionally together with their specific snapping range
+       std::list<std::pair<Inkscape::SnappedPoint, NR::Coord> > sp_list;
+       // Most of these snapped points are already within the snapping range, because
+       // they have already been filtered by their respective snappers. In that case
+       // we can set the snapping range to NR_HUGE here. If however we're looking at
+       // intersections of e.g. a grid and guide line, then we'll have to determine 
+       // once again whether we're within snapping range. In this case we will set
+       // the snapping range to e.g. min(guide_sens, grid_sens)
+       
+       // search for the closest snapped point
+       Inkscape::SnappedPoint closestPoint;
+       if (getClosestSP(sc.points, closestPoint)) {
+               sp_list.push_back(std::make_pair(closestPoint, NR_HUGE));
+       } 
+       
+       // search for the closest snapped grid line
+       Inkscape::SnappedInfiniteLine closestGridLine;
+       if (getClosestSIL(sc.grid_lines, closestGridLine)) {    
+               sp_list.push_back(std::make_pair(Inkscape::SnappedPoint(closestGridLine), NR_HUGE));
+       }
+       
+       // search for the closest snapped guide line
+       Inkscape::SnappedInfiniteLine closestGuideLine;
+       if (getClosestSIL(sc.guide_lines, closestGuideLine)) {
+               sp_list.push_back(std::make_pair(Inkscape::SnappedPoint(closestGuideLine), NR_HUGE));
+       }
+       
+       // search for the closest snapped intersection of grid lines
+       Inkscape::SnappedPoint closestGridPoint;
+       if (getClosestIntersectionSIL(sc.grid_lines, closestGridPoint)) {
+               sp_list.push_back(std::make_pair(closestGridPoint, NR_HUGE));
+       }
+       
+       // search for the closest snapped intersection of guide lines
+       Inkscape::SnappedPoint closestGuidePoint;
+       if (getClosestIntersectionSIL(sc.guide_lines, closestGuidePoint)) {
+               sp_list.push_back(std::make_pair(closestGuidePoint, NR_HUGE));
+       }
+       
+       // search for the closest snapped intersection of grid with guide lines
+       Inkscape::SnappedPoint closestGridGuidePoint;
+       if (getClosestIntersectionSIL(sc.grid_lines, sc.guide_lines, closestGridGuidePoint)) {
+               sp_list.push_back(std::make_pair(closestGridGuidePoint, std::min(guide_sens, grid_sens)));
+       }
+       
+       // now let's see which snapped point gets a thumbs up
+       Inkscape::SnappedPoint bestPoint(p, NR_HUGE);
+       for (std::list<std::pair<Inkscape::SnappedPoint, NR::Coord> >::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
+               // first find out if this snapped point is within snapping range
+               if ((*i).first.getDistance() <= (*i).second) {
+                       // if it's the first point
+                       bool c1 = (i == sp_list.begin());  
+                       // or, if it's closer
+                       bool c2 = (*i).first.getDistance() < bestPoint.getDistance(); 
+                       // or, if it's just as close but at an intersection
+                       bool c3 = ((*i).first.getDistance() == bestPoint.getDistance()) && (*i).first.getAtIntersection(); 
+                       // then prefer this point over the previous one
+                       if (c1 || c2 || c3) {
+                               bestPoint = (*i).first;
+                       }
+               }
+       }
+       return bestPoint;                
+}
 /*
   Local Variables:
   mode:c++
index f44df8923f68c9651db6541d1bc299bd146a1aa2..29d22a1cd71dec5f3ae32883cf27f87fce3b5478 100644 (file)
@@ -22,6 +22,7 @@
 #include <libnr/nr-dim2.h>
 #include <libnr/nr-forward.h>
 #include <libnr/nr-scale.h>
+
 #include "guide-snapper.h"
 #include "object-snapper.h"
 
@@ -48,18 +49,11 @@ public:
                                     NR::Point const &p,
                                     SPItem const *it) const;
 
-    Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t,
-                                    NR::Point const &p,
-                                    bool const &first_point,
-                                    std::vector<NR::Point> &points_to_snap,
-                                    std::list<SPItem const *> const &it) const;
-
-       Inkscape::SnappedPoint freeSnap( Inkscape::Snapper::PointType t,
+    Inkscape::SnappedPoint freeSnap( Inkscape::Snapper::PointType t,
                                       NR::Point const &p,
                                       bool const &first_point,
                                       std::vector<NR::Point> &points_to_snap,
-                                      std::list<SPItem const *> const &it,
-                                      SnapperList const &snappers ) const;
+                                      std::list<SPItem const *> const &it) const;
 
     Inkscape::SnappedPoint freeSnapAlways( Inkscape::Snapper::PointType t,
                                            NR::Point const &p,
@@ -172,6 +166,8 @@ private:
                                                 NR::Point const &origin,
                                                 NR::Dim2 dim,
                                                 bool uniform) const;
+                                                
+       Inkscape::SnappedPoint findBestSnap(NR::Point const &p, SnappedConstraints &sc) const;
 };
 
 #endif /* !SEEN_SNAP_H */
diff --git a/src/snapped-line.cpp b/src/snapped-line.cpp
new file mode 100644 (file)
index 0000000..5e31fc1
--- /dev/null
@@ -0,0 +1,180 @@
+/**
+ *    \file src/snapped-line.cpp
+ *    \brief SnappedInfiniteLine class.
+ *
+ *    Authors:
+ *      Diederik van Lierop <mail@diedenrezi.nl>
+ *
+ *    Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include "snapped-line.h"
+#include "geom.h"
+
+Inkscape::SnappedLine::SnappedLine(NR::Point snapped_point, NR::Coord snapped_distance, NR::Point start_point_of_line, NR::Point end_point_of_line)
+    : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line) 
+{
+       _distance = snapped_distance;
+       _point = snapped_point;
+       _at_intersection = false;
+}
+
+Inkscape::SnappedLine::SnappedLine() 
+{
+       _start_point_of_line = NR::Point(0,0);
+       _end_point_of_line = NR::Point(0,0);
+       _distance = NR_HUGE;
+       _point = NR::Point(0,0);
+       _at_intersection = false;
+}
+
+
+Inkscape::SnappedLine::~SnappedLine()
+{
+}
+
+Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line) const 
+{
+       //TODO: Diederik, implement the intersection    
+       NR::Point const intersection = NR::Point(NR_HUGE, NR_HUGE);
+        
+       //if (result == INTERSECTS) {
+               /* The relevant snapped distance is the distance to the closest snapped line, not the
+               distance to the intersection. For example, when 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 grid line. We will be snapping
+               to the closest snapped point however, so if we ever want to snap to the intersection
+               then the distance to it should at least be equal to the other distance, not greater 
+               than it, as that would rule the intersection out
+               */
+       NR::Coord distance = std::min(_distance, line.getDistance());
+       //}
+       return SnappedPoint(intersection, distance);
+};
+
+
+
+Inkscape::SnappedInfiniteLine::SnappedInfiniteLine(NR::Point snapped_point, NR::Coord snapped_distance, NR::Point normal_to_line, NR::Point point_on_line)
+    : _normal_to_line(normal_to_line), _point_on_line(point_on_line)
+{
+       _distance = snapped_distance;
+       _point = snapped_point;
+       _at_intersection = false;
+}
+
+Inkscape::SnappedInfiniteLine::SnappedInfiniteLine() 
+{
+       _normal_to_line = NR::Point(0,0);
+       _point_on_line = NR::Point(0,0);
+       _distance = NR_HUGE;
+       _point = NR::Point(0,0);
+       _at_intersection = false;
+}
+
+Inkscape::SnappedInfiniteLine::~SnappedInfiniteLine()
+{
+}
+
+Inkscape::SnappedPoint Inkscape::SnappedInfiniteLine::intersect(SnappedInfiniteLine const &line) const 
+{
+       // Calculate the intersection of to infinite lines, which are both within snapping range
+       // The point of intersection should be considered for snapping, but might be outside the snapping range
+       
+       NR::Point intersection = NR::Point(NR_HUGE, NR_HUGE);
+       NR::Coord distance = NR_HUGE;
+       
+       IntersectorKind result = intersector_line_intersection(getNormal(), getConstTerm(), 
+                                               line.getNormal(), line.getConstTerm(), intersection);
+        
+       /*std::cout << "n0 = " << getNormal() << std::endl;
+       std::cout << "n1 = " << line.getNormal() << std::endl;
+       std::cout << "c0 = " << getConstTerm() << std::endl;
+       std::cout << "c1 = " << line.getConstTerm() << std::endl;*/
+       
+       if (result == INTERSECTS) {
+               /* The relevant snapped distance is the distance to the closest snapped line, not the
+               distance to the intersection. For example, when 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 grid line. We will be snapping
+               to the closest snapped point however, so if we ever want to snap to the intersection
+               then the distance to it should at least be equal to the other distance, not greater 
+               than it, as that would rule the intersection out
+               */
+               distance = std::min(_distance, line.getDistance());
+               //std::cout << "Intersected nicely, now getSIL distance = " << distance << std::endl;
+       }
+       
+       //std::cout << "getSIL distance = " << distance << std::endl;
+       
+       return SnappedPoint(intersection, distance, result == INTERSECTS);      
+}
+
+// search for the closest snapped infinite line
+bool getClosestSIL(std::list<Inkscape::SnappedInfiniteLine> &list, Inkscape::SnappedInfiniteLine &result) 
+{
+       bool success = false;
+       
+       for (std::list<Inkscape::SnappedInfiniteLine>::const_iterator i = list.begin(); i != list.end(); i++) {
+               if ((i == list.begin()) || (*i).getDistance() < result.getDistance()) {
+                       result = *i;
+                       success = true;
+               }       
+       }
+       
+       return success; 
+}
+
+// search for the closest intersection of two snapped infinite lines, which are both member of the same collection
+bool getClosestIntersectionSIL(std::list<Inkscape::SnappedInfiniteLine> &list, Inkscape::SnappedPoint &result)
+{
+       bool success = false;
+       
+       for (std::list<Inkscape::SnappedInfiniteLine>::const_iterator i = list.begin(); i != list.end(); i++) {
+               std::list<Inkscape::SnappedInfiniteLine>::const_iterator j = i;
+               j++;
+               for (; j != list.end(); j++) {
+                       Inkscape::SnappedPoint sp = (*i).intersect(*j);
+                       if (sp.getAtIntersection()) {
+                               if (!success || sp.getDistance() < result.getDistance()) {  
+                                       // !success because the first intersection cannot be compared to a previous one
+                                       result = sp;
+                                       success = true;
+                               }
+                       }                               
+               }
+       }
+       
+       return success; 
+}
+
+// search for the closest intersection of two snapped infinite lines, which are in two different collections
+bool getClosestIntersectionSIL(std::list<Inkscape::SnappedInfiniteLine> &list1, std::list<Inkscape::SnappedInfiniteLine> &list2, Inkscape::SnappedPoint &result)
+{
+       bool success = false;
+       
+       for (std::list<Inkscape::SnappedInfiniteLine>::const_iterator i = list1.begin(); i != list1.end(); i++) {
+               for (std::list<Inkscape::SnappedInfiniteLine>::const_iterator j = list2.begin(); j != list2.end(); j++) {
+                       Inkscape::SnappedPoint sp = (*i).intersect(*j);
+                       if (sp.getAtIntersection()) {
+                               if (!success || sp.getDistance() < result.getDistance()) {
+                                       // !success because the first intersection cannot be compared to a previous one
+                                       result = sp;
+                                       success = true;
+                               }
+                       }                               
+               }
+       }
+       
+       return success;
+}
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/snapped-line.h b/src/snapped-line.h
new file mode 100644 (file)
index 0000000..0b8c905
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef SEEN_SNAPPEDLINE_H
+#define SEEN_SNAPPEDLINE_H
+
+/**
+ *    \file src/snapped-line.h
+ *    \brief SnappedInfiniteLine class.
+ *
+ *    Authors:
+ *      Diederik van Lierop <mail@diedenrezi.nl>
+ *
+ *    Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include <vector>
+#include <list>
+#include "libnr/nr-coord.h"
+#include "libnr/nr-point.h"
+#include <libnr/nr-point-fns.h>
+#include "snapped-point.h"
+
+namespace Inkscape
+{
+
+/// Class describing the result of an attempt to snap to a line segment.
+class SnappedLine : public SnappedPoint
+{
+public:
+       SnappedLine();
+    SnappedLine(NR::Point snapped_point, NR::Coord snapped_distance, NR::Point start_point_of_line, NR::Point end_point_of_line);
+    ~SnappedLine();
+    Inkscape::SnappedPoint intersect(SnappedLine const &line) const; //intersect with another SnappedLine
+    
+private:
+       NR::Point _start_point_of_line;
+       NR::Point _end_point_of_line;    
+};
+
+
+/// Class describing the result of an attempt to snap to an infinite line.
+class SnappedInfiniteLine : public SnappedPoint
+{
+public:
+       SnappedInfiniteLine();
+    SnappedInfiniteLine(NR::Point snapped_point, NR::Coord snapped_distance, NR::Point normal_to_line, NR::Point point_on_line);
+    ~SnappedInfiniteLine();
+    Inkscape::SnappedPoint intersect(SnappedInfiniteLine const &line) const; //intersect with another SnappedInfiniteLine
+    // This line is described by this equation:
+    //         a*x + b*y = c  <->  nx*px + ny+py = c  <->  n.p = c
+    NR::Point getNormal() const {return _normal_to_line;}                                                      // n = (nx, ny)
+    NR::Point getPointOnLine() const {return _point_on_line;}                                          // p = (px, py)
+    NR::Coord getConstTerm() const {return dot(_normal_to_line, _point_on_line);}      // c = n.p = nx*px + ny*py;
+       
+private:
+       NR::Point _normal_to_line;
+       NR::Point _point_on_line;    
+};
+
+}
+
+bool getClosestSIL(std::list<Inkscape::SnappedInfiniteLine> &list, Inkscape::SnappedInfiniteLine &result);
+bool getClosestIntersectionSIL(std::list<Inkscape::SnappedInfiniteLine> &list, Inkscape::SnappedPoint &result);
+bool getClosestIntersectionSIL(std::list<Inkscape::SnappedInfiniteLine> &list1, std::list<Inkscape::SnappedInfiniteLine> &list2, Inkscape::SnappedPoint &result);
+
+#endif /* !SEEN_SNAPPEDLINE_H */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
index 5d0d242dde08b2f5ce716e51b478aacf1e5a7260..9df76b7047f362945101e5bed31ffa93a57f0c48 100644 (file)
@@ -9,28 +9,24 @@
  */
 
 #include "snapped-point.h"
+#include <libnr/nr-values.h>
 
-Inkscape::SnappedPoint::SnappedPoint(NR::Point p, NR::Coord d)
-    : _distance(d), _point(p)
+Inkscape::SnappedPoint::SnappedPoint(NR::Point p, NR::Coord d, bool at_intersection)
+    : _distance(d), _point(p), _at_intersection(at_intersection)
 {
-
 }
 
-Inkscape::SnappedPoint::~SnappedPoint()
+Inkscape::SnappedPoint::SnappedPoint()
 {
-    /// TODO : empty the _hightlight_groups vector and destroy the
-    ///                 HighlightGroup items it holds
+       _distance = NR_HUGE;
+       _point = NR::Point(0,0);
+       _at_intersection = false;
 }
 
 
-void Inkscape::SnappedPoint::addHighlightGroup(HighlightGroup *group)
-{
-    /// TODO
-}
 
-void Inkscape::SnappedPoint::addHighlightGroups(std::vector<HighlightGroup*> *groups)
+Inkscape::SnappedPoint::~SnappedPoint()
 {
-    /// TODO
 }
 
 NR::Coord Inkscape::SnappedPoint::getDistance() const
@@ -43,12 +39,21 @@ NR::Point Inkscape::SnappedPoint::getPoint() const
     return _point;
 }
 
-std::vector<Inkscape::HighlightGroup*> Inkscape::SnappedPoint::getHighlightGroups() const
+// search for the closest snapped point
+bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoint &result) 
 {
-    return _hightlight_groups;
+       bool success = false;
+       
+       for (std::list<Inkscape::SnappedPoint>::const_iterator i = list.begin(); i != list.end(); i++) {
+               if ((i == list.begin()) || (*i).getDistance() < result.getDistance()) {
+                       result = *i;
+                       success = true;
+               }       
+       }
+       
+       return success;
 }
 
-
 /*
   Local Variables:
   mode:c++
index 0669ddd21621ad8b3a9854ae5c73135962c705a8..147922b2f9933c43c32df86f1f28dd790115a87e 100644 (file)
  */
 
 #include <vector>
+#include <list>
 #include "libnr/nr-coord.h"
 #include "libnr/nr-point.h"
 
 namespace Inkscape
 {
-
-class HighlightGroup;
-
+       
 /// Class describing the result of an attempt to snap.
 class SnappedPoint
 {
 public:
-    SnappedPoint() {}
-    SnappedPoint(::NR::Point p, ::NR::Coord d);
+    SnappedPoint();
+    SnappedPoint(::NR::Point p, ::NR::Coord d, bool at_intersection = false);
     ~SnappedPoint();
 
-    void addHighlightGroup(HighlightGroup *group);
-    void addHighlightGroups(std::vector<HighlightGroup*> *groups);
-
-    ::NR::Coord getDistance() const;
+    NR::Coord getDistance() const;
     NR::Point getPoint() const;
-    std::vector<HighlightGroup*> getHighlightGroups() const;
-
-private:
-    ::NR::Coord _distance;
-    ::NR::Point _point;
-    std::vector<HighlightGroup*> _hightlight_groups;
-};
+    bool getAtIntersection() const {return _at_intersection;}
+    
+protected:
+    NR::Coord _distance;
+    NR::Point _point;
+    bool _at_intersection;
+};    
 
 }
+
+bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoint &result);
+
+
 #endif /* !SEEN_SNAPPEDPOINT_H */
 
 /*
index 17d7b7137467cf93615d3f2f790de9e0d060a77d..5edde2405868b29fcfb04a5564a7ece96f6d5043 100644 (file)
@@ -91,7 +91,9 @@ void Inkscape::Snapper::setEnabled(bool s)
  *  \return Snapped point.
  */
 
-Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType const &t,
+void Inkscape::Snapper::freeSnap(SnappedConstraints &sc,
+                                                                                                  
+                                                                                                  PointType const &t,
                                                    NR::Point const &p,
                                                    bool const &first_point,
                                                   std::vector<NR::Point> &points_to_snap,                                               
@@ -99,7 +101,7 @@ Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType const &t,
 {
     std::list<SPItem const *> lit;
     lit.push_back(it);
-    return freeSnap(t, p, first_point, points_to_snap, lit);
+    freeSnap(sc, t, p, first_point, points_to_snap, lit);
 }
 
 
@@ -114,17 +116,19 @@ Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType const &t,
  *  \return Snapped point.
  */
 
-Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType const &t,
+void Inkscape::Snapper::freeSnap(SnappedConstraints &sc, 
+                                                                                                  
+                                                                                                  PointType const &t,
                                                    NR::Point const &p,
                                                    bool const &first_point,
                                                   std::vector<NR::Point> &points_to_snap,                                       
                                                    std::list<SPItem const *> const &it) const
 {
     if (_enabled == false || getSnapFrom(t) == false) {
-        return SnappedPoint(p, NR_HUGE);
+        return;
     }
 
-    return _doFreeSnap(t, p, first_point, points_to_snap, it);
+    _doFreeSnap(sc, t, p, first_point, points_to_snap, it);
 }
 
 
@@ -141,7 +145,9 @@ Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType const &t,
  *  \return Snapped point.
  */
 
-Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType const &t,
+void Inkscape::Snapper::constrainedSnap(SnappedConstraints &sc, 
+                                                                                                                 
+                                                                                                                 PointType const &t,
                                                           NR::Point const &p,
                                                           bool const &first_point,
                                                                  std::vector<NR::Point> &points_to_snap,
@@ -150,7 +156,7 @@ Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType const &t,
 {
     std::list<SPItem const *> lit;
     lit.push_back(it);
-    return constrainedSnap(t, p, first_point, points_to_snap, c, lit);
+    constrainedSnap(sc, t, p, first_point, points_to_snap, c, lit);
 }
 
 
@@ -165,7 +171,9 @@ Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType const &t,
  *  \return Snapped point.
  */
 
-Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType const &t,
+void Inkscape::Snapper::constrainedSnap(SnappedConstraints &sc, 
+                                                                                                                 
+                                                                                                                 PointType const &t,
                                                           NR::Point const &p,
                                                           bool const &first_point,
                                                                  std::vector<NR::Point> &points_to_snap,                                                
@@ -173,10 +181,10 @@ Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType const &t,
                                                           std::list<SPItem const *> const &it) const
 {
     if (_enabled == false || getSnapFrom(t) == false) {
-        return SnappedPoint(p, NR_HUGE);
+        return;
     }
 
-    return _doConstrainedSnap(t, p, first_point, points_to_snap, c, it);
+    _doConstrainedSnap(sc, t, p, first_point, points_to_snap, c, it);
 }
 
 /*
index 5b6b4a2588aaea0f9448a4c5e8f645a58a061a0f..a122db72fa1efe428dfc90edf40eb14f7170c99d 100644 (file)
 #include <list>
 #include "libnr/nr-coord.h"
 #include "libnr/nr-point.h"
+
 #include "snapped-point.h"
+#include "snapped-line.h"
+
+struct SnappedConstraints {
+       std::list<Inkscape::SnappedPoint> points; 
+       std::list<Inkscape::SnappedLine> lines;
+       std::list<Inkscape::SnappedInfiniteLine> grid_lines;
+       std::list<Inkscape::SnappedInfiniteLine> guide_lines;
+};
 
 struct SPNamedView;
 struct SPItem;
@@ -50,13 +59,15 @@ public:
 
     void setEnabled(bool s);
 
-    SnappedPoint freeSnap(PointType const &t,
+    void freeSnap(SnappedConstraints &sc,
+                                         PointType const &t,
                           NR::Point const &p,
                           bool const &first_point,                                             
                           std::vector<NR::Point> &points_to_snap,                                               
                           SPItem const *it) const;
 
-    SnappedPoint freeSnap(PointType const &t,
+    void freeSnap(SnappedConstraints &sc,
+                                         PointType const &t,
                           NR::Point const &p,
                           bool const &first_point,                                             
                           std::vector<NR::Point> &points_to_snap,                                               
@@ -87,19 +98,22 @@ public:
         NR::Point _direction;
     };
 
-    SnappedPoint constrainedSnap(PointType const &t,
+    void constrainedSnap(SnappedConstraints &sc,
+                                                        PointType const &t,
                                  NR::Point const &p,
                                  bool const &first_point,
                                  std::vector<NR::Point> &points_to_snap,       
                                  ConstraintLine const &c,
                                  SPItem const *it) const;
 
-    SnappedPoint constrainedSnap(PointType const &t,
+    void constrainedSnap(SnappedConstraints &sc,
+                                                        PointType const &t,
                                  NR::Point const &p,
                                  bool const &first_point,
                                  std::vector<NR::Point> &points_to_snap,                                                
                                  ConstraintLine const &c,
                                  std::list<SPItem const *> const &it) const;
+                                 
 protected:
     SPNamedView const *_named_view;
     int _snap_from; ///< bitmap of point types that we will snap from
@@ -116,7 +130,8 @@ private:
      *  \param it Items that should not be snapped to.
      *  \return Snapped point.
      */
-    virtual SnappedPoint _doFreeSnap(PointType const &t,
+    virtual void _doFreeSnap(SnappedConstraints &sc,
+                                                                PointType const &t,
                                                                 NR::Point const &p,
                                                                 bool const &first_point,                                             
                                                                 std::vector<NR::Point> &points_to_snap,
@@ -132,14 +147,15 @@ private:
      *  \param it Items that should not be snapped to.
      *  \return Snapped point.
      */    
-    virtual SnappedPoint _doConstrainedSnap(PointType const &t,
+    virtual void _doConstrainedSnap(SnappedConstraints &sc,
+                                                                               PointType const &t,
                                                                                NR::Point const &p,
                                                                                bool const &first_point,
                                                                                std::vector<NR::Point> &points_to_snap,
                                             ConstraintLine const &c,
                                             std::list<SPItem const *> const &it) const = 0;
     
-    ::NR::Coord _distance; ///< snap distance (desktop coordinates)
+    NR::Coord _distance; ///< snap distance (desktop coordinates)
 };
 
 }