Code

The snap indicator's tooltip now displays "A to B", whereas before it only displayed...
authordvlierop2 <dvlierop2@users.sourceforge.net>
Fri, 20 Feb 2009 21:49:07 +0000 (21:49 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Fri, 20 Feb 2009 21:49:07 +0000 (21:49 +0000)
56 files changed:
src/arc-context.cpp
src/box3d-context.cpp
src/connector-context.cpp
src/context-fns.cpp
src/display/canvas-axonomgrid.cpp
src/display/canvas-axonomgrid.h
src/display/canvas-grid.cpp
src/display/canvas-grid.h
src/display/snap-indicator.cpp
src/display/snap-indicator.h
src/draw-context.cpp
src/gradient-context.cpp
src/gradient-drag.cpp
src/guide-snapper.cpp
src/guide-snapper.h
src/knot-holder-entity.cpp
src/line-snapper.cpp
src/line-snapper.h
src/nodepath.cpp
src/object-snapper.cpp
src/object-snapper.h
src/pen-context.cpp
src/pencil-context.cpp
src/rect-context.cpp
src/satisfied-guide-cns.cpp
src/satisfied-guide-cns.h
src/selection.cpp
src/selection.h
src/seltrans.cpp
src/seltrans.h
src/snap.cpp
src/snap.h
src/snapped-curve.cpp
src/snapped-curve.h
src/snapped-line.cpp
src/snapped-line.h
src/snapped-point.cpp
src/snapped-point.h
src/snapper.h
src/sp-ellipse.cpp
src/sp-image.cpp
src/sp-item-group.cpp
src/sp-item-notify-moveto.cpp
src/sp-item-rm-unsatisfied-cns.cpp
src/sp-item-update-cns.cpp
src/sp-item.cpp
src/sp-item.h
src/sp-offset.cpp
src/sp-rect.cpp
src/sp-shape.cpp
src/sp-spiral.cpp
src/sp-star.cpp
src/sp-text.cpp
src/sp-use.cpp
src/spiral-context.cpp
src/star-context.cpp

index da236ae8730672f7b1278afed563edd3a4538b39..115b5534c16137279b291f87c39aaae24e450262 100644 (file)
@@ -228,7 +228,7 @@ static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent
                 SnapManager &m = desktop->namedview->snap_manager;
                 m.setup(desktop);
                 Geom::Point pt2g = to_2geom(ac->center);
-                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
                 ac->center = from_2geom(pt2g);
 
                 sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
index 2b76233f5c5cdf3d88a1eb62ec01bfef760081d4..e8cee44b05f1ab4b90da783c64c8b913ae36e964 100644 (file)
@@ -294,7 +294,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
             /* Snap center */
             SnapManager &m = desktop->namedview->snap_manager;
             m.setup(desktop, true, bc->item);
-            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
             bc->center = from_2geom(button_dt);
 
             sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -326,7 +326,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
 
             SnapManager &m = desktop->namedview->snap_manager;
             m.setup(desktop, true, bc->item);
-            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt);
+            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt, Inkscape::SNAPSOURCE_HANDLE);
 
             bc->ctrl_dragged  = event->motion.state & GDK_CONTROL_MASK;
 
@@ -360,7 +360,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
                     bc->drag_ptC_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X);
                 }
                 Geom::Point pt2g = to_2geom(bc->drag_ptC);
-                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
                 bc->drag_ptC = from_2geom(pt2g);
             }
 
index 6fa709b18915437322ef9827a8daacbb0e2786d9..a3bb19de6d6131c397c66669f171f2ca53fb69bb 100644 (file)
@@ -537,7 +537,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
                         // as there's no other points to go off.
                         SnapManager &m = cc->desktop->namedview->snap_manager;
                         m.setup(cc->desktop);
-                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
                     }
                     spcc_connector_set_initial_point(cc, from_2geom(pt2g));
 
index 54b07a02a76f05287b7a8b2fce27a78b85902344..30062504cfd03d81f91f01b4bd7e2d74026eca51 100644 (file)
@@ -132,11 +132,11 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
             Inkscape::SnappedPoint s[2];
 
             /* Try to snap p[0] (the opposite corner) along the constraint vector */
-            s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]),
+            s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE,
                                      Inkscape::Snapper::ConstraintLine(p[0] - p[1]));
 
             /* Try to snap p[1] (the dragged corner) along the constraint vector */
-            s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]),
+            s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
                                      Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
 
             /* Choose the best snap and update points accordingly */
@@ -157,7 +157,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
 
             /* Our origin is the opposite corner.  Snap the drag point along the constraint vector */
             p[0] = center;
-            snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]),
+            snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
                                           Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
             if (snappoint.getSnapped()) {
                 p[1] = snappoint.getPoint();
@@ -175,8 +175,8 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
 
         Inkscape::SnappedPoint s[2];
 
-        s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]));
-        s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]));
+        s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE);
+        s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE);
 
         if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
             if (s[0].getSnapped()) {
@@ -197,7 +197,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
         /* There's no constraint on the corner point, so just snap it to anything */
         p[0] = center;
         p[1] = pt;
-        snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(pt));
+        snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(pt), Inkscape::SNAPSOURCE_HANDLE);
         if (snappoint.getSnapped()) {
             p[1] = snappoint.getPoint();
         }
@@ -209,7 +209,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
 
     p[0] = sp_desktop_dt2doc_xy_point(desktop, p[0]);
     p[1] = sp_desktop_dt2doc_xy_point(desktop, p[1]);
-    
+
     return Geom::Rect(Geom::Point(MIN(p[0][Geom::X], p[1][Geom::X]), MIN(p[0][Geom::Y], p[1][Geom::Y])),
                     Geom::Point(MAX(p[0][Geom::X], p[1][Geom::X]), MAX(p[0][Geom::Y], p[1][Geom::Y])));
 }
index 076dcdd332613e346f8f2c002ce7b090c33f8f6f..ea5393d393f3b090229e5b20a07332b928120f25 100644 (file)
@@ -757,9 +757,9 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const
     return s;
 }
 
-void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
 {
-    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
     sc.grid_lines.push_back(dummy);
 }
 
index 4849f08ad50d025cda018d1840a42134d0f6aec7..ecbd846a18e58549bea477ef4e165d9b8a7015fc 100644 (file)
@@ -78,7 +78,7 @@ public:
 
 private:
     LineList _getSnapLines(Geom::Point const &p) const;
-    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
+    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
 
     CanvasAxonomGrid *grid;
 };
index 49a1211eb9eb45f266489a4847483b48f5b8a72a..3e7295b90aea83cf2ac2b7656ead1d0495e667ca 100644 (file)
@@ -1003,9 +1003,9 @@ CanvasXYGridSnapper::_getSnapLines(Geom::Point const &p) const
     return s;
 }
 
-void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance,  SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
 {
-    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
     sc.grid_lines.push_back(dummy);
 }
 
index 85e890feff84d5bc93d760967c011b2b13bc668a..37e30fab0fcfcaff83cebbae166aa2015c535f27 100644 (file)
@@ -166,7 +166,7 @@ public:
 
 private:
     LineList _getSnapLines(Geom::Point const &p) const;
-    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
+    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance,  SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
     CanvasXYGrid *grid;
 };
 
index 1785da7b91896d9a1ab60de6c874fb63c3852fe2..e55c8faac2d88dca24e15c3c08da99ca52e3ff0f 100644 (file)
@@ -75,8 +75,11 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p)
             case SNAPTARGET_GRID_GUIDE_INTERSECTION:
                target_name = _("grid-guide intersection");
                break;
-            case SNAPTARGET_NODE:
-                               target_name = _("node");
+            case SNAPTARGET_NODE_CUSP:
+                               target_name = _("cusp node");
+                               break;
+            case SNAPTARGET_NODE_SMOOTH:
+                               target_name = _("smooth node");
                                break;
                        case SNAPTARGET_PATH:
                target_name = _("path");
@@ -96,15 +99,91 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p)
             case SNAPTARGET_PAGE_BORDER:
                target_name = _("page border");
                                break;
+            case SNAPTARGET_LINE_MIDPOINT:
+               target_name = _("line midpoint");
+               break;
+            case SNAPTARGET_OBJECT_MIDPOINT:
+               target_name = _("object midpoint");
+               break;
+            case SNAPTARGET_ROTATION_CENTER:
+               target_name = _("object rotation center");
+               break;
+            case SNAPTARGET_HANDLE:
+               target_name = _("handle");
+               break;
+            case SNAPTARGET_BBOX_EDGE_MIDPOINT:
+               target_name = _("bounding box side midpoint");
+               break;
+            case SNAPTARGET_BBOX_MIDPOINT:
+               target_name = _("bounding box midpoint");
+               break;
+            case SNAPTARGET_PAGE_CORNER:
+               target_name = _("page corner");
+               break;
+            case SNAPTARGET_CONVEX_HULL_CORNER:
+               target_name = _("convex hull corner");
+               break;
+            case SNAPTARGET_ELLIPSE_QUADRANT_POINT:
+               target_name = _("quadrant point");
+               break;
             default:
                g_warning("Snap target has not yet been defined!");
                 break;
         }
-        // std::cout << "Snapped to: " << target_name << std::endl;
+
+        gchar *source_name = _("UNDEFINED");
+               switch (p.getSource()) {
+                       case SNAPSOURCE_UNDEFINED:
+                               source_name = _("UNDEFINED");
+                               break;
+                       case SNAPSOURCE_BBOX_CORNER:
+                               source_name = _("Bounding box corner");
+                               break;
+                       case SNAPSOURCE_BBOX_MIDPOINT:
+                               source_name = _("Bounding box midpoint");
+                               break;
+                       case SNAPSOURCE_BBOX_EDGE_MIDPOINT:
+                               source_name = _("Bounding box side midpoint");
+                               break;
+                       case SNAPSOURCE_NODE_SMOOTH:
+                               source_name = _("Smooth node");
+                               break;
+                       case SNAPSOURCE_NODE_CUSP:
+                               source_name = _("Cusp node");
+                               break;
+                       case SNAPSOURCE_LINE_MIDPOINT:
+                               source_name = _("Line midpoint");
+                               break;
+                       case SNAPSOURCE_OBJECT_MIDPOINT:
+                               source_name = _("Object midpoint");
+                               break;
+                       case SNAPSOURCE_ROTATION_CENTER:
+                               source_name = _("Object rotation center");
+                               break;
+                       case SNAPSOURCE_HANDLE:
+                               source_name = _("Handle");
+                               break;
+                       case SNAPSOURCE_PATH_INTERSECTION:
+                               source_name = _("Path intersection");
+                               break;
+                       case SNAPSOURCE_GUIDE:
+                               source_name = _("Guide");
+                               break;
+                       case SNAPSOURCE_CONVEX_HULL_CORNER:
+                               source_name = _("Convex hull corner");
+                               break;
+                       case SNAPSOURCE_ELLIPSE_QUADRANT_POINT:
+                               source_name = _("Quadrant point");
+                               break;
+                       default:
+                               g_warning("Snap source has not yet been defined!");
+                               break;
+               }
+        //std::cout << "Snapped " << source_name << " to " << target_name << std::endl;
 
         // Display the snap indicator (i.e. the cross)
         SPCanvasItem * canvasitem = NULL;
-               if (p.getTarget() == SNAPTARGET_NODE) {
+               if (p.getTarget() == SNAPTARGET_NODE_SMOOTH || p.getTarget() == SNAPTARGET_NODE_CUSP) {
                        canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop),
                                                                                        SP_TYPE_CTRL,
                                                                                        "anchor", GTK_ANCHOR_CENTER,
@@ -136,7 +215,8 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p)
                GtkSettings *settings = gtk_widget_get_settings (&(_desktop->canvas->widget));
                // If we set the timeout too short, then the tooltip might not show at all (most noticeable when a long snap delay is active)
                g_object_set(settings, "gtk-tooltip-timeout", 200, NULL); // tooltip will be shown after x msec.
-        gtk_widget_set_tooltip_text(&(_desktop->canvas->widget), target_name);
+        gchar *tooltip_text = g_strconcat(source_name, _(" to "), target_name, NULL);
+               gtk_widget_set_tooltip_text(&(_desktop->canvas->widget), tooltip_text);
         // has_tooltip will be true by now because gtk_widget_set_has_tooltip() has been called implicitly
         update_tooltip();
         // The snap indicator will be removed automatically because it's a temporary canvas item; the tooltip
@@ -157,7 +237,7 @@ SnapIndicator::remove_snaptarget()
 }
 
 void
-SnapIndicator::set_new_snapsource(Geom::Point const p)
+SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p)
 {
        remove_snapsource();
 
@@ -177,7 +257,7 @@ SnapIndicator::set_new_snapsource(Geom::Point const p)
                                                         "shape", SP_KNOT_SHAPE_CIRCLE,
                                                         NULL );
 
-        SP_CTRL(canvasitem)->moveto(p);
+        SP_CTRL(canvasitem)->moveto(p.first);
         _snapsource = _desktop->add_temporary_canvasitem(canvasitem, 1000);
     }
 }
index 672d2e78c6f2331309ae46511901a666efd7eb58..ae0963b4f93ad0ac5d5e6a4c681d686768abeca5 100644 (file)
@@ -29,7 +29,7 @@ public:
     void set_new_snaptarget(Inkscape::SnappedPoint const p);
     void remove_snaptarget();
 
-    void set_new_snapsource(Geom::Point const p);
+    void set_new_snapsource(std::pair<Geom::Point, int> const p);
     void remove_snapsource();
 
 protected:
index a8d6187f6917908e747b7e87f28afa75cdfc361f..b860c457d32a97838fe56e6b3ece410bc6bd4a59 100644 (file)
@@ -513,7 +513,7 @@ void spdc_endpoint_snap_rotation(SPEventContext const *const ec, Geom::Point &p,
             SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
             m.setup(SP_EVENT_CONTEXT_DESKTOP(ec));
             Geom::Point pt2g = to_2geom(p);
-            m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::Snapper::ConstraintLine(best));
+            m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE, Inkscape::Snapper::ConstraintLine(best));
             p = from_2geom(pt2g);
         }
     }
@@ -525,7 +525,7 @@ void spdc_endpoint_snap_free(SPEventContext const * const ec, Geom::Point& p, gu
     SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
     m.setup(SP_EVENT_CONTEXT_DESKTOP(ec));
     Geom::Point pt2g = to_2geom(p);
-    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
     p = from_2geom(pt2g);
 }
 
index e9b46a2c29df5e3275d09c8a3d0af12665c68f79..16df41f7a82f6aa418ea38e8879214b59000defd 100644 (file)
@@ -560,7 +560,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 /* Snap center to nearest magnetic point */
                 SnapManager &m = desktop->namedview->snap_manager;
                 m.setup(desktop);
-                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
                 rc->origin = from_2geom(button_dt);
             }
 
index a24f45c849c5b90bf444a39d96bc2c9b6ef2c7f1..76bed32cf5c1e3a953489a030e2f68e9958ad347 100644 (file)
@@ -598,7 +598,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
         SPDesktop *desktop = dragger->parent->desktop;
         SnapManager &m = desktop->namedview->snap_manager;
         m.setup(desktop);
-        Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p));
+        Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p), Inkscape::SNAPSOURCE_HANDLE);
         if (s.getSnapped()) {
             p = s.getPoint();
             sp_knot_moveto (knot, p);
@@ -610,7 +610,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
                 dist = fabs(p[Geom::Y] - dragger->parent->hor_levels[i]);
                 if (dist < snap_dist) {
                     p[Geom::Y] = dragger->parent->hor_levels[i];
-                    s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
+                    s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
                     was_snapped = true;
                     sp_knot_moveto (knot, p);
                 }
@@ -619,7 +619,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
                 dist = fabs(p[Geom::X] - dragger->parent->vert_levels[i]);
                 if (dist < snap_dist) {
                     p[Geom::X] = dragger->parent->vert_levels[i];
-                    s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
+                    s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
                     was_snapped = true;
                     sp_knot_moveto (knot, p);
                 }
index f344d891ff800d0f33fee390c20bf0e3d7f5bb1c..6df066cbbf3d2ad7f65f9fd0b615a8f1f56c5665 100644 (file)
@@ -66,9 +66,9 @@ bool Inkscape::GuideSnapper::ThisSnapperMightSnap() const
        return (_snap_enabled && _snapmanager->snapprefs.getSnapToGuides() && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && _snapmanager->getNamedView()->showguides);
 }
 
-void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
 {
-    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
     sc.guide_lines.push_back(dummy);
 }
 
index dd55816541a3c773da49ff0b5a8f2eb6a59323a0..8b59194e8f2db39d9aea393ca9e93bf6a1a2611d 100644 (file)
@@ -36,7 +36,7 @@ public:
 
 private:
     LineList _getSnapLines(Geom::Point const &p) const;
-    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const;
+    void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance,  SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const;
 };
 
 }
index 36a072c444b92d2767c611b5845dcd3ce1d05057..df58d356a1f20cbce3a9ba4064e02a39d5e6426d 100644 (file)
@@ -1,8 +1,8 @@
 #define __KNOT_HOLDER_ENTITY_C__
 
-/** \file 
- * KnotHolderEntity definition. 
- * 
+/** \file
+ * KnotHolderEntity definition.
+ *
  * Authors:
  *   Mitsuru Oka <oka326@parkcity.ne.jp>
  *   Maximilian Albert <maximilian.albert@gmail.com>
@@ -82,7 +82,7 @@ KnotHolderEntity::update_knot()
     Geom::Point dp(knot_get() * i2d);
 
     _moved_connection.block();
-    sp_knot_set_position(knot, dp, SP_KNOT_STATE_NORMAL); 
+    sp_knot_set_position(knot, dp, SP_KNOT_STATE_NORMAL);
     _moved_connection.unblock();
 }
 
@@ -93,7 +93,7 @@ KnotHolderEntity::snap_knot_position(Geom::Point const &p)
     Geom::Point s = p * i2d;
     SnapManager &m = desktop->namedview->snap_manager;
     m.setup(desktop, true, item);
-    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, s);
+    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, s, Inkscape::SNAPSOURCE_HANDLE);
     return s * i2d.inverse();
 }
 
index bc43d640b0d9c6a327c26fe2e8a2609b2b1f69eb..d751993dda940d8c9d84a4b560d36495470f1277 100644 (file)
@@ -26,10 +26,11 @@ Inkscape::LineSnapper::LineSnapper(SnapManager *sm, Geom::Coord const d) : Snapp
 void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
                                                     Inkscape::SnapPreferences::PointType const &t,
                                                     Geom::Point const &p,
+                                                    SnapSourceType const &source_type,
                                                     bool const &/*f*/,
                                                     Geom::OptRect const &/*bbox_to_snap*/,
                                                     std::vector<SPItem const *> const */*it*/,
-                                                    std::vector<Geom::Point> */*unselected_nodes*/) const
+                                                    std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const
 {
        if (!(_snap_enabled && _snapmanager->snapprefs.getSnapFrom(t)) ) {
         return;
@@ -50,7 +51,8 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
         Geom::Coord const dist = Geom::L2(p_proj - p);
         //Store any line that's within snapping range
         if (dist < getSnapperTolerance()) {
-            _addSnappedLine(sc, p_proj, dist, i->first, i->second);
+            _addSnappedLine(sc, p_proj, dist, source_type, Inkscape::SNAPTARGET_UNDEFINED, i->first, i->second);
+            // We don't know if we're snapping to grids or guides here; therefore the snap target type will be set in findBestSnap()
             // std::cout << " -> distance = " << dist;
         }
         // std::cout << std::endl;
@@ -60,6 +62,7 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
 void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
                                                Inkscape::SnapPreferences::PointType const &t,
                                                Geom::Point const &p,
+                                               SnapSourceType const &source_type,
                                                bool const &/*f*/,
                                                Geom::OptRect const &/*bbox_to_snap*/,
                                                ConstraintLine const &c,
@@ -97,9 +100,7 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
                     // This snappoint is therefore fully constrained, so there's no need
                     // to look for additional intersections; just return the snapped point
                     // and forget about the line
-                    sc.points.push_back(SnappedPoint(t, Inkscape::SNAPTARGET_UNDEFINED, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true));
-                    // The type of the snap target is yet undefined, as we cannot tell whether
-                    // we're snapping to grid or the guide lines; must be set by on a higher level
+                    sc.points.push_back(SnappedPoint(t, source_type, Inkscape::SNAPTARGET_UNDEFINED, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true));
                 }
             }
         }
index 91e8ca596d8e2d2188d0b36c795c603eb19fad0b..3a7ed6aae23b59331858b494b950e51bfc4531d9 100644 (file)
@@ -27,14 +27,16 @@ public:
   void freeSnap(SnappedConstraints &sc,
                    Inkscape::SnapPreferences::PointType const &t,
                    Geom::Point const &p,
+                   SnapSourceType const &source_type,
                    bool const &first_point,
                    Geom::OptRect const &bbox_to_snap,
                    std::vector<SPItem const *> const *it,
-                   std::vector<Geom::Point> *unselected_nodes) const;
+                   std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
 
   void constrainedSnap(SnappedConstraints &sc,
                           Inkscape::SnapPreferences::PointType const &t,
                           Geom::Point const &p,
+                          SnapSourceType const &source_type,
                           bool const &first_point,
                           Geom::OptRect const &bbox_to_snap,
                           ConstraintLine const &c,
@@ -52,7 +54,7 @@ private:
    */
   virtual LineList _getSnapLines(Geom::Point const &p) const = 0;
 
-  virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0;
+  virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0;
 };
 
 }
index cc38acbe5183210d5bb599b2a182625523b6ddcc..845d47b3b23d781166dbeab68ac56bd36ca94d67 100644 (file)
@@ -1350,13 +1350,13 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
          * must provide that information. */
 
         // Build a list of the unselected nodes to which the snapper should snap
-        std::vector<Geom::Point> unselected_nodes;
+       std::vector<std::pair<Geom::Point, int> > unselected_nodes;
         for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
             Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
             for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
                 Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
                 if (!node->selected) {
-                    unselected_nodes.push_back(to_2geom(node->pos));
+                    unselected_nodes.push_back(std::make_pair(to_2geom(node->pos), node->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPTARGET_NODE_SMOOTH : Inkscape::SNAPTARGET_NODE_CUSP));
                 }
             }
         }
@@ -1388,12 +1388,13 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
             Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
             if (!closest_only || n == closest_node) { //try to snap either all selected nodes or only the closest one
                    Inkscape::SnappedPoint s;
+                   Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
                    if (constrained) {
                        Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
                        dedicated_constraint.setPoint(n->pos);
-                       s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), dedicated_constraint);
+                       s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type, dedicated_constraint);
                    } else {
-                       s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta));
+                       s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type);
                    }
 
                    if (s.getSnapped()) {
@@ -3945,6 +3946,7 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
     }
 
     Inkscape::NodePath::Node *othernode = opposite->other;
+    Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
     if (othernode) {
         if ((n->type != Inkscape::NodePath::NODE_CUSP) && sp_node_side_is_line(n, opposite)) {
             /* We are smooth node adjacent with line */
@@ -3958,16 +3960,16 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
                 p = n->pos + (scal / linelen) * ndelta;
             }
             if ((state & GDK_SHIFT_MASK) == 0) {
-                s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::Snapper::ConstraintLine(p, ndelta));
+                s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type, Inkscape::Snapper::ConstraintLine(p, ndelta));
             }
         } else {
             if ((state & GDK_SHIFT_MASK) == 0) {
-                s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+                s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
             }
         }
     } else {
         if ((state & GDK_SHIFT_MASK) == 0) {
-            s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+            s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
         }
     }
 
index 515008964e2864432beda0c36ceb10edce3f9ea1..e2ca05408700299b1520009acb32d864bc7aa009 100644 (file)
@@ -47,7 +47,7 @@ Inkscape::ObjectSnapper::ObjectSnapper(SnapManager *sm, Geom::Coord const d)
     : Snapper(sm, d)
 {
     _candidates = new std::vector<SnapCandidate>;
-    _points_to_snap_to = new std::vector<Geom::Point>;
+    _points_to_snap_to = new std::vector<std::pair<Geom::Point, int> >;
     _paths_to_snap_to = new std::vector<std::pair<Geom::PathVector*, SnapTargetType> >;
 }
 
@@ -196,7 +196,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
                 SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
         }
 
-        // Consider the page border for snapping
+        // Consider the page border for snapping to
         if (_snapmanager->snapprefs.getSnapToPageBorder()) {
             _getBorderNodes(_points_to_snap_to);
         }
@@ -235,7 +235,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
                                        _snapmanager->snapprefs.setSnapIntersectionCS(false);
                                }
 
-                               sp_item_snappoints(root_item, SnapPointsIter(*_points_to_snap_to), &_snapmanager->snapprefs);
+                               sp_item_snappoints(root_item, true, *_points_to_snap_to, &_snapmanager->snapprefs);
 
                                if (_snapmanager->snapprefs.getSnapToItemPath()) {
                                        _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
@@ -248,7 +248,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
                                // of the item AND the bbox of the clipping path at the same time
                                if (!(*i).clip_or_mask) {
                                        Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type);
-                                       getBBoxPoints(b, _points_to_snap_to, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints());
+                                       getBBoxPoints(b, _points_to_snap_to, true, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints());
                                }
                        }
         }
@@ -258,8 +258,9 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
 void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
                                          Inkscape::SnapPreferences::PointType const &t,
                                          Geom::Point const &p,
+                                         SnapSourceType const &source_type,
                                          bool const &first_point,
-                                         std::vector<Geom::Point> *unselected_nodes) const
+                                         std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
 {
     // Iterate through all nodes, find out which one is the closest to p, and snap to it!
 
@@ -272,10 +273,10 @@ void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
     SnappedPoint s;
     bool success = false;
 
-    for (std::vector<Geom::Point>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
-        Geom::Coord dist = Geom::L2(*k - p);
+    for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+        Geom::Coord dist = Geom::L2((*k).first - p);
         if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) {
-            s = SnappedPoint(*k, SNAPTARGET_NODE, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).first, source_type, static_cast<Inkscape::SnapTargetType>((*k).second), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
             success = true;
         }
     }
@@ -298,13 +299,13 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s
 
     Geom::Coord tol = getSnapperTolerance();
 
-    for (std::vector<Geom::Point>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+    for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
         // Project each node (*k) on the guide line (running through point p)
-        Geom::Point p_proj = project_on_linesegment(*k, p, p + Geom::rot90(guide_normal));
-        Geom::Coord dist = Geom::L2(*k - p_proj); // distance from node to the guide
+        Geom::Point p_proj = project_on_linesegment((*k).first, p, p + Geom::rot90(guide_normal));
+        Geom::Coord dist = Geom::L2((*k).first - p_proj); // distance from node to the guide
         Geom::Coord dist2 = Geom::L2(p - p_proj); // distance from projection of node on the guide, to the mouse location
         if ((dist < tol && dist2 < tol) || (getSnapperAlwaysSnap() && dist < s.getSnapDistance())) {
-            s = SnappedPoint(*k, SNAPTARGET_NODE, dist, tol, getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).first, SNAPSOURCE_GUIDE, static_cast<Inkscape::SnapTargetType>((*k).second), dist, tol, getSnapperAlwaysSnap(), true);
             success = true;
         }
     }
@@ -344,7 +345,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
         if (_snapmanager->snapprefs.getSnapToPageBorder()) {
             Geom::PathVector *border_path = _getBorderPathv();
             if (border_path != NULL) {
-                _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(border_path, SNAPTARGET_PAGE_BORDER));
+                _paths_to_snap_to->push_back(std::make_pair(border_path, SNAPTARGET_PAGE_BORDER));
             }
         }
 
@@ -392,7 +393,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
                         if (curve) {
                             // We will get our own copy of the path, which must be freed at some point
                             Geom::PathVector *borderpathv = pathvector_for_curve(root_item, curve, true, true, Geom::identity(), (*i).additional_affine);
-                            _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
+                            _paths_to_snap_to->push_back(std::make_pair(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
                             curve->unref();
                         }
                     }
@@ -409,7 +410,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
                         sp_item_invoke_bbox(root_item, rect, i2doc, TRUE, bbox_type);
                         if (rect) {
                             Geom::PathVector *path = _getPathvFromRect(*rect);
-                            _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(path, SNAPTARGET_BBOX_EDGE));
+                            _paths_to_snap_to->push_back(std::make_pair(path, SNAPTARGET_BBOX_EDGE));
                         }
                     }
                 }
@@ -421,8 +422,9 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
 void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
                                      Inkscape::SnapPreferences::PointType const &t,
                                      Geom::Point const &p,
+                                     SnapSourceType const &source_type,
                                      bool const &first_point,
-                                     std::vector<Geom::Point> *unselected_nodes,
+                                     std::vector<std::pair<Geom::Point, int> > *unselected_nodes,
                                      SPPath const *selected_path) const
 {
     _collectPaths(t, first_point);
@@ -446,7 +448,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
             SPCurve *curve = curve_for_item(SP_ITEM(selected_path));
             if (curve) {
                 Geom::PathVector *pathv = pathvector_for_curve(SP_ITEM(selected_path), curve, true, true, Geom::identity(), Geom::identity()); // We will get our own copy of the path, which must be freed at some point
-                _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(pathv, SNAPTARGET_PATH));
+                _paths_to_snap_to->push_back(std::make_pair(pathv, SNAPTARGET_PATH));
                 curve->unref();
             }
         }
@@ -496,7 +498,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
                 if (!being_edited || (c1 && c2)) {
                     Geom::Coord const dist = Geom::distance(sp_doc, p_doc);
                     if (dist < getSnapperTolerance()) {
-                        sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, it_p->second));
+                        sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, source_type, it_p->second));
                     }
                 }
             }
@@ -505,7 +507,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
 }
 
 /* Returns true if point is coincident with one of the unselected nodes */
-bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<Geom::Point> const *unselected_nodes) const
+bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const
 {
     if (unselected_nodes == NULL) {
         return false;
@@ -515,8 +517,8 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
         return false;
     }
 
-    for (std::vector<Geom::Point>::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
-        if (Geom::L2(point - *i) < 1e-4) {
+    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
+        if (Geom::L2(point - (*i).first) < 1e-4) {
             return true;
         }
     }
@@ -527,6 +529,7 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
 void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
                                      Inkscape::SnapPreferences::PointType const &t,
                                      Geom::Point const &p,
+                                     SnapSourceType const source_type,
                                      bool const &first_point,
                                      ConstraintLine const &c) const
 {
@@ -572,7 +575,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
                         // When it's within snapping range, then return it
                         // (within snapping range == between p_min_on_cl and p_max_on_cl == 0 < ta < 1)
                         Geom::Coord dist = Geom::L2(_snapmanager->getDesktop()->dt2doc(p_proj_on_cl) - p_inters);
-                        SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+                        SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), source_type, k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
                         sc.points.push_back(s);
                     }
                 }
@@ -585,10 +588,11 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
 void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
                                             Inkscape::SnapPreferences::PointType const &t,
                                             Geom::Point const &p,
+                                            SnapSourceType const &source_type,
                                             bool const &first_point,
                                             Geom::OptRect const &bbox_to_snap,
                                             std::vector<SPItem const *> const *it,
-                                            std::vector<Geom::Point> *unselected_nodes) const
+                                            std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
 {
     if (_snap_enabled == false || _snapmanager->snapprefs.getSnapFrom(t) == false ) {
         return;
@@ -605,7 +609,7 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
                || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints()
                || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()
                || _snapmanager->snapprefs.getIncludeItemCenter()) {
-        _snapNodes(sc, t, p, first_point, unselected_nodes);
+        _snapNodes(sc, t, p, source_type, first_point, unselected_nodes);
     }
 
     if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
@@ -622,9 +626,9 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
                 g_assert(it->size() == 1);
                 path = SP_PATH(*it->begin());
             }
-            _snapPaths(sc, t, p, first_point, unselected_nodes, path);
+            _snapPaths(sc, t, p, source_type, first_point, unselected_nodes, path);
         } else {
-            _snapPaths(sc, t, p, first_point, NULL, NULL);
+            _snapPaths(sc, t, p, source_type, first_point, NULL, NULL);
         }
     }
 }
@@ -632,6 +636,7 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
 void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
                                                   Inkscape::SnapPreferences::PointType const &t,
                                                   Geom::Point const &p,
+                                                  SnapSourceType const &source_type,
                                                   bool const &first_point,
                                                   Geom::OptRect const &bbox_to_snap,
                                                   ConstraintLine const &c,
@@ -648,7 +653,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
     }
 
     // A constrained snap, is a snap in only one degree of freedom (specified by the constraint line).
-    // This is usefull for example when scaling an object while maintaining a fixed aspect ratio. It's
+    // This is useful for example when scaling an object while maintaining a fixed aspect ratio. It's
     // nodes are only allowed to move in one direction (i.e. in one degree of freedom).
 
     // When snapping to objects, we either snap to their nodes or their paths. It is however very
@@ -657,7 +662,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
     // so we will more or less snap to them anyhow.
 
     if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
-        _snapPathsConstrained(sc, t, p, first_point, c);
+        _snapPathsConstrained(sc, t, p, source_type, first_point, c);
     }
 }
 
@@ -743,31 +748,31 @@ Geom::PathVector* Inkscape::ObjectSnapper::_getPathvFromRect(Geom::Rect const re
     }
 }
 
-void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<Geom::Point> *points) const
+void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const
 {
     Geom::Coord w = sp_document_width(_snapmanager->getDocument());
     Geom::Coord h = sp_document_height(_snapmanager->getDocument());
-    points->push_back(Geom::Point(0,0));
-    points->push_back(Geom::Point(0,h));
-    points->push_back(Geom::Point(w,h));
-    points->push_back(Geom::Point(w,0));
+    points->push_back(std::make_pair(Geom::Point(0,0), SNAPTARGET_PAGE_CORNER));
+    points->push_back(std::make_pair(Geom::Point(0,h), SNAPTARGET_PAGE_CORNER));
+    points->push_back(std::make_pair(Geom::Point(w,h), SNAPTARGET_PAGE_CORNER));
+    points->push_back(std::make_pair(Geom::Point(w,0), SNAPTARGET_PAGE_CORNER));
 }
 
-void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
+void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
 {
        if (bbox) {
                // collect the corners of the bounding box
                for ( unsigned k = 0 ; k < 4 ; k++ ) {
                        if (includeCorners) {
-                               points->push_back(bbox->corner(k));
+                               points->push_back(std::make_pair((bbox->corner(k)), isTarget ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER)));
                        }
                        // optionally, collect the midpoints of the bounding box's edges too
                        if (includeLineMidpoints) {
-                               points->push_back((bbox->corner(k) + bbox->corner((k+1) % 4))/2);
+                               points->push_back(std::make_pair((bbox->corner(k) + bbox->corner((k+1) % 4))/2, isTarget ? int(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT)));
                        }
                }
                if (includeObjectMidpoints) {
-                       points->push_back(bbox->midpoint());
+                       points->push_back(std::make_pair(bbox->midpoint(), isTarget ? int(Inkscape::SNAPTARGET_BBOX_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_MIDPOINT)));
                }
        }
 }
index 9a6978d4705e5c305d2b8f99ea4e1aeabaae7217..f220106e389a73fc97a409322db5aaf6c834e908 100644 (file)
@@ -69,14 +69,16 @@ public:
        void freeSnap(SnappedConstraints &sc,
                                  Inkscape::SnapPreferences::PointType const &t,
                                  Geom::Point const &p,
+                                 SnapSourceType const &source_type,
                                  bool const &first_point,
                                  Geom::OptRect const &bbox_to_snap,
                                  std::vector<SPItem const *> const *it,
-                                 std::vector<Geom::Point> *unselected_nodes) const;
+                                 std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
 
        void constrainedSnap(SnappedConstraints &sc,
                                  Inkscape::SnapPreferences::PointType const &t,
                                  Geom::Point const &p,
+                                 SnapSourceType const &source_type,
                                  bool const &first_point,
                                  Geom::OptRect const &bbox_to_snap,
                                  ConstraintLine const &c,
@@ -85,7 +87,7 @@ public:
 private:
     //store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap
     std::vector<SnapCandidate> *_candidates;
-    std::vector<Geom::Point> *_points_to_snap_to;
+    std::vector<std::pair<Geom::Point, int> > *_points_to_snap_to;
     std::vector<std::pair<Geom::PathVector*, SnapTargetType> > *_paths_to_snap_to;
 
     void _findCandidates(SPObject* parent,
@@ -99,8 +101,9 @@ private:
     void _snapNodes(SnappedConstraints &sc,
                       Inkscape::SnapPreferences::PointType const &t,
                       Geom::Point const &p, // in desktop coordinates
+                      SnapSourceType const &source_type,
                       bool const &first_point,
-                      std::vector<Geom::Point> *unselected_nodes) const; // in desktop coordinates
+                      std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; // in desktop coordinates
 
     void _snapTranslatingGuideToNodes(SnappedConstraints &sc,
                      Inkscape::SnapPreferences::PointType const &t,
@@ -113,17 +116,19 @@ private:
     void _snapPaths(SnappedConstraints &sc,
                       Inkscape::SnapPreferences::PointType const &t,
                       Geom::Point const &p,    // in desktop coordinates
+                      SnapSourceType const &source_type,
                       bool const &first_point,
-                      std::vector<Geom::Point> *unselected_nodes, // in desktop coordinates
+                      std::vector<std::pair<Geom::Point, int> > *unselected_nodes, // in desktop coordinates
                       SPPath const *selected_path) const;
 
     void _snapPathsConstrained(SnappedConstraints &sc,
                  Inkscape::SnapPreferences::PointType const &t,
                  Geom::Point const &p, // in desktop coordinates
-                 bool const &first_point,
+                 SnapSourceType const source_type,
+                                bool const &first_point,
                  ConstraintLine const &c) const;
 
-    bool isUnselectedNode(Geom::Point const &point, std::vector<Geom::Point> const *unselected_nodes) const;
+    bool isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const;
 
     void _collectPaths(Inkscape::SnapPreferences::PointType const &t,
                   bool const &first_point) const;
@@ -131,11 +136,11 @@ private:
     void _clear_paths() const;
     Geom::PathVector* _getBorderPathv() const;
     Geom::PathVector* _getPathvFromRect(Geom::Rect const rect) const;
-    void _getBorderNodes(std::vector<Geom::Point> *points) const;
+    void _getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const;
 
 }; // end of ObjectSnapper class
 
-void getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
+void getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
 
 } // end of namespace Inkscape
 
index 804c736bee91c1af5b30dbf913674810eefa6d43..7ff3de9e1de7c7a8900940a2210833890ffc76d2 100644 (file)
@@ -477,7 +477,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
                                if (!(bevent.state & GDK_SHIFT_MASK)) {
                                        SnapManager &m = desktop->namedview->snap_manager;
                                        m.setup(desktop);
-                                                                       m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+                                                                       m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
                                }
                                                                spdc_create_single_dot(event_context, p, "/tools/freehand/pen", bevent.state);
                                                                ret = TRUE;
index de286ea5afba91416a7e11843e6ce30fe629633f..3e3a95c24922eabbfebfcc9df048cfc2077da460 100644 (file)
@@ -259,7 +259,7 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
 
                 if (bevent.state & GDK_CONTROL_MASK) {
                        if (!(bevent.state & GDK_SHIFT_MASK)) {
-                               m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+                               m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
                        }
                                        spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state);
                                        sp_canvas_set_snap_delay_active(desktop->canvas, false);
@@ -277,10 +277,10 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
                         // anchor, which is handled by the sibling branch above)
                         selection->clear();
                         desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path"));
-                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
                     } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) {
                         desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path"));
-                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+                        m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
                     }
                 }
                 pc->sa = anchor;
index c63e1dc2ab5505db9f10a90b3a58ff35f2461545..3650e05b1115d5da06d6fb4097f09802dc9dc76d 100644 (file)
@@ -266,7 +266,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
             /* Snap center */
             SnapManager &m = desktop->namedview->snap_manager;
             m.setup(desktop);
-            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
             rc->center = from_2geom(button_dt);
 
             sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
index 3ffebeb065a081acee6349675f0427be79cfeb45..505e18675779c6e46bf4ea2dc2add7b7308542fc 100644 (file)
@@ -6,14 +6,14 @@
 #include <approx-equal.h>
 
 void satisfied_guide_cns(SPDesktop const &desktop,
-                         std::vector<Geom::Point> const &snappoints,
+                         SnapPointsWithType const &snappoints,
                          std::vector<SPGuideConstraint> &cns)
 {
     SPNamedView const &nv = *sp_desktop_namedview(&desktop);
     for (GSList const *l = nv.guides; l != NULL; l = l->next) {
         SPGuide &g = *SP_GUIDE(l->data);
         for (unsigned int i = 0; i < snappoints.size(); ++i) {
-            if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i]), 0) ) {
+            if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i].first), 0) ) {
                 cns.push_back(SPGuideConstraint(&g, i));
             }
         }
index 1952bef448402906bfa0eddd2002a5c1d12a3f25..99229f64c9aafc084c39d888b62ac2ecd0dc7725 100644 (file)
@@ -4,10 +4,12 @@
 #include <forward.h>
 #include <2geom/forward.h>
 #include <vector>
+#include <sp-item.h>
+
 class SPGuideConstraint;
 
 void satisfied_guide_cns(SPDesktop const &desktop,
-                         std::vector<Geom::Point> const &snappoints,
+                         SnapPointsWithType const &snappoints,
                          std::vector<SPGuideConstraint> &cns);
 
 
index ea1c0053fa6be419f3c4178cf9e36f17d36f396c..4d92a18df77948f7de0620a8609566eb9e33075e 100644 (file)
@@ -441,48 +441,48 @@ boost::optional<Geom::Point> Selection::center() const {
 /**
  * Compute the list of points in the selection that are to be considered for snapping.
  */
-std::vector<Geom::Point> Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
+std::vector<std::pair<Geom::Point, int> > Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
-    
+
     SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs
     snapprefs_dummy.setIncludeItemCenter(false); // locally disable snapping to the item center
-    
-    std::vector<Geom::Point> p;
+
+    std::vector<std::pair<Geom::Point, int> > p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
         SPItem *this_item = SP_ITEM(iter->data);
-        sp_item_snappoints(this_item, SnapPointsIter(p), &snapprefs_dummy);
-       
+        sp_item_snappoints(this_item, false, p, &snapprefs_dummy);
+
         //Include the transformation origin for snapping
         //For a selection or group only the overall origin is considered
         if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-               p.push_back(this_item->getCenter());
-        }  
+               p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
+        }
     }
 
     return p;
 }
 
-std::vector<Geom::Point> Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
+std::vector<std::pair<Geom::Point, int> > Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
-    std::vector<Geom::Point> p;
+    std::vector<std::pair<Geom::Point, int> > p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
-               sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p), snapprefs);
+               sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
     }
 
-    std::vector<Geom::Point> pHull;
+    std::vector<std::pair<Geom::Point, int> > pHull;
     if (!p.empty()) {
-        std::vector<Geom::Point>::iterator i;
-        Geom::RectHull cvh(p.front());
+       std::vector<std::pair<Geom::Point, int> >::iterator i;
+        Geom::RectHull cvh((p.front()).first);
         for (i = p.begin(); i != p.end(); i++) {
             // these are the points we get back
-            cvh.add(*i);
+            cvh.add((*i).first);
         }
 
         Geom::OptRect rHull = cvh.bounds();
         if (rHull) {
             for ( unsigned i = 0 ; i < 4 ; ++i ) {
-                pHull.push_back(rHull->corner(i));
+                pHull.push_back(std::make_pair(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
             }
         }
     }
index f3ab8e1c1a07ed48954bea58d97a020dd9823af9..ecb1ef45e5399780cbe4812bf52a1bb18b6517ce 100644 (file)
@@ -30,6 +30,7 @@
 #include "gc-soft-ptr.h"
 #include "util/list.h"
 #include "sp-item.h"
+#include "snapped-point.h"
 
 class SPItem;
 class SPBox3D;
@@ -57,7 +58,7 @@ namespace Inkscape {
  * at the given desktop. Both SPItem and SPRepr lists can be retrieved
  * from the selection. Many actions operate on the selection, so it is
  * widely used throughout the code.
- * It also implements its own asynchronous notification signals that 
+ * It also implements its own asynchronous notification signals that
  * UI elements can listen to.
  */
 class Selection : public Inkscape::GC::Managed<>,
@@ -249,7 +250,7 @@ public:
      * @brief Returns the bounding rectangle of the selection
      *
      * \todo how is this different from bounds()?
-     */ 
+     */
     NRRect *boundsInDocument(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
 
     /**
@@ -268,13 +269,13 @@ public:
      * @brief Gets the selection's snap points.
      * @return Selection's snap points
      */
-    std::vector<Geom::Point> getSnapPoints(SnapPreferences const *snapprefs) const;
+    std::vector<std::pair<Geom::Point, int> > getSnapPoints(SnapPreferences const *snapprefs) const;
 
     /**
      * @brief Gets the snap points of a selection that form a convex hull.
      * @return Selection's convex hull points
      */
-    std::vector<Geom::Point> getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
+    std::vector<std::pair<Geom::Point, int> > getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
 
     /**
      * @brief Connects a slot to be notified of selection changes
@@ -291,8 +292,8 @@ public:
     }
 
     /**
-     * @brief Connects a slot to be notified of selected 
-     *        object modifications 
+     * @brief Connects a slot to be notified of selected
+     *        object modifications
      *
      * This method connects the given slot such that it will
      * receive notifications whenever any selected item is
index 4614adb87c9dea7f1e7111f32ff983da0f4b6441..f3ad2849c4ed802d04397b9f2cd2254b9fe98c37 100644 (file)
@@ -291,7 +291,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
        // but as a snap source we still need some nodes though!
     _snap_points.clear();
        _snap_points = selection->getSnapPoints(&local_snapprefs);
-       std::vector<Geom::Point> snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
+       std::vector<std::pair<Geom::Point, int> > snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
        if (_snap_points.size() > 100) {
                /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes
                An average user would rarely ever try to snap such a large number of nodes anyway, because
@@ -305,11 +305,11 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
     // any other special points
     Geom::Rect snap_points_bbox;
     if ( snap_points_hull.empty() == false ) {
-        std::vector<Geom::Point>::iterator i = snap_points_hull.begin();
-        snap_points_bbox = Geom::Rect(*i, *i);
+       std::vector<std::pair<Geom::Point, int> >::iterator i = snap_points_hull.begin();
+        snap_points_bbox = Geom::Rect((*i).first, (*i).first);
         i++;
         while (i != snap_points_hull.end()) {
-            snap_points_bbox.expandTo(*i);
+            snap_points_bbox.expandTo((*i).first);
             i++;
         }
     }
@@ -317,7 +317,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
     _bbox_points.clear();
     if (_bbox) {
        if (m.snapprefs.getSnapModeBBox()) {
-               getBBoxPoints(_bbox, &_bbox_points, true, m.snapprefs.getSnapBBoxEdgeMidpoints(), m.snapprefs.getSnapBBoxMidpoints());
+               getBBoxPoints(_bbox, &_bbox_points, false, true, m.snapprefs.getSnapBBoxEdgeMidpoints(), m.snapprefs.getSnapBBoxMidpoints());
        }
        // There are two separate "opposites" (i.e. opposite w.r.t. the handle being dragged):
         //  - one for snapping the boundingbox, which can be either visual or geometric
@@ -350,7 +350,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
        g_assert(_bbox_points.size() < 2 && _snap_points.size() < 2);
        if (_snap_points.size() == 1 && _bbox_points.size() == 1) { //both vectors can only have either one or zero elements
                // So we have exactly one bbox corner and one node left; now find out which is closest and delete the other one
-               if (Geom::L2(_snap_points.at(0) - p) < Geom::L2(_bbox_points.at(0) - p)) {
+               if (Geom::L2((_snap_points.at(0)).first - p) < Geom::L2((_bbox_points.at(0)).first - p)) {
                        _bbox_points.clear();
                } else {
                        _snap_points.clear();
@@ -370,20 +370,6 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
 
        sp_canvas_set_snap_delay_active(_desktop->canvas, true);
 
-    // The lines below are useful for debugging any snapping issues, as they'll spit out all points that are considered for snapping
-
-    /*std::cout << "Number of snap points:  " << _snap_points.size() << std::endl;
-    for (std::vector<Geom::Point>::const_iterator i = _snap_points.begin(); i != _snap_points.end(); i++)
-    {
-        std::cout << "    " << *i << std::endl;
-    }
-
-    std::cout << "Number of bbox points:  " << _bbox_points.size() << std::endl;
-    for (std::vector<Geom::Point>::const_iterator i = _bbox_points.begin(); i != _bbox_points.end(); i++)
-    {
-        std::cout << "    " << *i << std::endl;
-    }*/
-
     if ((x != -1) && (y != -1)) {
         sp_canvas_item_show(_norm);
         sp_canvas_item_show(_grip);
@@ -1295,11 +1281,12 @@ gboolean Inkscape::SelTrans::rotateRequest(Geom::Point &pt, guint state)
     return TRUE;
 }
 
+// Move the item's transformation center
 gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state)
 {
     SnapManager &m = _desktop->namedview->snap_manager;
     m.setup(_desktop);
-    m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, pt);
+    m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, pt, Inkscape::SNAPSOURCE_HANDLE);
 
     if (state & GDK_CONTROL_MASK) {
         if ( fabs(_point[Geom::X] - pt[Geom::X]) > fabs(_point[Geom::Y] - pt[Geom::Y]) ) {
@@ -1407,7 +1394,7 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state)
         */
 
        m.setup(_desktop, true, _items_const);
-       m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy);
+       m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy, Inkscape::SNAPSOURCE_UNDEFINED);
 
     } else if (!shift) {
 
@@ -1593,15 +1580,15 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineGeom(Geom::Scale const geom_scale)
     return visual_bbox.min() + visual_bbox.dimensions() * Geom::Scale(_handle_x, _handle_y);
 }
 
-void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<Geom::Point> &points, const Geom::Point &reference)
+void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference)
 {
        if (points.size() < 2) return;
 
-       Geom::Point closest_point = Geom::Point(NR_HUGE, NR_HUGE);
+       std::pair<Geom::Point, int> closest_point = std::make_pair(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED);
        Geom::Coord closest_dist = NR_HUGE;
 
-       for(std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
-               Geom::Coord dist = Geom::L2(*i - reference);
+       for(std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
+               Geom::Coord dist = Geom::L2((*i).first - reference);
                if (i == points.begin() || dist < closest_dist) {
                        closest_point = *i;
                        closest_dist = dist;
index 42effff7c03dfb4e2eff255362ba5bb44884fe5a..4f47d8e2072d7311f537adbe6b787845ee29d881 100644 (file)
@@ -86,7 +86,7 @@ public:
         return _empty;
     }
     bool isGrabbed() {
-        return _grabbed;    
+        return _grabbed;
     }
        bool centerIsVisible() {
                return ( _chandle && SP_KNOT_IS_VISIBLE (_chandle) );
@@ -102,24 +102,24 @@ private:
     Geom::Point _getGeomHandlePos(Geom::Point const &visual_handle_pos);
     Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale);
     Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale);
-    void _keepClosestPointOnly(std::vector<Geom::Point> &points, const Geom::Point &reference);
+    void _keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference);
     void _display_snapsource();
 
     enum State {
         STATE_SCALE, //scale or stretch
         STATE_ROTATE //rotate or skew
     };
-    
+
     SPDesktop *_desktop;
 
     std::vector<SPItem *> _items;
     std::vector<SPItem const *> _items_const;
     std::vector<Geom::Matrix> _items_affines;
     std::vector<Geom::Point> _items_centers;
-    
-    std::vector<Geom::Point> _snap_points;
-    std::vector<Geom::Point> _bbox_points;
-    
+
+    std::vector<std::pair<Geom::Point, int> > _snap_points;
+    std::vector<std::pair<Geom::Point, int> > _bbox_points;
+
     Inkscape::SelCue _selcue;
 
     Inkscape::Selection *_selection;
@@ -132,12 +132,12 @@ private:
     bool _changed;
 
     SPItem::BBoxType _snap_bbox_type;
-    
+
     Geom::OptRect _bbox;
     Geom::OptRect _approximate_bbox;
     Geom::OptRect _geometric_bbox;
     gdouble _strokewidth;
-    
+
     Geom::Matrix _current_relative_affine;
     Geom::Matrix _absolute_affine;
     Geom::Matrix _relative_affine;
@@ -146,8 +146,8 @@ private:
      * lines into straight lines and parallel lines into parallel lines but may alter distance between points
      * and angles between lines <affine geometry>
      */
-    
-    Geom::Point _opposite; ///< opposite point to where a scale is taking place    
+
+    Geom::Point _opposite; ///< opposite point to where a scale is taking place
     Geom::Point _opposite_for_specpoints;
     Geom::Point _opposite_for_bboxpoints;
     Geom::Point _origin_for_specpoints;
index 548741455704b51b510b052b2d9df4a608d0dd9f..a170046c23c4a70232e82819e25f3d03d6e4affc 100644 (file)
@@ -137,14 +137,16 @@ bool SnapManager::gridSnapperMightSnap() const
  */
 
 void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
-                                             Geom::Point &p,
-                                             bool first_point,
+                                                                                        Geom::Point &p,
+                                                                                        Inkscape::SnapSourceType const source_type,
+                                                                                        bool first_point,
                                              Geom::OptRect const &bbox_to_snap) const
 {
-    Inkscape::SnappedPoint const s = freeSnap(point_type, p, first_point, bbox_to_snap);
+    Inkscape::SnappedPoint const s = freeSnap(point_type, p, source_type, first_point, bbox_to_snap);
     s.getPoint(p);
 }
 
+
 /**
  *  Try to snap a point to any of the specified snappers.
  *
@@ -157,8 +159,9 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point
  */
 
 Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType point_type,
-                                             Geom::Point const &p,
-                                             bool first_point,
+                                                                                        Geom::Point const &p,
+                                                                                        Inkscape::SnapSourceType const &source_type,
+                                                                                        bool first_point,
                                              Geom::OptRect const &bbox_to_snap) const
 {
        if (_desktop->canvas->context_snap_delay_active == false) {
@@ -167,7 +170,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
        }
 
        if (!someSnapperMightSnap()) {
-        return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+        return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
     }
 
     std::vector<SPItem const *> *items_to_ignore;
@@ -184,14 +187,14 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
     SnapperList const snappers = getSnappers();
 
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->freeSnap(sc, point_type, p, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes);
+        (*i)->freeSnap(sc, point_type, p, source_type, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes);
     }
 
     if (_item_to_ignore) {
         delete items_to_ignore;
     }
 
-    return findBestSnap(p, sc, false);
+    return findBestSnap(p, source_type, sc, false);
 }
 
 // When pasting, we would like to snap to the grid. Problem is that we don't know which nodes were
@@ -199,7 +202,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
 // unaligned node to the grid, previously aligned nodes would become unaligned. That's undesirable.
 // Instead we will make sure that the offset between the source and the copy is a multiple of the grid
 // pitch. If the source was aligned, then the copy will therefore also be aligned
-// PS: Wether we really find a multiple also depends on the snapping range!
+// PS: Whether we really find a multiple also depends on the snapping range!
 Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
 {
     if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here
@@ -229,9 +232,9 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
                 Geom::Point const t_offset = t + grid->origin;
                 SnappedConstraints sc;
                 // Only the first three parameters are being used for grid snappers
-                snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, TRUE, Geom::OptRect(), NULL, NULL);
+                snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, TRUE, Geom::OptRect(), NULL, NULL);
                 // Find the best snap for this grid, including intersections of the grid-lines
-                Inkscape::SnappedPoint s = findBestSnap(t_offset, sc, false);
+                Inkscape::SnappedPoint s = findBestSnap(t_offset, Inkscape::SNAPSOURCE_UNDEFINED, sc, false);
                 if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
                     // use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
                     // doesn't tell us anything about which node to snap
@@ -262,15 +265,17 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
  */
 
 void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
-                                                    Geom::Point &p,
+                                                                                                       Geom::Point &p,
+                                                                                                       Inkscape::SnapSourceType const source_type,
                                                     Inkscape::Snapper::ConstraintLine const &constraint,
                                                     bool first_point,
                                                     Geom::OptRect const &bbox_to_snap) const
 {
-    Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, constraint, first_point, bbox_to_snap);
+    Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, source_type, constraint, first_point, bbox_to_snap);
     s.getPoint(p);
 }
 
+
 /**
  *  Try to snap a point to any interested snappers.  A snap will only occur along
  *  a line described by a Inkscape::Snapper::ConstraintLine.
@@ -284,7 +289,8 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
-                                                    Geom::Point const &p,
+                                                                                                       Geom::Point const &p,
+                                                                                                       Inkscape::SnapSourceType const &source_type,
                                                     Inkscape::Snapper::ConstraintLine const &constraint,
                                                     bool first_point,
                                                     Geom::OptRect const &bbox_to_snap) const
@@ -295,7 +301,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
        }
 
        if (!someSnapperMightSnap()) {
-        return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+        return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
     }
 
     std::vector<SPItem const *> *items_to_ignore;
@@ -311,14 +317,14 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
     SnappedConstraints sc;
     SnapperList const snappers = getSnappers();
     for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
-        (*i)->constrainedSnap(sc, point_type, p, first_point, bbox_to_snap, constraint, items_to_ignore);
+        (*i)->constrainedSnap(sc, point_type, p, source_type, first_point, bbox_to_snap, constraint, items_to_ignore);
     }
 
     if (_item_to_ignore) {
         delete items_to_ignore;
     }
 
-    return findBestSnap(p, sc, true);
+    return findBestSnap(p, source_type, sc, true);
 }
 
 void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const
@@ -337,7 +343,7 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
     SnappedConstraints sc;
     object.guideSnap(sc, p, guide_normal);
 
-    Inkscape::SnappedPoint const s = findBestSnap(p, sc, false);
+    Inkscape::SnappedPoint const s = findBestSnap(p, Inkscape::SNAPSOURCE_GUIDE, sc, false);
     s.getPoint(p);
 }
 
@@ -361,7 +367,7 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
 
 Inkscape::SnappedPoint SnapManager::_snapTransformed(
     Inkscape::SnapPreferences::PointType type,
-    std::vector<Geom::Point> const &points,
+    std::vector<std::pair<Geom::Point, int> > const &points,
     Geom::Point const &pointer,
     bool constrained,
     Inkscape::Snapper::ConstraintLine const &constraint,
@@ -383,10 +389,10 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
         return Inkscape::SnappedPoint();
     }
 
-    std::vector<Geom::Point> transformed_points;
+    std::vector<std::pair<Geom::Point, int> > transformed_points;
     Geom::Rect bbox;
 
-    for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
 
         /* Work out the transformed version of this point */
         Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform);
@@ -398,7 +404,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
             bbox.expandTo(transformed);
         }
 
-        transformed_points.push_back(transformed);
+        transformed_points.push_back(std::make_pair(transformed, (*i).second));
     }
 
     /* The current best transformation */
@@ -412,15 +418,15 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
     g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point
     g_assert(best_snapped_point.getAtIntersection() == false);
 
-    std::vector<Geom::Point>::const_iterator j = transformed_points.begin();
+    std::vector<std::pair<Geom::Point, int> >::const_iterator j = transformed_points.begin();
 
     // std::cout << std::endl;
-    for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+    for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
 
         /* Snap it */
         Inkscape::SnappedPoint snapped_point;
         Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
-        Geom::Point const b = (*i - origin); // vector to original point
+        Geom::Point const b = ((*i).first - origin); // vector to original point
 
         if (constrained) {
             if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) {
@@ -429,18 +435,18 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                 // calculate that line here
                 dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, b);
             } else if (transformation_type == STRETCH) { // when non-uniform stretching {
-                dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]);
+                dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i).first, component_vectors[dim]);
             } else if (transformation_type == TRANSLATION) {
                 // When doing a constrained translation, all points will move in the same direction, i.e.
                 // either horizontally or vertically. The lines along which they move are therefore all
                 // parallel, but might not be colinear. Therefore we will have to set the point through
                 // which the constraint-line runs here, for each point individually.
-                dedicated_constraint.setPoint(*i);
+                dedicated_constraint.setPoint((*i).first);
             } // else: leave the original constraint, e.g. for skewing
             if (transformation_type == SCALE && !uniform) {
                 g_warning("Non-uniform constrained scaling is not supported!");
             }
-            snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
+            snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox);
         } else {
             bool const c1 = fabs(b[Geom::X]) < 1e-6;
             bool const c2 = fabs(b[Geom::Y]) < 1e-6;
@@ -449,13 +455,13 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                 // move in that specific direction; therefore it should only snap in that direction, otherwise
                 // we will get snapped points with an invalid transformation
                 dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]);
-                snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
+                snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox);
             } else {
-                snapped_point = freeSnap(type, *j, i == points.begin(), bbox);
+                snapped_point = freeSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), i == points.begin(), bbox);
             }
         }
         // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl;
-        snapped_point.setPointerDistance(Geom::L2(pointer - *i));
+        snapped_point.setPointerDistance(Geom::L2(pointer - (*i).first));
 
         Geom::Point result;
         Geom::Point scale_metric(NR_HUGE, NR_HUGE);
@@ -469,7 +475,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
 
             switch (transformation_type) {
                 case TRANSLATION:
-                    result = snapped_point.getPoint() - *i;
+                    result = snapped_point.getPoint() - (*i).first;
                     /* 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
@@ -519,7 +525,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
                     snapped_point.setSecondSnapDistance(NR_HUGE);
                     break;
                 case SKEW:
-                    result[0] = (snapped_point.getPoint()[dim] - (*i)[dim]) / ((*i)[1 - dim] - origin[1 - dim]); // skew factor
+                    result[0] = (snapped_point.getPoint()[dim] - ((*i).first)[dim]) / (((*i).first)[1 - dim] - origin[1 - dim]); // skew factor
                     result[1] = transformation[1]; // scale factor
                     // Store the metric for this transformation as a virtual distance
                     snapped_point.setSnapDistance(std::abs(result[0] - transformation[0]));
@@ -600,12 +606,12 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed(
  */
 
 Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                        std::vector<Geom::Point> const &p,
+                                                        std::vector<std::pair<Geom::Point, int> > const &p,
                                                         Geom::Point const &pointer,
                                                         Geom::Point const &tr) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -625,13 +631,13 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                               std::vector<Geom::Point> const &p,
+                                                               std::vector<std::pair<Geom::Point, int> > const &p,
                                                                Geom::Point const &pointer,
                                                                Inkscape::Snapper::ConstraintLine const &constraint,
                                                                Geom::Point const &tr) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -650,13 +656,13 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre
  */
 
 Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                  std::vector<Geom::Point> const &p,
+                                                  std::vector<std::pair<Geom::Point, int> > const &p,
                                                   Geom::Point const &pointer,
                                                   Geom::Scale const &s,
                                                   Geom::Point const &o) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
@@ -676,14 +682,14 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                         std::vector<Geom::Point> const &p,
+                                                         std::vector<std::pair<Geom::Point, int> > const &p,
                                                          Geom::Point const &pointer,
                                                          Geom::Scale const &s,
                                                          Geom::Point const &o) const
 {
     // When constrained scaling, only uniform scaling is supported.
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
@@ -704,7 +710,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
-                                                            std::vector<Geom::Point> const &p,
+                                                            std::vector<std::pair<Geom::Point, int> > const &p,
                                                             Geom::Point const &pointer,
                                                             Geom::Coord const &s,
                                                             Geom::Point const &o,
@@ -712,7 +718,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
                                                             bool u) const
 {
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
@@ -732,7 +738,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
  */
 
 Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
-                                                 std::vector<Geom::Point> const &p,
+                                                 std::vector<std::pair<Geom::Point, int> > const &p,
                                                  Geom::Point const &pointer,
                                                  Inkscape::Snapper::ConstraintLine const &constraint,
                                                  Geom::Point const &s,
@@ -749,13 +755,13 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
     g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
 
     if (p.size() == 1) {
-        _displaySnapsource(point_type, _transformPoint(p.at(0), SKEW, s, o, d, false));
+        _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SKEW, s, o, d, false), (p.at(0)).second));
     }
 
     return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
 }
 
-Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const
+Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained) const
 {
 
     /*
@@ -786,7 +792,8 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
         // search for the closest snapped intersection of curves
         Inkscape::SnappedPoint closestCurvesIntersection;
         if (getClosestIntersectionCS(sc.curves, p, closestCurvesIntersection, _desktop->dt2doc())) {
-            sp_list.push_back(closestCurvesIntersection);
+               closestCurvesIntersection.setSource(source_type);
+               sp_list.push_back(closestCurvesIntersection);
         }
     }
 
@@ -814,14 +821,16 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
         // search for the closest snapped intersection of grid lines
         Inkscape::SnappedPoint closestGridPoint;
         if (getClosestIntersectionSL(sc.grid_lines, closestGridPoint)) {
-            closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
+               closestGridPoint.setSource(source_type);
+               closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
             sp_list.push_back(closestGridPoint);
         }
 
         // search for the closest snapped intersection of guide lines
         Inkscape::SnappedPoint closestGuidePoint;
         if (getClosestIntersectionSL(sc.guide_lines, closestGuidePoint)) {
-            closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
+               closestGuidePoint.setSource(source_type);
+               closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
             sp_list.push_back(closestGuidePoint);
         }
 
@@ -829,14 +838,15 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
         if (snapprefs.getSnapIntersectionGG()) {
             Inkscape::SnappedPoint closestGridGuidePoint;
             if (getClosestIntersectionSL(sc.grid_lines, sc.guide_lines, closestGridGuidePoint)) {
-                closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
+               closestGridGuidePoint.setSource(source_type);
+               closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
                 sp_list.push_back(closestGridGuidePoint);
             }
         }
     }
 
     // now let's see which snapped point gets a thumbs up
-    Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+    Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
     // std::cout << "Finding the best snap..." << std::endl;
     for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
         // first find out if this snapped point is within snapping range
@@ -864,7 +874,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
     return bestSnappedPoint;
 }
 
-void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem const *item_to_ignore, std::vector<Geom::Point> *unselected_nodes)
+void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem const *item_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes)
 {
     g_assert(desktop != NULL);
     _item_to_ignore = item_to_ignore;
@@ -874,7 +884,7 @@ void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem con
     _unselected_nodes = unselected_nodes;
 }
 
-void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<Geom::Point> *unselected_nodes)
+void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes)
 {
     g_assert(desktop != NULL);
     _item_to_ignore = NULL;
@@ -889,7 +899,7 @@ SPDocument *SnapManager::getDocument() const
     return _named_view->document;
 }
 
-Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
+Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
                                         Transformation const transformation_type,
                                         Geom::Point const &transformation,
                                         Geom::Point const &origin,
@@ -900,10 +910,10 @@ Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
     Geom::Point transformed;
     switch (transformation_type) {
         case TRANSLATION:
-            transformed = p + transformation;
+            transformed = p.first + transformation;
             break;
         case SCALE:
-            transformed = (p - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
+            transformed = (p.first - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
             break;
         case STRETCH:
         {
@@ -914,15 +924,15 @@ Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
                 s[dim] = transformation[dim];
                 s[1 - dim] = 1;
             }
-            transformed = ((p - origin) * s) + origin;
+            transformed = ((p.first - origin) * s) + origin;
             break;
         }
         case SKEW:
             // Apply the skew factor
-            transformed[dim] = p[dim] + transformation[0] * (p[1 - dim] - origin[1 - dim]);
+            transformed[dim] = (p.first)[dim] + transformation[0] * ((p.first)[1 - dim] - origin[1 - dim]);
             // While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed.
             // Apply that scale factor here
-            transformed[1-dim] = (p - origin)[1 - dim] * transformation[1] + origin[1 - dim];
+            transformed[1-dim] = (p.first - origin)[1 - dim] * transformation[1] + origin[1 - dim];
             break;
         default:
             g_assert_not_reached();
@@ -931,7 +941,7 @@ Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
     return transformed;
 }
 
-void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const {
+void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const {
 
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     if (prefs->getBool("/options/snapclosestonly/value")) {
index b86ceb8b0e7f3fdc5e5351c8098013f828395e62..b6ec3a5d74d64629cb70a3a220bf55e848905e46 100644 (file)
@@ -56,64 +56,69 @@ public:
     bool someSnapperMightSnap() const;
     bool gridSnapperMightSnap() const;
 
-    void setup(SPDesktop const *desktop, bool snapindicator = true, SPItem const *item_to_ignore = NULL, std::vector<Geom::Point> *unselected_nodes = NULL);
-    void setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<Geom::Point> *unselected_nodes = NULL);
+    void setup(SPDesktop const *desktop, bool snapindicator = true, SPItem const *item_to_ignore = NULL, std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL);
+    void setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL);
 
     // freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a
-    // point if snapping has occured (by overwriting p); otherwise p is untouched
+    // point if snapping has occurred (by overwriting p); otherwise p is untouched
     void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
-                      Geom::Point &p,
-                      bool first_point = true,
-                      Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+                                                       Geom::Point &p,
+                                                       Inkscape::SnapSourceType const source_type,
+                                                       bool first_point = true,
+                                                       Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+
 
     Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type,
-                                    Geom::Point const &p,
-                                    bool first_point = true,
+                                                                       Geom::Point const &p,
+                                                           Inkscape::SnapSourceType const &source_type,
+                                       bool first_point = true,
                                     Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const;
 
     Geom::Point multipleOfGridPitch(Geom::Point const &t) const;
 
     // constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a
-    // point, by overwriting p, if snapping has occured; otherwise p is untouched
+    // point, by overwriting p, if snapping has occurred; otherwise p is untouched
     void constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
-                             Geom::Point &p,
-                             Inkscape::Snapper::ConstraintLine const &constraint,
-                             bool first_point = true,
-                             Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+                                                                       Geom::Point &p,
+                                                                       Inkscape::SnapSourceType const source_type,
+                                                                       Inkscape::Snapper::ConstraintLine const &constraint,
+                                                                       bool first_point = true,
+                                                                       Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
     Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
-                                           Geom::Point const &p,
-                                           Inkscape::Snapper::ConstraintLine const &constraint,
+                                                                                  Geom::Point const &p,
+                                                                                  Inkscape::SnapSourceType const &source_type,
+                                                                                  Inkscape::Snapper::ConstraintLine const &constraint,
                                            bool first_point = true,
                                            Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
     void guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const;
 
     Inkscape::SnappedPoint freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                               std::vector<Geom::Point> const &p,
+                                               std::vector<std::pair<Geom::Point, int> > const &p,
                                                Geom::Point const &pointer,
                                                Geom::Point const &tr) const;
 
     Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
-                                                      std::vector<Geom::Point> const &p,
+                                                      std::vector<std::pair<Geom::Point, int> > const &p,
                                                       Geom::Point const &pointer,
                                                       Inkscape::Snapper::ConstraintLine const &constraint,
                                                       Geom::Point const &tr) const;
 
     Inkscape::SnappedPoint freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                         std::vector<Geom::Point> const &p,
+                                         std::vector<std::pair<Geom::Point, int> > const &p,
                                          Geom::Point const &pointer,
                                          Geom::Scale const &s,
                                          Geom::Point const &o) const;
 
     Inkscape::SnappedPoint constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
-                                                std::vector<Geom::Point> const &p,
+                                                std::vector<std::pair<Geom::Point, int> > const &p,
                                                 Geom::Point const &pointer,
                                                 Geom::Scale const &s,
                                                 Geom::Point const &o) const;
 
     Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
-                                                  std::vector<Geom::Point> const &p,
+                                                  std::vector<std::pair<Geom::Point, int> > const &p,
                                                   Geom::Point const &pointer,
                                                   Geom::Coord const &s,
                                                   Geom::Point const &o,
@@ -121,7 +126,7 @@ public:
                                                   bool uniform) const;
 
     Inkscape::SnappedPoint constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
-                                               std::vector<Geom::Point> const &p,
+                                               std::vector<std::pair<Geom::Point, int> > const &p,
                                                Geom::Point const &pointer,
                                                Inkscape::Snapper::ConstraintLine const &constraint,
                                                Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor
@@ -149,10 +154,10 @@ private:
     SPItem const *_item_to_ignore;
     SPDesktop const *_desktop;
     bool _snapindicator;
-    std::vector<Geom::Point> *_unselected_nodes;
+    std::vector<std::pair<Geom::Point, int> > *_unselected_nodes;
 
     Inkscape::SnappedPoint _snapTransformed(Inkscape::SnapPreferences::PointType type,
-                                            std::vector<Geom::Point> const &points,
+                                            std::vector<std::pair<Geom::Point, int> > const &points,
                                             Geom::Point const &pointer,
                                             bool constrained,
                                             Inkscape::Snapper::ConstraintLine const &constraint,
@@ -162,16 +167,16 @@ private:
                                             Geom::Dim2 dim,
                                             bool uniform) const;
 
-    Geom::Point _transformPoint(Geom::Point const &p,
+    Geom::Point _transformPoint(std::pair<Geom::Point, int> const &p,
                                             Transformation const transformation_type,
                                             Geom::Point const &transformation,
                                             Geom::Point const &origin,
                                             Geom::Dim2 const dim,
                                             bool const uniform) const;
 
-    void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const;
+    void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const;
 
-    Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const;
+    Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained) const;
 };
 
 #endif /* !SEEN_SNAP_H */
index 34cc4dad2a15a0c45d6896bba7a0368c0174406e..e66b44401fca7d8717d61d4e0e1e3a68077e17e6 100644 (file)
@@ -14,7 +14,7 @@
 #include <2geom/path-intersection.h>
 #include <libnr/nr-convert2geom.h>
 
-Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target)
+Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target)
 {
     _distance = snapped_distance;
     _tolerance = std::max(snapped_tolerance, 1.0);
@@ -26,6 +26,7 @@ Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coo
     _point = snapped_point;
     _at_intersection = false;
     _fully_constrained = fully_constrained;
+    _source = source;
     _target = target;
 }
 
@@ -41,6 +42,7 @@ Inkscape::SnappedCurve::SnappedCurve()
     _point = Geom::Point(0,0);
     _at_intersection = false;
     _fully_constrained = false;
+    _source = SNAPSOURCE_UNDEFINED;
     _target = SNAPTARGET_UNDEFINED;
 }
 
@@ -83,12 +85,12 @@ Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &cur
         // TODO: Investigate whether it is possible to use document coordinates everywhere
         // in the snapper code. Only the mouse position should be in desktop coordinates, I guess.
         // All paths are already in document coords and we are certainly not going to change THAT.
-        return SnappedPoint(best_p, Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
+        return SnappedPoint(best_p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
                 secondaryDist, secondaryC->getTolerance(), secondaryC->getAlwaysSnap());
     }
 
     // No intersection
-    return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+    return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
 }
 
 // search for the closest snapped line
index d3dcd023813b16e4ddfaba69e953b34e65da92da..60f5fa0d98329fdad3566616425bb57df310bc4e 100644 (file)
@@ -27,7 +27,7 @@ class SnappedCurve : public SnappedPoint
 {
 public:
     SnappedCurve();
-    SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target);
+    SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target);
     ~SnappedCurve();
     Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve
 
index 5f7d5407b5e9e8f2afdcecb77b6de4d245087380..70689367339c4e141e846fd65a1349a1ab7f89b0 100644 (file)
 #include <2geom/geom.h>
 #include "libnr/nr-values.h"
 
-Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
+Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
     : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line)
 {
     _point = snapped_point;
+    _source = source;
+       _target = target;
     _distance = snapped_distance;
     _tolerance = std::max(snapped_tolerance, 1.0);
     _always_snap = always_snap;
@@ -30,6 +32,8 @@ Inkscape::SnappedLineSegment::SnappedLineSegment()
     _start_point_of_line = Geom::Point(0,0);
     _end_point_of_line = Geom::Point(0,0);
     _point = Geom::Point(0,0);
+    _source = SNAPSOURCE_UNDEFINED;
+       _target = SNAPTARGET_UNDEFINED;
     _distance = NR_HUGE;
     _tolerance = 1;
     _always_snap = false;
@@ -69,20 +73,22 @@ Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegmen
         Inkscape::SnappedLineSegment const *secondarySLS = use_this_as_primary ? &line : this;
         Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
         Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
-        return SnappedPoint(intersection, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
+        return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
                                           secondaryDist, secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap());
     }
 
     // No intersection
-    return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+    return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
 };
 
 
 
-Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line)
+Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line)
     : _normal_to_line(normal_to_line), _point_on_line(point_on_line)
 {
-    _distance = snapped_distance;
+       _source = source;
+       _target = target;
+       _distance = snapped_distance;
     _tolerance = std::max(snapped_tolerance, 1.0);
     _always_snap = always_snap;
     _second_distance = NR_HUGE;
@@ -96,6 +102,8 @@ Inkscape::SnappedLine::SnappedLine()
 {
     _normal_to_line = Geom::Point(0,0);
     _point_on_line = Geom::Point(0,0);
+    _source = SNAPSOURCE_UNDEFINED;
+       _target = SNAPTARGET_UNDEFINED;
     _distance = NR_HUGE;
     _tolerance = 1;
     _always_snap = false;
@@ -137,14 +145,14 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line)
         Inkscape::SnappedLine const *secondarySL = use_this_as_primary ? &line : this;
         Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
         Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
-        return SnappedPoint(intersection, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
+        return SnappedPoint(intersection, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
                                           secondaryDist, secondarySL->getTolerance(), secondarySL->getAlwaysSnap());
         // The type of the snap target is yet undefined, as we cannot tell whether
         // we're snapping to grid or the guide lines; must be set by on a higher level
     }
 
     // No intersection
-    return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+    return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
 }
 
 // search for the closest snapped line segment
index ea18baefc5e98201cfa22216efdcbdc84c1a579b..3d666831107f311e9367aa47e1989bed2c809fb9 100644 (file)
@@ -26,13 +26,13 @@ class SnappedLineSegment : public SnappedPoint
 {
 public:
     SnappedLineSegment();
-    SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line);
+    SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance,bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line);
     ~SnappedLineSegment();
     Inkscape::SnappedPoint intersect(SnappedLineSegment const &line) const; //intersect with another SnappedLineSegment
-    
+
 private:
     Geom::Point _start_point_of_line;
-    Geom::Point _end_point_of_line;    
+    Geom::Point _end_point_of_line;
 };
 
 
@@ -41,7 +41,7 @@ class SnappedLine : public SnappedPoint
 {
 public:
     SnappedLine();
-    SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line);
+    SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line);
     ~SnappedLine();
     Inkscape::SnappedPoint intersect(SnappedLine const &line) const; //intersect with another SnappedLine
     // This line is described by this equation:
@@ -49,10 +49,10 @@ public:
     Geom::Point getNormal() const {return _normal_to_line;}                             // n = (nx, ny)
     Geom::Point getPointOnLine() const {return _point_on_line;}                         // p = (px, py)
     Geom::Coord getConstTerm() const {return dot(_normal_to_line, _point_on_line);}     // c = n.p = nx*px + ny*py;
-    
+
 private:
     Geom::Point _normal_to_line;
-    Geom::Point _point_on_line;    
+    Geom::Point _point_on_line;
 };
 
 }
@@ -62,7 +62,7 @@ bool getClosestIntersectionSLS(std::list<Inkscape::SnappedLineSegment> const &li
 bool getClosestSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedLine &result);
 bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedPoint &result);
 bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list1, std::list<Inkscape::SnappedLine> const &list2, Inkscape::SnappedPoint &result);
+
 
 #endif /* !SEEN_SNAPPEDLINE_H */
 
index 44b69050ff99a2ab7739e6599c950969380a0706..d7f13d82fa298ae6fa0d91b75a34bb7edbc4229d 100644 (file)
@@ -14,8 +14,8 @@
 #include "preferences.h"
 
 // overloaded constructor
-Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
-    : _point(p), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
+    : _point(p), _source(source), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
 {
     // tolerance should never be smaller than 1 px, as it is used for normalization in isOtherSnapBetter. We don't want a division by zero.
     _at_intersection = false;
@@ -27,8 +27,8 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const
     _pointer_distance = NR_HUGE;
 }
 
-Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2)
-    : _point(p), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a),
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2)
+    : _point(p), _source(source), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a),
     _second_distance(d2), _second_tolerance(std::max(t2,1.0)), _second_always_snap(a2)
 {
     // tolerance should never be smaller than 1 px, as it is used for normalization in
@@ -40,6 +40,7 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const
 Inkscape::SnappedPoint::SnappedPoint()
 {
     _point = Geom::Point(0,0);
+    _source = SNAPSOURCE_UNDEFINED,
     _target = SNAPTARGET_UNDEFINED,
     _at_intersection = false;
     _fully_constrained = false;
index 7085ccae8f6d0d09c12d5ab6dc118577ec3b242e..f8ef50ff361f873f92c44c6f2ef7986bba62a985 100644 (file)
@@ -22,29 +22,57 @@ namespace Inkscape
 {
 
 enum SnapTargetType {
-    SNAPTARGET_UNDEFINED,
+    SNAPTARGET_UNDEFINED = 0,
     SNAPTARGET_GRID,
     SNAPTARGET_GRID_INTERSECTION,
     SNAPTARGET_GUIDE,
     SNAPTARGET_GUIDE_INTERSECTION,
     SNAPTARGET_GRID_GUIDE_INTERSECTION,
-    SNAPTARGET_NODE,
+    SNAPTARGET_NODE_SMOOTH,
+    SNAPTARGET_NODE_CUSP,
+    SNAPTARGET_LINE_MIDPOINT,
+    SNAPTARGET_OBJECT_MIDPOINT,
+    SNAPTARGET_ROTATION_CENTER,
+    SNAPTARGET_HANDLE, //e.g. center of ellipse, corner of rectangle
     SNAPTARGET_PATH,
     SNAPTARGET_PATH_INTERSECTION,
     SNAPTARGET_BBOX_CORNER,
     SNAPTARGET_BBOX_EDGE,
+    SNAPTARGET_BBOX_EDGE_MIDPOINT,
+    SNAPTARGET_BBOX_MIDPOINT,
     SNAPTARGET_GRADIENT,
-    SNAPTARGET_PAGE_BORDER
+    SNAPTARGET_PAGE_BORDER,
+    SNAPTARGET_PAGE_CORNER,
+    SNAPTARGET_CONVEX_HULL_CORNER,
+    SNAPTARGET_ELLIPSE_QUADRANT_POINT,
 };
 
+enum SnapSourceType {
+    SNAPSOURCE_UNDEFINED = 0,
+    SNAPSOURCE_BBOX_CORNER,
+    SNAPSOURCE_BBOX_MIDPOINT,
+    SNAPSOURCE_BBOX_EDGE_MIDPOINT,
+    SNAPSOURCE_NODE_SMOOTH,
+    SNAPSOURCE_NODE_CUSP,
+    SNAPSOURCE_LINE_MIDPOINT,
+    SNAPSOURCE_OBJECT_MIDPOINT,
+    SNAPSOURCE_ROTATION_CENTER,
+    SNAPSOURCE_HANDLE,
+    SNAPSOURCE_PATH_INTERSECTION,
+    SNAPSOURCE_GUIDE,
+    SNAPSOURCE_CONVEX_HULL_CORNER,
+    SNAPSOURCE_ELLIPSE_QUADRANT_POINT
+};
+
+
 /// Class describing the result of an attempt to snap.
 class SnappedPoint
 {
 
 public:
     SnappedPoint();
-    SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2);
-    SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
+    SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2);
+    SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
     ~SnappedPoint();
 
     Geom::Coord getSnapDistance() const {return _distance;}
@@ -79,11 +107,14 @@ public:
     void setTransformation(Geom::Point const t) {_transformation = t;}
     void setTarget(SnapTargetType const target) {_target = target;}
     SnapTargetType getTarget() const {return _target;}
+    void setSource(SnapSourceType const source) {_source = source;}
+       SnapSourceType getSource() const {return _source;}
 
     bool isOtherSnapBetter(SnappedPoint const &other_one, bool weighted) const;
 
     /*void dump() const {
         std::cout << "_point              = " << _point << std::endl;
+        std::cout << "_source             = " << _source << std::endl;
         std::cout << "_target             = " << _target << std::endl;
         std::cout << "_at_intersection    = " << _at_intersection << std::endl;
         std::cout << "_fully_constrained  = " << _fully_constrained << std::endl;
@@ -99,6 +130,7 @@ public:
 
 protected:
     Geom::Point _point; // Location of the snapped point
+    SnapSourceType _source; // Describes what snapped
     SnapTargetType _target; // Describes to what we've snapped to
     bool _at_intersection; // If true, the snapped point is at an intersection
     bool _fully_constrained; // When snapping for example to a node, then the snap will be "fully constrained".
index 49f2774113d8062ee5afe6942e3f38d6fc8b2847..08b10e41b30676f6ca390bd57ae898cab09902e6 100644 (file)
@@ -59,10 +59,11 @@ public:
     virtual void freeSnap(SnappedConstraints &/*sc*/,
                           SnapPreferences::PointType const &/*t*/,
                           Geom::Point const &/*p*/,
+                          SnapSourceType const &/*source_type*/,
                           bool const &/*first_point*/,
                           Geom::OptRect const &/*bbox_to_snap*/,
                           std::vector<SPItem const *> const */*it*/,
-                          std::vector<Geom::Point> */*unselected_nodes*/) const {};
+                          std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const {};
 
     class ConstraintLine
     {
@@ -97,6 +98,7 @@ public:
     virtual void constrainedSnap(SnappedConstraints &/*sc*/,
                                                         SnapPreferences::PointType const &/*t*/,
                                  Geom::Point const &/*p*/,
+                                 SnapSourceType const &/*source_type*/,
                                  bool const &/*first_point*/,
                                  Geom::OptRect const &/*bbox_to_snap*/,
                                  ConstraintLine const &/*c*/,
index ce1343272f9612da961c4b25c1f7ae26998521c7..97656375428a9f4eef0251254888b93cc9f322c9 100644 (file)
@@ -72,7 +72,7 @@ static void sp_genericellipse_init(SPGenericEllipse *ellipse);
 
 static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags);
 
-static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_genericellipse_set_shape(SPShape *shape);
 static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -260,7 +260,7 @@ static void sp_genericellipse_set_shape(SPShape *shape)
     curve->unref();
 }
 
-static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_GENERICELLIPSE(item));
@@ -290,31 +290,37 @@ static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, I
     double cx = ellipse->cx.computed;
     double cy = ellipse->cy.computed;
 
+    Geom::Point pt;
+
     // Snap to the 4 quadrant points of the ellipse, but only if the arc
     // spans far enough to include them
     if (snapprefs->getSnapToItemNode()) { //TODO: Make a separate snap option toggle for this?
                double angle = 0;
                for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
                        if (angle >= ellipse->start && angle <= ellipse->end) {
-                               *p = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+                               pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+                               p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT) : int(Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT)));
                        }
                }
     }
 
     // Add the centre, if we have a closed slice or when explicitly asked for
     if ((snapprefs->getSnapToItemNode() && slice && ellipse->closed) || snapprefs->getSnapObjectMidpoints()) {
-       *p = Geom::Point(cx, cy) * i2d;
+       pt = Geom::Point(cx, cy) * i2d;
+       p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE)));
     }
 
     // And if we have a slice, also snap to the endpoints
     if (snapprefs->getSnapToItemNode() && slice) {
         // Add the start point, if it's not coincident with a quadrant point
         if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
-            *p = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
+            pt = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
+            p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
         }
         // Add the end point, if it's not coincident with a quadrant point
         if (fmod(ellipse->end, M_PI_2) != 0.0 ) {
-            *p = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
+            pt = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
+            p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
         }
     }
 }
index 75be3bea2cb951f3c9702d69b5590ef631ebf7ad..e23dddaf629b25ff348b1ed5b37d77db0e3ead14 100644 (file)
@@ -76,7 +76,7 @@ static Inkscape::XML::Node *sp_image_write (SPObject *object, Inkscape::XML::Doc
 static void sp_image_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
 static void sp_image_print (SPItem * item, SPPrintContext *ctx);
 static gchar * sp_image_description (SPItem * item);
-static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static Geom::Matrix sp_image_set_transform (SPItem *item, Geom::Matrix const &xform);
 static void sp_image_set_curve(SPImage *image);
@@ -1305,7 +1305,7 @@ sp_image_update_canvas_image (SPImage *image)
     }
 }
 
-static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     /* An image doesn't have any nodes to snap, but still we want to be able snap one image
     to another. Therefore we will create some snappoints at the corner, similar to a rect. If
@@ -1327,10 +1327,12 @@ static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
         double const x1 = x0 + image.width.computed;
         double const y1 = y0 + image.height.computed;
         Geom::Matrix const i2d (sp_item_i2d_affine (item));
-        *p = Geom::Point(x0, y0) * i2d;
-        *p = Geom::Point(x0, y1) * i2d;
-        *p = Geom::Point(x1, y1) * i2d;
-        *p = Geom::Point(x1, y0) * i2d;
+        Geom::Point pt;
+        int type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+        p.push_back(std::make_pair(Geom::Point(x0, y0) * i2d, type));
+        p.push_back(std::make_pair(Geom::Point(x0, y1) * i2d, type));
+        p.push_back(std::make_pair(Geom::Point(x1, y1) * i2d, type));
+        p.push_back(std::make_pair(Geom::Point(x1, y0) * i2d, type));
     }
 }
 
index 862a36cb065888c7ba178fe561be9375ebf2e459..ed5382fae3cc9389ac5366984d90968442ab098b 100644 (file)
@@ -68,7 +68,7 @@ static gchar * sp_group_description (SPItem * item);
 static Geom::Matrix sp_group_set_transform(SPItem *item, Geom::Matrix const &xform);
 static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static void sp_group_hide (SPItem * item, unsigned int key);
-static void sp_group_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_group_update_patheffect(SPLPEItem *lpeitem, bool write);
 static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup);
@@ -338,14 +338,14 @@ sp_group_hide (SPItem *item, unsigned int key)
     SP_GROUP(item)->group->hide(key);
 }
 
-static void sp_group_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     for (SPObject const *o = sp_object_first_child(SP_OBJECT(item));
          o != NULL;
          o = SP_OBJECT_NEXT(o))
     {
         if (SP_IS_ITEM(o)) {
-            sp_item_snappoints(SP_ITEM(o), p, snapprefs);
+            sp_item_snappoints(SP_ITEM(o), target, p, snapprefs);
         }
     }
 }
index 5cc1692216de354f596a490c686bbe9a20a96420..0bc08a2355d84f9ad0fb5143b3b0ce8fb7ddd226 100644 (file)
@@ -24,11 +24,11 @@ void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoin
     double const dir_lensq(dot(dir, dir));
     g_return_if_fail( dir_lensq != 0 );
 
-    std::vector<Geom::Point> snappoints;
-    sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+    SnapPointsWithType snappoints;
+    sp_item_snappoints(&item, false, snappoints, NULL);
     g_return_if_fail( snappoint_ix < int(snappoints.size()) );
 
-    double const pos0 = dot(dir, snappoints[snappoint_ix]);
+    double const pos0 = dot(dir, snappoints[snappoint_ix].first);
     /// \todo effic: skip if mv_g is already satisfied.
 
     /* Translate along dir to make dot(dir, snappoints(item)[snappoint_ix]) == position. */
index 6d7ab2fda8937880b8e013ce5071450fcddc5c7d..2464532413d2a32cf687267fe0471d53b4df05f4 100644 (file)
@@ -14,14 +14,14 @@ void sp_item_rm_unsatisfied_cns(SPItem &item)
     if (item.constraints.empty()) {
         return;
     }
-    std::vector<Geom::Point> snappoints;
-    sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+    SnapPointsWithType snappoints;
+    sp_item_snappoints(&item, false, snappoints, NULL);
     for (unsigned i = item.constraints.size(); i--;) {
         g_assert( i < item.constraints.size() );
         SPGuideConstraint const &cn = item.constraints[i];
         int const snappoint_ix = cn.snappoint_ix;
         g_assert( snappoint_ix < int(snappoints.size()) );
-        if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix]), 0) ) {
+        if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix].first), 0) ) {
             remove_last(cn.g->attached_items, SPGuideAttachment(&item, cn.snappoint_ix));
             g_assert( i < item.constraints.size() );
             vector<SPGuideConstraint>::iterator const ei(&item.constraints[i]);
index f7329bd45a2096907bba6349b653cbb92e1c734f..bebd6502199dab5b9939e014c976d9191a079875 100644 (file)
@@ -9,8 +9,8 @@ using std::vector;
 
 void sp_item_update_cns(SPItem &item, SPDesktop const &desktop)
 {
-    std::vector<Geom::Point> snappoints;
-    sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+    SnapPointsWithType snappoints;
+    sp_item_snappoints(&item, false, snappoints, NULL);
     /* TODO: Implement the ordering. */
     vector<SPGuideConstraint> found_cns;
     satisfied_guide_cns(desktop, snappoints, found_cns);
index 2ac480341a4ef469a9194ed439bff6f249a517ea..996804cd3a5c4001c1df381da035fb8ce686f194 100644 (file)
@@ -90,7 +90,7 @@ static void sp_item_update(SPObject *object, SPCtx *ctx, guint flags);
 static Inkscape::XML::Node *sp_item_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
 
 static gchar *sp_item_private_description(SPItem *item);
-static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem);
 static SPItemView *sp_item_view_list_remove(SPItemView *list, SPItemView *view);
@@ -939,7 +939,7 @@ Geom::OptRect sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type)
     return rect;
 }
 
-static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     /* This will only be called if the derived class doesn't override this.
      * see for example sp_genericellipse_snappoints in sp-ellipse.cpp
@@ -952,15 +952,16 @@ static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Ink
         Geom::Point p1, p2;
         p1 = bbox->min();
         p2 = bbox->max();
-        *p = p1;
-        *p = Geom::Point(p1[Geom::X], p2[Geom::Y]);
-        *p = p2;
-        *p = Geom::Point(p1[Geom::Y], p2[Geom::X]);
+        int type = target ? int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER) : int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER);
+        p.push_back(std::make_pair(p1, type));
+        p.push_back(std::make_pair(Geom::Point(p1[Geom::X], p2[Geom::Y]), type));
+        p.push_back(std::make_pair(p2, type));
+        p.push_back(std::make_pair(Geom::Point(p1[Geom::Y], p2[Geom::X]), type));
     }
 
 }
 
-void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert (item != NULL);
     g_assert (SP_IS_ITEM(item));
@@ -968,12 +969,12 @@ void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPref
     // Get the snappoints of the item
     SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(item);
     if (item_class.snappoints) {
-        item_class.snappoints(item, p, snapprefs);
+        item_class.snappoints(item, target, p, snapprefs);
     }
 
     // Get the snappoints at the item's center
     if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-       *p = item->getCenter();
+       p.push_back(std::make_pair(item->getCenter(), target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT)));
     }
 
     // Get the snappoints of clipping paths and mask, if any
@@ -988,14 +989,15 @@ void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPref
             // obj is a group object, the children are the actual clippers
             for (SPObject *child = (*o)->children ; child ; child = child->next) {
                 if (SP_IS_ITEM(child)) {
-                    std::vector<Geom::Point> p_clip_or_mask;
+                       SnapPointsWithType p_clip_or_mask;
                     // Please note the recursive call here!
-                    sp_item_snappoints(SP_ITEM(child), SnapPointsIter(p_clip_or_mask), snapprefs);
+                    sp_item_snappoints(SP_ITEM(child), target, p_clip_or_mask, snapprefs);
                     // Take into account the transformation of the item being clipped or masked
-                    for (std::vector<Geom::Point>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
+                    for (SnapPointsWithType::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
                         // All snappoints are in desktop coordinates, but the item's transformation is
                         // in document coordinates. Hence the awkward construction below
-                        *p = desktop->dt2doc(*p_orig) * sp_item_i2d_affine(item);
+                        Geom::Point pt = desktop->dt2doc((*p_orig).first) * sp_item_i2d_affine(item);
+                        p.push_back(std::make_pair(pt, (*p_orig).second));
                     }
                 }
             }
index d95fc2486f1b28ce9cce49c54e3fab5e66ef6e1c..639a1b4a2a18d1d0c601cc41706281ce25d9a04d 100644 (file)
@@ -26,6 +26,7 @@
 #include <2geom/forward.h>
 #include <libnr/nr-convert2geom.h>
 #include <snap-preferences.h>
+#include <snapped-point.h>
 
 class SPGuideConstraint;
 struct SPClipPathReference;
@@ -33,7 +34,7 @@ struct SPMaskReference;
 struct SPAvoidRef;
 struct SPPrintContext;
 namespace Inkscape { class URIReference; }
+
 enum {
     SP_EVENT_INVALID,
     SP_EVENT_NONE,
@@ -72,7 +73,7 @@ struct SPItemView {
 #define SP_ITEM_SHOW_DISPLAY (1 << 0)
 
 /**
- * Flag for referenced views (i.e. markers, clippaths, masks and patterns); 
+ * Flag for referenced views (i.e. markers, clippaths, masks and patterns);
    currently unused, does the same as DISPLAY
  */
 #define SP_ITEM_REFERENCE_FLAGS (1 << 1)
@@ -92,7 +93,7 @@ struct SPItemCtx {
 struct SPItem : public SPObject {
     enum BBoxType {
         // legacy behavior: includes crude stroke, markers; excludes long miters, blur margin; is known to be wrong for caps
-        APPROXIMATE_BBOX, 
+        APPROXIMATE_BBOX,
         // includes only the bare path bbox, no stroke, no nothing
         GEOMETRIC_BBOX,
         // includes everything: correctly done stroke (with proper miters and caps), markers, filter margins (e.g. blur)
@@ -105,34 +106,34 @@ struct SPItem : public SPObject {
     double transform_center_y;
 
     Geom::Matrix transform;
-    
+
     SPClipPathReference *clip_ref;
     SPMaskReference *mask_ref;
-    
+
     // Used for object-avoiding connectors
     SPAvoidRef *avoidRef;
-    
+
     SPItemView *display;
-    
+
     std::vector<SPGuideConstraint> constraints;
-    
+
     sigc::signal<void, Geom::Matrix const *, SPItem *> _transformed_signal;
 
-    void init();    
+    void init();
     bool isLocked() const;
     void setLocked(bool lock);
-    
+
     bool isHidden() const;
     void setHidden(bool hidden);
 
     bool isEvaluated() const;
     void setEvaluated(bool visible);
     void resetEvaluated();
-    
+
     bool isHidden(unsigned display_key) const;
-    
+
     bool isExplicitlyHidden() const;
-    
+
     void setExplicitlyHidden(bool val);
 
     void setCenter(Geom::Point object_centre);
@@ -141,11 +142,11 @@ struct SPItem : public SPObject {
     Geom::Point getCenter() const;
 
     bool isVisibleAndUnlocked() const;
-    
+
     bool isVisibleAndUnlocked(unsigned display_key) const;
-    
+
     Geom::Matrix getRelativeTransform(SPObject const *obj) const;
-    
+
     void raiseOne();
     void lowerOne();
     void raiseToTop();
@@ -170,7 +171,7 @@ private:
     mutable EvaluatedStatus _evaluated_status;
 };
 
-typedef std::back_insert_iterator<std::vector<Geom::Point> > SnapPointsIter;
+typedef std::vector<std::pair<Geom::Point, int> > SnapPointsWithType; // int is either of these enums: Inkscape::SnapTargetType or Inkscape::SnapSourceType
 
 /// The SPItem vtable.
 struct SPItemClass {
@@ -178,28 +179,28 @@ struct SPItemClass {
 
     /** BBox union in given coordinate system */
     void (* bbox) (SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
-    
+
     /** Printing method. Assumes ctm is set to item affine matrix */
     /* \todo Think about it, and maybe implement generic export method instead (Lauris) */
     void (* print) (SPItem *item, SPPrintContext *ctx);
-    
+
     /** Give short description of item (for status display) */
     gchar * (* description) (SPItem * item);
-    
+
     NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
     void (* hide) (SPItem *item, unsigned int key);
-    
+
     /** Write to an iterator the points that should be considered for snapping
      * as the item's `nodes'.
      */
-    void (* snappoints) (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
-    
+    void (* snappoints) (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+
     /** Apply the transform optimally, and return any residual transformation */
     Geom::Matrix (* set_transform)(SPItem *item, Geom::Matrix const &transform);
 
     /** Convert the item to guidelines */
     void (* convert_to_guides)(SPItem *item);
-    
+
     /** Emit event, if applicable */
     gint (* event) (SPItem *item, SPEvent *event);
 };
@@ -225,7 +226,7 @@ unsigned int sp_item_display_key_new(unsigned int numkeys);
 NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 void sp_item_invoke_hide(SPItem *item, unsigned int key);
 
-void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 void sp_item_adjust_pattern(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
 void sp_item_adjust_gradient(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
index 39b8227a4384cb68cab7508135de9263b97c66bc..ae0f7bf19ea48bebe09cc7ccf91f12f6958aff74 100644 (file)
@@ -83,7 +83,7 @@ static void sp_offset_update (SPObject * object, SPCtx * ctx, guint flags);
 static void sp_offset_release (SPObject * object);
 
 static gchar *sp_offset_description (SPItem * item);
-static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 static void sp_offset_set_shape (SPShape * shape);
 
 static void refresh_offset_source(SPOffset* offset);
@@ -718,10 +718,10 @@ sp_offset_set_shape(SPShape *shape)
 /**
  * Virtual snappoints function.
  */
-static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     if (((SPItemClass *) parent_class)->snappoints) {
-        ((SPItemClass *) parent_class)->snappoints (item, p, snapprefs);
+        ((SPItemClass *) parent_class)->snappoints (item, target, p, snapprefs);
     }
 }
 
index c88b9eb38df0899f11d88a972de5f35f64e53f3a..4f8dbbbce6ad733923b56a90490dae8d2530948e 100644 (file)
@@ -45,7 +45,7 @@ static Geom::Matrix sp_rect_set_transform(SPItem *item, Geom::Matrix const &xfor
 static void sp_rect_convert_to_guides(SPItem *item);
 
 static void sp_rect_set_shape(SPShape *shape);
-static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static SPShapeClass *parent_class;
 
@@ -543,7 +543,7 @@ sp_rect_get_visible_height(SPRect *rect)
 /**
  * Sets the snappoint p to the unrounded corners of the rectangle
  */
-static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     /* This method overrides sp_shape_snappoints, which is the default for any shape. The default method
     returns all eight points along the path of a rounded rectangle, but not the real corners. Snapping
@@ -569,22 +569,27 @@ static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
     Geom::Point p2 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d;
     Geom::Point p3 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
 
+    int type;
+
     if (snapprefs->getSnapToItemNode()) {
-               *p = p0;
-               *p = p1;
-               *p = p2;
-               *p = p3;
+       type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+       p.push_back(std::make_pair(p0, type));
+       p.push_back(std::make_pair(p1, type));
+       p.push_back(std::make_pair(p2, type));
+       p.push_back(std::make_pair(p3, type));
     }
 
        if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
-               *p = (p0 + p1)/2;
-               *p = (p1 + p2)/2;
-               *p = (p2 + p3)/2;
-               *p = (p3 + p0)/2;
+               type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
+               p.push_back(std::make_pair((p0 + p1)/2, type));
+               p.push_back(std::make_pair((p1 + p2)/2, type));
+               p.push_back(std::make_pair((p2 + p3)/2, type));
+               p.push_back(std::make_pair((p3 + p0)/2, type));
        }
 
        if (snapprefs->getSnapObjectMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
-               *p = (p0 + p2)/2;
+               type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+               p.push_back(std::make_pair((p0 + p2)/2, type));
        }
 
 }
index 178ca89a8b210c93a529f8a75720e4170109a745..7b4663908e84cf532ffc6a9fd07167ed4f769e8a 100644 (file)
@@ -68,7 +68,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &
 void sp_shape_print (SPItem * item, SPPrintContext * ctx);
 static NRArenaItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
 static void sp_shape_hide (SPItem *item, unsigned int key);
-static void sp_shape_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_shape_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai);
 
@@ -1057,7 +1057,7 @@ sp_shape_set_curve_insync (SPShape *shape, SPCurve *curve, unsigned int owner)
 /**
  * Return all nodes in a path that are to be considered for snapping
  */
-static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_SHAPE(item));
@@ -1078,16 +1078,20 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
 
     Geom::Matrix const i2d (sp_item_i2d_affine (item));
 
+    int type;
+
        if (snapprefs->getSnapObjectMidpoints()) {
                Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item));
                if (bbox) {
-                       *p = bbox->midpoint();
+                       type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+                       p.push_back(std::make_pair(bbox->midpoint(), type));
                }
        }
 
     for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
         if (snapprefs->getSnapToItemNode()) {
-               *p = path_it->initialPoint() * i2d;
+               type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
+               p.push_back(std::make_pair(path_it->initialPoint() * i2d, type));
         }
 
         Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
@@ -1106,13 +1110,15 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
             bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
 
             if (c1 || c2) {
-                               *p = curve_it1->finalPoint() * i2d;
+               type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
+                               p.push_back(std::make_pair(curve_it1->finalPoint() * i2d, type));
             }
 
                        // Consider midpoints of line segments for snapping
                        if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
                                if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
-                                       *p = Geom::middle_point(*line_segment) * i2d;
+                                       type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
+                                       p.push_back(std::make_pair(Geom::middle_point(*line_segment) * i2d, type));
                                }
                        }
 
@@ -1128,7 +1134,8 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
             if (cs.size() > 0) { // There might be multiple intersections...
                 for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); i++) {
                     Geom::Point p_ix = (*path_it).pointAt((*i).ta);
-                    *p = p_ix * i2d;
+                    type = target ? int(Inkscape::SNAPTARGET_PATH_INTERSECTION) : int(Inkscape::SNAPSOURCE_PATH_INTERSECTION);
+                    p.push_back(std::make_pair(p_ix * i2d, type));
                 }
             }
         }
index 624c5ae181ad7513a2200cac5e1c79373270043a..872607c275da938770a17b1521edb441899737eb 100644 (file)
@@ -36,7 +36,7 @@ static void sp_spiral_set (SPObject *object, unsigned int key, const gchar *valu
 static void sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags);
 
 static gchar * sp_spiral_description (SPItem * item);
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_spiral_set_shape (SPShape *shape);
 static void sp_spiral_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -503,7 +503,7 @@ sp_spiral_position_set       (SPSpiral          *spiral,
 /**
  * Virtual snappoints callback.
  */
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
        // We will determine the spiral's midpoint ourselves, instead of trusting on the base class
        // Therefore setSnapObjectMidpoints() is set to false temporarily
@@ -511,7 +511,7 @@ static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape:
        local_snapprefs.setSnapObjectMidpoints(false);
 
        if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+               ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
        }
 
        // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
@@ -522,7 +522,8 @@ static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape:
        if (snapprefs->getSnapObjectMidpoints()) {
                Geom::Matrix const i2d (sp_item_i2d_affine (item));
                SPSpiral *spiral = SP_SPIRAL(item);
-               *p = Geom::Point(spiral->cx, spiral->cy) * i2d;
+               int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+               p.push_back(std::make_pair(Geom::Point(spiral->cx, spiral->cy) * i2d, type));
                // This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
                // in the object snapper. In that case we will get a duplicate!
        }
index c1581a6d6d7bc3baa131f52680b1bde2f0d31b00..3c8754a1147ebd148b99fbb6e34c3198ab891edf 100644 (file)
@@ -39,7 +39,7 @@ static void sp_star_set (SPObject *object, unsigned int key, const gchar *value)
 static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags);
 
 static gchar * sp_star_description (SPItem * item);
-static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 
 static void sp_star_set_shape (SPShape *shape);
 static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
@@ -528,7 +528,7 @@ sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1,
        SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
-static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
        // We will determine the star's midpoint ourselves, instead of trusting on the base class
        // Therefore setSnapObjectMidpoints() is set to false temporarily
@@ -536,7 +536,7 @@ static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
        local_snapprefs.setSnapObjectMidpoints(false);
 
        if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+               ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
        }
 
        // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
@@ -546,7 +546,8 @@ static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
 
        if (snapprefs->getSnapObjectMidpoints()) {
                Geom::Matrix const i2d (sp_item_i2d_affine (item));
-               *p = SP_STAR(item)->center * i2d;
+               int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+               p.push_back(std::make_pair(SP_STAR(item)->center * i2d, type));
        }
 }
 
index 8627e179ffbc88dc0fc7d4eb29e2dd98c8429dd6..abfb9ca6582c5b3841ff94c652c8a2fa8bc9a0b8 100644 (file)
@@ -74,7 +74,7 @@ static void sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &t
 static NRArenaItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, unsigned flags);
 static void sp_text_hide (SPItem *item, unsigned key);
 static char *sp_text_description (SPItem *item);
-static void sp_text_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 static Geom::Matrix sp_text_set_transform(SPItem *item, Geom::Matrix const &xform);
 static void sp_text_print (SPItem *item, SPPrintContext *gpc);
 
@@ -428,12 +428,13 @@ sp_text_description(SPItem *item)
     return ret;
 }
 
-static void sp_text_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     // the baseline anchor of the first char
     Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item);
     if(layout != NULL) {
-        *p = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
+        int type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+       p.push_back(std::make_pair(layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item), type));
     }
 }
 
index 36372e67b4f3f8a5a0c7fadb0d98a6e994cb93b9..990407f95deb85b7004b4e8dcaf142a58c107e4e 100644 (file)
@@ -52,7 +52,7 @@ static void sp_use_update(SPObject *object, SPCtx *ctx, guint flags);
 static void sp_use_modified(SPObject *object, guint flags);
 
 static void sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
-static void sp_use_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
 static void sp_use_print(SPItem *item, SPPrintContext *ctx);
 static gchar *sp_use_description(SPItem *item);
 static NRArenaItem *sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags);
@@ -741,19 +741,19 @@ sp_use_get_original(SPUse *use)
 }
 
 static void
-sp_use_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert (item != NULL);
     g_assert (SP_IS_ITEM(item));
     g_assert (SP_IS_USE(item));
-    
+
     SPUse *use = SP_USE(item);
     SPItem *root = sp_use_root(use);
     g_return_if_fail(root);
-    
+
     SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(root);
     if (item_class.snappoints) {
-        item_class.snappoints(root, p, snapprefs);
+        item_class.snappoints(root, target, p, snapprefs);
     }
 }
 
index 35d5144a7881d58f8b67f87321bd848fc10b6fa6..3689ae4af3fbbe9bea974c9b5306786e08fe7d6c 100644 (file)
@@ -227,7 +227,7 @@ sp_spiral_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 SnapManager &m = desktop->namedview->snap_manager;
                 m.setup(desktop);
                 Geom::Point pt2g = to_2geom(sc->center);
-                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
                 sc->center = from_2geom(pt2g);
 
                 sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -258,7 +258,7 @@ sp_spiral_context_root_handler(SPEventContext *event_context, GdkEvent *event)
 
                 SnapManager &m = desktop->namedview->snap_manager;
                 m.setup(desktop, true, sc->item);
-                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt);
+                m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt, Inkscape::SNAPSOURCE_HANDLE);
                 sp_spiral_drag(sc, from_2geom(motion_dt), event->motion.state);
 
                 gobble_motion_events(GDK_BUTTON1_MASK);
@@ -404,7 +404,7 @@ sp_spiral_drag(SPSpiralContext *sc, Geom::Point p, guint state)
     SnapManager &m = desktop->namedview->snap_manager;
     m.setup(desktop, true, sc->item);
     Geom::Point pt2g = to_2geom(p);
-    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
 
     Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
     Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));
index da79d4719a9852ce62e294b91516ac7e919f9750..54c431e2cadc656c1818f62bd3a9b4cfeb297de6 100644 (file)
@@ -243,7 +243,7 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
             SnapManager &m = desktop->namedview->snap_manager;
             m.setup(desktop, true);
             Geom::Point pt2g = to_2geom(sc->center);
-            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+            m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
             sc->center = from_2geom(pt2g);
 
             sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -416,7 +416,7 @@ static void sp_star_drag(SPStarContext *sc, Geom::Point p, guint state)
     SnapManager &m = desktop->namedview->snap_manager;
     m.setup(desktop, true, sc->item);
     Geom::Point pt2g = to_2geom(p);
-    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
 
     Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
     Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));