Code

Marking the tests as failing.
[inkscape.git] / src / sp-spiral.cpp
index 7b741a940cb80d9230ce3e6789ad54361895754b..6297153327939f3b71f5100d4675add5a31ac9ed 100644 (file)
@@ -19,7 +19,8 @@
 
 #include "svg/svg.h"
 #include "attributes.h"
-#include "display/bezier-utils.h"
+#include <2geom/bezier-utils.h>
+#include <2geom/pathvector.h>
 #include "display/curve.h"
 #include <glibmm/i18n.h>
 #include "xml/repr.h"
@@ -36,7 +37,7 @@ static void sp_spiral_set (SPObject *object, unsigned int key, const gchar *valu
 static void sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags);
 
 static gchar * sp_spiral_description (SPItem * item);
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p);
+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);
@@ -388,7 +389,7 @@ sp_spiral_fit_and_draw (SPSpiral const *spiral,
        /** \todo
          * We should use better algorithm to specify maximum error.
          */
-       depth = sp_bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE,
+       depth = Geom::bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE,
                                          hat1, hat2,
                                          SPIRAL_TOLERANCE*SPIRAL_TOLERANCE,
                                          FITTING_MAX_BEZIERS);
@@ -418,15 +419,27 @@ sp_spiral_fit_and_draw (SPSpiral const *spiral,
 static void
 sp_spiral_set_shape (SPShape *shape)
 {
+       SPSpiral *spiral = SP_SPIRAL(shape);
+
+    if (sp_lpe_item_has_broken_path_effect(SP_LPE_ITEM(shape))) {
+        g_warning ("The spiral shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as spiral will remove the bad LPE");
+        if (SP_OBJECT_REPR(shape)->attribute("d")) {
+            // unconditionally read the curve from d, if any, to preserve appearance
+            Geom::PathVector pv = sp_svg_read_pathv(SP_OBJECT_REPR(shape)->attribute("d"));
+            SPCurve *cold = new SPCurve(pv);
+            sp_shape_set_curve_insync (shape, cold, TRUE);
+            cold->unref();
+        }
+        return;
+    }
+
        Geom::Point darray[SAMPLE_SIZE + 1];
        double t;
 
-       SPSpiral *spiral = SP_SPIRAL(shape);
-
        SP_OBJECT (spiral)->requestModified(SP_OBJECT_MODIFIED_FLAG);
 
        SPCurve *c = new SPCurve ();
-       
+
 #ifdef SPIRAL_VERBOSE
        g_print ("cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n",
                 spiral->cx,
@@ -455,8 +468,17 @@ sp_spiral_set_shape (SPShape *shape)
                sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0),
                                        darray, hat1, hat2, &t);
 
-    sp_lpe_item_perform_path_effect(SP_LPE_ITEM (spiral), c);
-    sp_shape_set_curve_insync ((SPShape *) spiral, c, TRUE);
+    /* Reset the shape'scurve to the "original_curve"
+     * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
+    sp_shape_set_curve_insync (shape, c, TRUE);
+    if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
+        SPCurve *c_lpe = c->copy();
+        bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
+        if (success) {
+            sp_shape_set_curve_insync (shape, c_lpe, TRUE);
+        }
+        c_lpe->unref();
+    }
     c->unref();
 }
 
@@ -484,20 +506,39 @@ sp_spiral_position_set       (SPSpiral          *spiral,
        spiral->cy         = cy;
        spiral->exp        = exp;
        spiral->revo       = revo;
-       spiral->rad        = MAX (rad, 0.001);
+       spiral->rad        = MAX (rad, 0.0);
        spiral->arg        = arg;
        spiral->t0         = CLAMP(t0, 0.0, 0.999);
-       
+
        ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
 /**
  * Virtual snappoints callback.
  */
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p)
+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
+       Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+       local_snapprefs.setSnapObjectMidpoints(false);
+
        if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, p);
+               ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
+       }
+
+       // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+               return;
+       }
+
+       if (snapprefs->getSnapObjectMidpoints()) {
+               Geom::Matrix const i2d (sp_item_i2d_affine (item));
+               SPSpiral *spiral = SP_SPIRAL(item);
+               int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+               p.push_back(std::make_pair(Geom::Point(spiral->cx, spiral->cy) * i2d, type));
+               // This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
+               // in the object snapper. In that case we will get a duplicate!
        }
 }