Code

Fix snapping to midpoints of closing segments
authorDiederik van Lierop <mailat-signdiedenrezidotnl>
Mon, 19 Jul 2010 07:14:43 +0000 (09:14 +0200)
committerDiederik van Lierop <mailat-signdiedenrezidotnl>
Mon, 19 Jul 2010 07:14:43 +0000 (09:14 +0200)
src/object-snapper.cpp
src/sp-shape.cpp

index 57d5b0fc5cbfb3487265a79442bd30842edb4024..7d593dfc47f55e5e973d8e3cab466df74c7d2f72 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "svg/svg.h"
 #include <2geom/path-intersection.h>
+#include <2geom/pathvector.h>
 #include <2geom/point.h>
 #include <2geom/rect.h>
 #include <2geom/line.h>
@@ -386,9 +387,14 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapCandidatePoint const &
                     if (!very_lenghty_prose && !very_complex_path) {
                         SPCurve *curve = curve_for_item(root_item);
                         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(Inkscape::SnapCandidatePath(borderpathv, SNAPTARGET_PATH, Geom::OptRect())); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
+                            // We will get our own copy of the pathvector, which must be freed at some point
+
+                               // Geom::PathVector *pv = pathvector_for_curve(root_item, curve, true, true, Geom::identity(), (*i).additional_affine);
+
+                               Geom::PathVector *pv = new Geom::PathVector(curve->get_pathvector());
+                               (*pv) *= sp_item_i2d_affine(root_item) * (*i).additional_affine * _snapmanager->getDesktop()->doc2dt(); // (_edit_transform * _i2d_transform);
+
+                            _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(pv, SNAPTARGET_PATH, Geom::OptRect())); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
                             curve->unref();
                         }
                     }
index 3064341b66238b48b2842c7514771033183f0eb3..0038908bfd19f6bc869d0aad951a176c9f69761f 100644 (file)
@@ -1208,51 +1208,57 @@ static void sp_shape_snappoints(SPItem const *item, std::vector<Inkscape::SnapCa
 
     for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
         if (snapprefs->getSnapToItemNode()) {
-            p.push_back(Inkscape::SnapCandidatePoint(path_it->initialPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
+               // Add the first point of the path
+               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
         Geom::Path::const_iterator curve_it2 = ++(path_it->begin());  // outgoing curve
-        while (curve_it2 != path_it->end_closed())
+        while (curve_it1 != path_it->end_default())
         {
-            /* Test whether to add the node between curve_it1 and curve_it2.
-             * Loop to end_closed (so always including closing segment); the last node to be added
-             * is the node between the closing segment and the segment before that, regardless
-             * of the path being closed or not. If the path is closed, the final point was already added by
-             * adding the initial point. */
-
-            Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
-
-            bool c1 = snapprefs->getSnapToItemNode() && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
-            bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
-
-            if (c1 || c2) {
-                Inkscape::SnapSourceType sst;
-                Inkscape::SnapTargetType stt;
-                switch (nodetype) {
-                case Geom::NODE_CUSP:
-                    sst = Inkscape::SNAPSOURCE_NODE_CUSP;
-                    stt = Inkscape::SNAPTARGET_NODE_CUSP;
-                    break;
-                case Geom::NODE_SMOOTH:
-                case Geom::NODE_SYMM:
-                    sst = Inkscape::SNAPSOURCE_NODE_SMOOTH;
-                    stt = Inkscape::SNAPTARGET_NODE_SMOOTH;
-                    break;
-                default:
-                    sst = Inkscape::SNAPSOURCE_UNDEFINED;
-                    stt = Inkscape::SNAPTARGET_UNDEFINED;
-                    break;
-                }
-                p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2d, sst, stt));
-            }
-
-            // 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));
-                }
-            }
+               // For each path: consider midpoints of line segments for snapping
+                       if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforces 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));
+                               }
+                       }
+
+                       if (curve_it2 == path_it->end_default()) { // Test will only pass for the last iteration of the while loop
+                               if (snapprefs->getSnapToItemNode() && !path_it->closed()) {
+                                       // Add the last point of the path, but only for open paths
+                                       // (for closed paths the first and last point will coincide)
+                                       p.push_back(Inkscape::SnapCandidatePoint((*curve_it1).finalPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
+                               }
+                       } else {
+                               /* Test whether to add the node between curve_it1 and curve_it2.
+                                * Loop to end_default (so only iterating through the stroked part); */
+
+                               Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
+
+                               bool c1 = snapprefs->getSnapToItemNode() && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
+                               bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
+
+                               if (c1 || c2) {
+                                       Inkscape::SnapSourceType sst;
+                                       Inkscape::SnapTargetType stt;
+                                       switch (nodetype) {
+                                       case Geom::NODE_CUSP:
+                                               sst = Inkscape::SNAPSOURCE_NODE_CUSP;
+                                               stt = Inkscape::SNAPTARGET_NODE_CUSP;
+                                               break;
+                                       case Geom::NODE_SMOOTH:
+                                       case Geom::NODE_SYMM:
+                                               sst = Inkscape::SNAPSOURCE_NODE_SMOOTH;
+                                               stt = Inkscape::SNAPTARGET_NODE_SMOOTH;
+                                               break;
+                                       default:
+                                               sst = Inkscape::SNAPSOURCE_UNDEFINED;
+                                               stt = Inkscape::SNAPTARGET_UNDEFINED;
+                                               break;
+                                       }
+                                       p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2d, sst, stt));
+                               }
+                       }
 
             ++curve_it1;
             ++curve_it2;