]> git.tokkee.org Git - inkscape.git/commitdiff

Code

Various snapping cleanups and bug fixes.
authorcth103 <cth103@users.sourceforge.net>
Fri, 5 May 2006 14:22:41 +0000 (14:22 +0000)
committercth103 <cth103@users.sourceforge.net>
Fri, 5 May 2006 14:22:41 +0000 (14:22 +0000)
12 files changed:
src/context-fns.cpp
src/draw-context.cpp
src/line-snapper.cpp
src/line-snapper.h
src/nodepath.cpp
src/object-snapper.cpp
src/object-snapper.h
src/seltrans.cpp
src/snap.cpp
src/snap.h
src/snapper.cpp
src/snapper.h

index 5db98ec16955f107703ecf5296ef4a6f601d5de2..f11b2fcfa80fad5f732c4a0f9fda85212563641c 100644 (file)
@@ -108,12 +108,12 @@ NR::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::Snapper::SNAP_POINT,
-                                     p[0], p[0] - p[1], item);
+            s[0] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, p[0],
+                                     Inkscape::Snapper::ConstraintLine(p[0] - p[1]), item);
 
             /* Try to snap p[1] (the dragged corner) along the constraint vector */
-            s[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT,
-                                     p[1], p[1] - p[0], item);
+            s[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, p[1],
+                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item);
 
             /* Choose the best snap and update points accordingly */
             if (s[0].getDistance() < s[1].getDistance()) {
@@ -128,7 +128,8 @@ NR::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;
-            p[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, p[1], p[1] - p[0], item).getPoint();
+            p[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, p[1],
+                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item).getPoint();
         }
 
     } else if (shift) {
index aa1480c675d4d335aa1e337876e7ae042024ecdc..75ded20f5a04a388aab181a92d8d9f56fdf49f7a 100644 (file)
@@ -374,7 +374,7 @@ void spdc_endpoint_snap_rotation(SPEventContext const *const ec, NR::Point &p, N
         /* Snap it along best vector */
         SnapManager const &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
         p = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT | Inkscape::Snapper::BBOX_POINT,
-                              p, best, NULL).getPoint();
+                              p, Inkscape::Snapper::ConstraintLine(best), NULL).getPoint();
     }
 }
 
index 383c1fb96725f731c9c62574a00e5422a033d095..a2c6b944bcc28ff10c36963b8fbb1bb142901cda 100644 (file)
@@ -35,23 +35,21 @@ Inkscape::SnappedPoint Inkscape::LineSnapper::_doFreeSnap(NR::Point const &p,
 }
 
 Inkscape::SnappedPoint Inkscape::LineSnapper::_doConstrainedSnap(NR::Point const &p,
-                                                                 NR::Point const &c,
+                                                                 ConstraintLine const &c,
                                                                  std::list<SPItem const *> const &it) const
 {
     Inkscape::SnappedPoint s = SnappedPoint(p, NR_HUGE);
 
-    NR::Point const v = NR::unit_vector(c);
-
     /* 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(v));
+        NR::Point const n(NR::rot90(NR::unit_vector(c.getDirection())));
 
-        /* Hence constant term of the line we're trying to snap along */
-        NR::Coord const q = dot(n, p);
+        /* Constant term of the line we're trying to snap along */
+        NR::Coord const q = dot(n, c.hasPoint() ? c.getPoint() : p);
 
         /* Try to intersect this line with the target line */
         NR::Point t = p;
index 581466d330533b4ebbdd005c4d31440525253b9e..2816b2ec01e3648d853f309ecf6732f25eabfb62 100644 (file)
@@ -29,7 +29,7 @@ private:
                           std::list<SPItem const *> const &it) const;
   
   SnappedPoint _doConstrainedSnap(NR::Point const &p,
-                                 NR::Point const &c,
+                                 ConstraintLine const &c,
                                  std::list<SPItem const *> const &it) const;
   
   /**
index 64611f12cbf5edf5b7a4b2bc6ff1e1319407f058..7eb68d7d644cb69be0d20f7e8f5feffb70e6d844 100644 (file)
@@ -2852,7 +2852,7 @@ static gboolean node_handle_request(SPKnot *knot, NR::Point *p, guint state, gpo
             NR::Coord const scal = dot(delta, ndelta) / linelen;
             (*p) = n->pos + (scal / linelen) * ndelta;
         }
-        *p = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, *p, ndelta, NULL).getPoint();
+        *p = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, *p, Inkscape::Snapper::ConstraintLine(*p, ndelta), NULL).getPoint();
     } else {
         *p = m.freeSnap(Inkscape::Snapper::SNAP_POINT, *p, NULL).getPoint();
     }
index 9a3f61525d91c288060ce1b09b1a7fdc204554d9..e7a975d01397f8066cb2921f0b302be11ab53dd6 100644 (file)
@@ -167,7 +167,7 @@ Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doFreeSnap(NR::Point const &p,
 
 
 Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doConstrainedSnap(NR::Point const &p,
-                                                                   NR::Point const &c,
+                                                                   ConstraintLine const &c,
                                                                    std::list<SPItem const *> const &it) const
 {
     /* FIXME: this needs implementing properly; I think we have to do the
index 189e96e3e249c925303a8c55edd967a4605b70f6..4e74b2f744b246a824bbf24fee146110901674e0 100644 (file)
@@ -48,7 +48,7 @@ private:
                           std::list<SPItem const *> const &it) const;
 
   SnappedPoint _doConstrainedSnap(NR::Point const &p,
-                                 NR::Point const &c,
+                                 ConstraintLine const &c,
                                  std::list<SPItem const *> const &it) const;
   
   void _findCandidates(std::list<SPItem*>& c,
index d6628ea7201a957c6e4b354b97984096001d9c45..2d4201fac5fa3f91bc8d0bed8cfb9d02e5a215d5 100644 (file)
@@ -769,6 +769,8 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state)
         }
     }
 
+    SnapManager const &m = _desktop->namedview->snap_manager;
+
     /* Get a STL list of the selected items.
     ** FIXME: this should probably be done by Inkscape::Selection.
     */
@@ -778,50 +780,60 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state)
     }
 
     if ((state & GDK_CONTROL_MASK) || _desktop->isToolboxButtonActive ("lock")) {
-        /* Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y] */
-
-        NR::Dim2 locked_dim;
-
-        /* Lock aspect ratio, using the smaller of the x and y factors */
-        if (fabs(s[NR::X]) > fabs(s[NR::Y])) {
-            s[NR::X] = fabs(s[NR::Y]) * sign(s[NR::X]);
-            locked_dim = NR::X;
-        } else {
-            s[NR::Y] = fabs(s[NR::X]) * sign(s[NR::Y]);
-            locked_dim = NR::Y;
-        }
-
-        /* Snap the scale factor */
-        std::pair<double, bool> bb = namedview_vector_snap_list(_desktop->namedview,
-                                                                Snapper::BBOX_POINT, _bbox_points,
-                                                                _origin, s, it);
-        std::pair<double, bool> sn = namedview_vector_snap_list(_desktop->namedview,
-                                                                Snapper::SNAP_POINT, _snap_points,
-                                                                _origin, s, it);
-
-        double bd = bb.second ? fabs(bb.first - s[locked_dim]) : NR_HUGE;
-        double sd = sn.second ? fabs(sn.first - s[locked_dim]) : NR_HUGE;
-        double r = (bd < sd) ? bb.first : sn.first;
-
-        for ( unsigned int i = 0 ; i < 2 ; i++ ) {
-            s[i] = r * sign(s[i]);
-        }
+        /* Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y].
+        ** To do this, we snap along a suitable constraint vector from the origin.
+        */
 
+        NR::Point const cv = NR::Point(
+            pt[NR::X] > _origin[NR::X] ? 1 : -1,
+            pt[NR::Y] > _origin[NR::Y] ? 1 : -1
+            );
+
+        std::pair<NR::scale, bool> bb = m.constrainedSnapScale(Snapper::BBOX_POINT,
+                                                               _bbox_points,
+                                                               it,
+                                                               Snapper::ConstraintLine(_origin, cv),
+                                                               s,
+                                                               _origin);
+
+        std::pair<NR::scale, bool> sn = m.constrainedSnapScale(Snapper::SNAP_POINT,
+                                                               _snap_points,
+                                                               it,
+                                                               Snapper::ConstraintLine(_origin, cv),
+                                                               s,
+                                                               _origin);
+
+        /* Choose the smaller difference in scale.  Since s[X] == s[Y] we can
+        ** just compare difference in s[X].
+        */
+        double const bd = bb.second ? fabs(bb.first[NR::X] - s[NR::X]) : NR_HUGE;
+        double const sd = sn.second ? fabs(sn.first[NR::X] - s[NR::X]) : NR_HUGE;
+        s = (bd < sd) ? bb.first : sn.first;
+        
     } else {
         /* Scale aspect ratio is unlocked */
-        for ( unsigned int i = 0 ; i < 2 ; i++ ) {
-            std::pair<double, bool> bb = namedview_dim_snap_list_scale(_desktop->namedview,
-                                                                       Snapper::BBOX_POINT, _bbox_points,
-                                                                       _origin, s[i], NR::Dim2(i), it);
-            std::pair<double, bool> sn = namedview_dim_snap_list_scale(_desktop->namedview,
-                                                                       Snapper::SNAP_POINT, _snap_points,
-                                                                       _origin, s[i], NR::Dim2(i), it);
-
-            /* Pick the snap that puts us closest to the original scale */
-            NR::Coord bd = bb.second ? fabs(bb.first - s[i]) : NR_HUGE;
-            NR::Coord sd = sn.second ? fabs(sn.first - s[i]) : NR_HUGE;
-            s[i] = (bd < sd) ? bb.first : sn.first;
-        }
+        
+        std::pair<NR::scale, bool> bb = m.freeSnapScale(Snapper::BBOX_POINT,
+                                                        _bbox_points,
+                                                        it,
+                                                        s,
+                                                        _origin);
+        std::pair<NR::scale, bool> sn = m.freeSnapScale(Snapper::SNAP_POINT,
+                                                        _snap_points,
+                                                        it,
+                                                        s,
+                                                        _origin);
+
+        /* Pick the snap that puts us closest to the original scale */
+        NR::Coord bd = bb.second ?
+            fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) -
+                 NR::L2(NR::Point(s[NR::X], s[NR::Y])))
+            : NR_HUGE;
+        NR::Coord sd = sn.second ?
+            fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) -
+                 NR::L2(NR::Point(s[NR::X], s[NR::Y])))
+            : NR_HUGE;
+        s = (bd < sd) ? bb.first : sn.first;
     }
 
     /* Update the knot position */
@@ -1287,10 +1299,15 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state)
             for (unsigned int dim = 0; dim < 2; dim++) {
                 s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::BBOX_POINT,
                                                          _bbox_points,
-                                                         component_vectors[dim], it, dxy));
+                                                         it,
+                                                         Inkscape::Snapper::ConstraintLine(component_vectors[dim]),
+                                                         dxy));
+                            
                 s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::SNAP_POINT,
                                                          _snap_points,
-                                                         component_vectors[dim], it, dxy));
+                                                         it,
+                                                         Inkscape::Snapper::ConstraintLine(component_vectors[dim]),
+                                                         dxy));
             }
 
         } else {
index 452a1e496bb7583396480dfbbbf6b6b2b0a9f42e..ca7efde73ee8ed46b235d265494564bc2e9c39fe 100644 (file)
@@ -21,7 +21,7 @@
 #include <libnr/nr-scale-ops.h>
 #include <libnr/nr-values.h>
 
-SnapManager::SnapManager(SPNamedViewv) : grid(v, 0), guide(v, 0), object(v, 0)
+SnapManager::SnapManager(SPNamedView const *v) : grid(v, 0), guide(v, 0), object(v, 0)
 {
 
 }
@@ -85,7 +85,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t,
 
 Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t,
                                                     NR::Point const &p,
-                                                    NR::Point const &c,
+                                                    Inkscape::Snapper::ConstraintLine const &c,
                                                     SPItem const *it) const
 {
     std::list<SPItem const *> lit;
@@ -96,7 +96,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType
 
 Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t,
                                                     NR::Point const &p,
-                                                    NR::Point const &c,
+                                                    Inkscape::Snapper::ConstraintLine const &c,
                                                     std::list<SPItem const *> const &it) const
 {
     Inkscape::SnappedPoint r(p, NR_HUGE);
@@ -113,74 +113,120 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType
 }
 
 
-std::pair<NR::Point, bool> SnapManager::freeSnapTranslation(Inkscape::Snapper::PointType t,
-                                                            std::vector<NR::Point> const &p,
-                                                            std::list<SPItem const *> const &it,
-                                                            NR::Point const &tr) const
+std::pair<NR::Point, bool> SnapManager::_snapTransformed(Inkscape::Snapper::PointType type,
+                                                         std::vector<NR::Point> const &points,
+                                                         std::list<SPItem const *> const &ignore,
+                                                         bool constrained,
+                                                         Inkscape::Snapper::ConstraintLine const &constraint,
+                                                         Transformation transformation_type,
+                                                         NR::Point const &transformation,
+                                                         NR::Point const &origin) const
 {
+    /* We have a list of points, which we are proposing to transform in some way.  We need to see
+    ** if any of these points, when transformed, snap to anything.  If they do, we return the
+    ** appropriate transformation with `true'; otherwise we return the original scale with `false'.
+    */
+
+    /* Quick check to see if we have any snappers that are enabled */
     if (willSnapSomething() == false) {
-        return std::make_pair(tr, false);
+        return std::make_pair(transformation, false);
     }
 
-    NR::Point best_translation = tr;
-    NR::Coord best_distance = NR_HUGE;
-
-    for (std::vector<NR::Point>::const_iterator i = p.begin(); i != p.end(); i++) {
-        /* Translated version of this point */
-        NR::Point const q = *i + tr;
+    /* The current best transformation */
+    NR::Point best_transformation = transformation;
+    /* The current best metric for the best transformation; lower is better, NR_HUGE
+    ** means that we haven't snapped anything.
+    */
+    NR::Coord best_metric = NR_HUGE;
+
+    for (std::vector<NR::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+
+        /* Work out the transformed version of this point */
+        NR::Point transformed;
+        switch (transformation_type) {
+            case TRANSLATION:
+                transformed = *i + transformation;
+                break;
+            case SCALE:
+                transformed = ((*i - origin) * NR::scale(transformation[NR::X], transformation[NR::Y])) + origin;
+                break;
+            default:
+                g_assert_not_reached();
+        }
+        
         /* Snap it */
-        Inkscape::SnappedPoint s = freeSnap(t, q, it);
-        if (s.getDistance() < NR_HUGE) {
-            /* Resulting translation */
-            NR::Point const r = s.getPoint() - *i;
-            NR::Coord const d = NR::L2(r);
-            if (d < best_distance) {
-                best_distance = d;
-                best_translation = r;
+        Inkscape::SnappedPoint const snapped = constrained ?
+            constrainedSnap(type, transformed, constraint, ignore) : freeSnap(type, transformed, ignore);
+
+        if (snapped.getDistance() < NR_HUGE) {
+            /* We snapped.  Find the transformation that describes where the snapped point has
+            ** ended up, and also the metric for this transformation.
+            */
+            NR::Point result;
+            NR::Coord metric;
+            switch (transformation_type) {
+                case TRANSLATION:
+                    result = snapped.getPoint() - *i;
+                    metric = NR::L2(result);
+                    break;
+                case SCALE:
+                    NR::Point const a = (snapped.getPoint() - origin);
+                    NR::Point const b = (*i - origin);
+                    result = NR::Point(a[NR::X] / b[NR::X], a[NR::Y] / b[NR::Y]);
+                    metric = std::abs(NR::L2(result) - NR::L2(transformation));
+                    break;
+            }
+
+            /* Note it if it's the best so far */
+            if (metric < best_metric && metric != 0) {
+                best_transformation = result;
+                best_metric = metric;
             }
         }
     }
+        
+    return std::make_pair(best_transformation, best_metric < NR_HUGE);
+}
+
 
-    return std::make_pair(best_translation, best_distance < NR_HUGE);
+std::pair<NR::Point, bool> SnapManager::freeSnapTranslation(Inkscape::Snapper::PointType t,
+                                                            std::vector<NR::Point> const &p,
+                                                            std::list<SPItem const *> const &it,
+                                                            NR::Point const &tr) const
+{
+    return _snapTransformed(t, p, it, false, NR::Point(), TRANSLATION, tr, NR::Point(0, 0));
 }
 
 
 
 std::pair<NR::Point, bool> SnapManager::constrainedSnapTranslation(Inkscape::Snapper::PointType t,
                                                                    std::vector<NR::Point> const &p,
-                                                                   NR::Point const &c,
                                                                    std::list<SPItem const *> const &it,
+                                                                   Inkscape::Snapper::ConstraintLine const &c,
                                                                    NR::Point const &tr) const
 {
-    if (willSnapSomething() == false) {
-        return std::make_pair(tr, false);
-    }
-
-    NR::Point best_translation = tr;
-    NR::Coord best_distance = NR_HUGE;
-
-    for (std::vector<NR::Point>::const_iterator i = p.begin(); i != p.end(); i++) {
-        /* Translated version of this point */
-        NR::Point const q = *i + tr;
-        /* Snap it */
-        Inkscape::SnappedPoint s = constrainedSnap(t, q, c, it);
-        if (s.getDistance() < NR_HUGE) {
-            /* Resulting translation */
-            NR::Point const r = s.getPoint() - *i;
-            NR::Coord const d = NR::L2(r);
-            if (d < best_distance) {
-                best_distance = d;
-                best_translation = r;
-            }
-        }
-    }
-
-    return std::make_pair(best_translation, best_distance < NR_HUGE);
+    return _snapTransformed(t, p, it, true, c, TRANSLATION, tr, NR::Point(0, 0));
 }
 
+std::pair<NR::scale, bool> SnapManager::freeSnapScale(Inkscape::Snapper::PointType t,
+                                                      std::vector<NR::Point> const &p,
+                                                      std::list<SPItem const *> const &it,
+                                                      NR::scale const &s,
+                                                      NR::Point const &o) const
+{
+    return _snapTransformed(t, p, it, false, NR::Point(0, 0), SCALE, NR::Point(s[NR::X], s[NR::Y]), o);
+}
 
 
-
+std::pair<NR::scale, bool> SnapManager::constrainedSnapScale(Inkscape::Snapper::PointType t,
+                                                             std::vector<NR::Point> const &p,
+                                                             std::list<SPItem const *> const &it,
+                                                             Inkscape::Snapper::ConstraintLine const &c,
+                                                             NR::scale const &s,
+                                                             NR::Point const &o) const
+{
+    return _snapTransformed(t, p, it, true, c, SCALE, NR::Point(s[NR::X], s[NR::Y]), o);
+}    
 
 
 /// Minimal distance to norm before point is considered for snap.
@@ -292,7 +338,7 @@ std::pair<double, bool> namedview_vector_snap_list(SPNamedView const *nv, Inksca
 
     return std::make_pair(ratio, dist < NR_HUGE);
 }
-
+   
 
 /**
  * Try to snap points in \a p after they have been scaled by \a sx with respect to
index c77e8df41aeb5441af1ef84da91feb0d48fc20ef..a37878f9c8ab2fd3ea1d02d3d242bc52d3ee5c2c 100644 (file)
@@ -29,7 +29,7 @@ class SPNamedView;
 class SnapManager
 {
 public:
-    SnapManager(SPNamedViewv);
+    SnapManager(SPNamedView const *v);
     
     bool willSnapSomething() const;
 
@@ -43,12 +43,12 @@ public:
     
     Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t,
                                            NR::Point const &p,
-                                           NR::Point const &c,
+                                           Inkscape::Snapper::ConstraintLine const &c,
                                            SPItem const *it) const;
     
     Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t,
                                            NR::Point const &p,
-                                           NR::Point const &c,
+                                           Inkscape::Snapper::ConstraintLine const &c,
                                            std::list<SPItem const *> const &it) const;
 
     std::pair<NR::Point, bool> freeSnapTranslation(Inkscape::Snapper::PointType t,
@@ -58,16 +58,46 @@ public:
 
     std::pair<NR::Point, bool> constrainedSnapTranslation(Inkscape::Snapper::PointType t,
                                                           std::vector<NR::Point> const &p,
-                                                          NR::Point const &c,
                                                           std::list<SPItem const *> const &it,
+                                                          Inkscape::Snapper::ConstraintLine const &c,
                                                           NR::Point const &tr) const;
 
+    std::pair<NR::scale, bool> freeSnapScale(Inkscape::Snapper::PointType t,
+                                             std::vector<NR::Point> const &p,
+                                             std::list<SPItem const *> const &it,
+                                             NR::scale const &s,
+                                             NR::Point const &o) const;
+
+    std::pair<NR::scale, bool> constrainedSnapScale(Inkscape::Snapper::PointType t,
+                                                    std::vector<NR::Point> const &p,
+                                                    std::list<SPItem const *> const &it,
+                                                    Inkscape::Snapper::ConstraintLine const &c,
+                                                    NR::scale const &s,
+                                                    NR::Point const &o) const;
+
     Inkscape::GridSnapper grid;
     Inkscape::GuideSnapper guide;
     Inkscape::ObjectSnapper object;
 
     typedef std::list<const Inkscape::Snapper*> SnapperList;
     SnapperList getSnappers() const;
+
+private:
+
+    enum Transformation
+    {
+        TRANSLATION,
+        SCALE
+    };
+
+    std::pair<NR::Point, bool> _snapTransformed(Inkscape::Snapper::PointType type,
+                                                std::vector<NR::Point> const &points,
+                                                std::list<SPItem const *> const &ignore,
+                                                bool constrained,
+                                                Inkscape::Snapper::ConstraintLine const &constraint,
+                                                Transformation transformation_type,
+                                                NR::Point const &transformation,
+                                                NR::Point const &origin) const;
 };
 
 
@@ -89,6 +119,7 @@ std::pair<double, bool> namedview_vector_snap_list(SPNamedView const *nv,
                                                    std::list<SPItem const *> const &it
                                                    );
 
+
 std::pair<double, bool> namedview_dim_snap_list_scale(SPNamedView const *nv,
                                                       Inkscape::Snapper::PointType t, const std::vector<NR::Point> &p,
                                                       NR::Point const &norm, double const sx,
index fd05809c13af5d54c10525e7a7ed96e48f1dd9b8..963cf7c9d3ad16c56f2123da1ff2f1fb097f0b23 100644 (file)
@@ -136,7 +136,7 @@ Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType t,
 
 Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType t,
                                                           NR::Point const &p,
-                                                          NR::Point const &c,
+                                                          ConstraintLine const &c,
                                                           SPItem const *it) const
 {
     std::list<SPItem const *> lit;
@@ -158,7 +158,7 @@ Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType t,
 
 Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType t,
                                                           NR::Point const &p,
-                                                          NR::Point const &c,
+                                                          ConstraintLine const &c,
                                                           std::list<SPItem const *> const &it) const
 {
     if (getSnapTo(t) == false) {
index 2f3c487d6b9bd672f4c987d154f07d6a201408f3..33a15bd04887d500e4a16c0dea0eb4bb30850a8f 100644 (file)
@@ -54,14 +54,39 @@ public:
                           NR::Point const &p,
                           std::list<SPItem const *> const &it) const;
 
+    class ConstraintLine
+    {
+    public:
+        ConstraintLine(NR::Point const &d) : _has_point(false), _direction(d) {}
+        ConstraintLine(NR::Point const &p, NR::Point const &d) : _has_point(true), _point(p), _direction(d) {}
+
+        bool hasPoint() const {
+            return _has_point;
+        }
+
+        NR::Point getPoint() const {
+            return _point;
+        }
+
+        NR::Point getDirection() const {
+            return _direction;
+        }
+        
+    private:
+
+        bool _has_point;
+        NR::Point _point;
+        NR::Point _direction;
+    };
+
     SnappedPoint constrainedSnap(PointType t,
                                  NR::Point const &p,
-                                 NR::Point const &c,
+                                 ConstraintLine const &c,
                                  SPItem const *it) const;
 
     SnappedPoint constrainedSnap(PointType t,
                                  NR::Point const &p,
-                                 NR::Point const &c,
+                                 ConstraintLine const &c,
                                  std::list<SPItem const *> const &it) const;
 protected:
     SPNamedView const *_named_view;
@@ -91,7 +116,7 @@ private:
      *  \return Snapped point.
      */    
     virtual SnappedPoint _doConstrainedSnap(NR::Point const &p,
-                                            NR::Point const &c,
+                                            ConstraintLine const &c,
                                             std::list<SPItem const *> const &it) const = 0;
     
     ::NR::Coord _distance; ///< snap distance (desktop coordinates)