diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index 9a3708d4b3a55e888fab51479636075ad19b40aa..6297153327939f3b71f5100d4675add5a31ac9ed 100644 (file)
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
#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"
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);
/** \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);
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,
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();
}
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, 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
+ Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+ local_snapprefs.setSnapObjectMidpoints(false);
+
if (((SPItemClass *) parent_class)->snappoints) {
- ((SPItemClass *) parent_class)->snappoints (item, p, 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
+ 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!
}
}