diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index ffbec8a8b945bb4baabeaa0f95653bc30c3cc1d0..b712539ab767f78f872a3fb550c54095ae7f1f9f 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
#include <cstring>
#include <string>
#include "live_effects/lpeobject.h"
+#include "live_effects/effect.h"
#include "live_effects/parameter/parameter.h"
#include "util/mathfns.h"
#include "display/snap-indicator.h"
/* Creation from object */
-static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t);
+static NArtBpath const * subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath const *b, gchar const *t);
static gchar *parse_nodetypes(gchar const *types, gint length);
/* Object updating */
@@ -151,6 +152,20 @@ static void sp_nodepath_set_curve (Inkscape::NodePath::Path *np, SPCurve *curve)
// active_node indicates mouseover node
Inkscape::NodePath::Node * Inkscape::NodePath::Path::active_node = NULL;
+static void sp_nodepath_draw_helper_curve(Inkscape::NodePath::Path *np, SPDesktop *desktop) {
+ // Draw helper curve
+ if (np->show_helperpath) {
+ SPCurve *helper_curve = np->curve->copy();
+ helper_curve->transform(np->i2d );
+ np->helper_path = sp_canvas_bpath_new(sp_desktop_controls(desktop), helper_curve);
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(np->helper_path), np->helperpath_rgba, np->helperpath_width, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(np->helper_path), 0, SP_WIND_RULE_NONZERO);
+ sp_canvas_item_move_to_z(np->helper_path, 0);
+ sp_canvas_item_show(np->helper_path);
+ helper_curve->unref();
+ }
+}
+
/**
* \brief Creates new nodepath from item
*/
if (curve == NULL)
return NULL;
- NArtBpath *bpath = curve->first_bpath();
- gint length = curve->_end;
+ NArtBpath const *bpath = curve->get_bpath();
+ gint length = curve->get_length();
if (length == 0) {
curve->unref();
return NULL; // prevent crash for one-node paths
@@ -207,7 +222,13 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object,
np->helperpath_rgba = prefs_get_int_attribute("tools.nodes", "highlight_color", 0xff0000ff);
np->helperpath_width = 1.0;
np->curve = curve->copy();
- np->show_helperpath = prefs_get_int_attribute ("tools.nodes", "show_helperpath", 0) == 1;
+ np->show_helperpath = (prefs_get_int_attribute ("tools.nodes", "show_helperpath", 0) == 1);
+ if (SP_IS_LPE_ITEM(object)) {
+ Inkscape::LivePathEffect::Effect *lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(object));
+ if (lpe && lpe->isVisible() && lpe->showOrigPath()) {
+ np->show_helperpath = true;
+ }
+ }
np->straight_path = false;
if (IS_LIVEPATHEFFECT(object) && item) {
np->item = item;
// to a change in repr by regenerating nodepath --bb
sp_object_read_attr(SP_OBJECT(np->item), "transform");
- np->i2d = sp_item_i2d_affine(np->item);
+ np->i2d = from_2geom(sp_item_i2d_affine(np->item));
np->d2i = np->i2d.inverse();
np->repr = repr;
if ( sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(np->object)) ) {
np->repr_key = g_strdup("inkscape:original-d");
- LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(SP_LPE_ITEM(np->object));
- if (lpeobj && lpeobj->lpe) {
- lpeobj->lpe->setup_nodepath(np);
+ Inkscape::LivePathEffect::Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(np->object));
+ if (lpe) {
+ lpe->setup_nodepath(np);
}
} else {
np->repr_key = g_strdup("d");
gchar *typestr = parse_nodetypes(nodetypes, length);
// create the subpath(s) from the bpath
- NArtBpath *b = bpath;
+ NArtBpath const *b = bpath;
while (b->code != NR_END) {
b = subpath_from_bpath(np, b, typestr + (b - bpath));
}
@@ -263,17 +284,7 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object,
// create the livarot representation from the same item
sp_nodepath_ensure_livarot_path(np);
- // Draw helper curve
- if (np->show_helperpath) {
- SPCurve *helper_curve = np->curve->copy();
- helper_curve->transform(np->i2d );
- np->helper_path = sp_canvas_bpath_new(sp_desktop_controls(desktop), helper_curve);
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(np->helper_path), np->helperpath_rgba, np->helperpath_width, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
- sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(np->helper_path), 0, SP_WIND_RULE_NONZERO);
- sp_canvas_item_move_to_z(np->helper_path, 0);
- sp_canvas_item_show(np->helper_path);
- helper_curve->unref();
- }
+ sp_nodepath_draw_helper_curve(np, desktop);
return np;
}
{
if (np && np->livarot_path == NULL) {
SPCurve *curve = create_curve(np);
- NArtBpath const *bpath = SP_CURVE_BPATH(curve);
- np->livarot_path = bpath_to_Path(bpath);
+ np->livarot_path = new Path;
+ np->livarot_path->LoadPathVector(curve->get_pathvector());
if (np->livarot_path)
np->livarot_path->ConvertWithBackData(0.01);
* \param t The node type.
* \todo Fixme: t should be a proper type, rather than gchar
*/
-static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t)
+static NArtBpath const * subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath const *b, gchar const *t)
{
NR::Point ppos, pos, npos;
np->curve = create_curve(np);
gchar *typestr = create_typestr(np);
- gchar *svgpath = sp_svg_write_path(SP_CURVE_BPATH(np->curve));
+ gchar *svgpath = sp_svg_write_path(np->curve->get_pathvector());
// determine if path has an effect applied and write to correct "d" attribute.
if (repr->attribute(np->repr_key) == NULL || strcmp(svgpath, repr->attribute(np->repr_key))) { // d changed
SPCurve *curve = create_curve(np);
gchar *typestr = create_typestr(np);
- gchar *svgpath = sp_svg_write_path(SP_CURVE_BPATH(curve));
+ gchar *svgpath = sp_svg_write_path(curve->get_pathvector());
new_repr->setAttribute(np->repr_key, svgpath);
new_repr->setAttribute(np->repr_nodetypes_key, typestr);
* Call sp_node_moveto() for node selection and handle possible snapping.
*/
static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath, NR::Coord dx, NR::Coord dy,
- bool const snap = true)
+ bool const snap, bool constrained = false,
+ Inkscape::Snapper::ConstraintLine const &constraint = NR::Point())
{
NR::Coord best = NR_HUGE;
NR::Point delta(dx, dy);
NR::Point best_pt = delta;
Inkscape::SnappedPoint best_abs;
-
if (snap) {
/* When dragging a (selected) node, it should only snap to other nodes (i.e. unselected nodes), and
@@ -1231,8 +1242,15 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
- m.setup(nodepath->desktop, SP_PATH(n->subpath->nodepath->item), &unselected_nodes);
- Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta);
+ m.setup(NULL, SP_PATH(n->subpath->nodepath->item), &unselected_nodes);
+ Inkscape::SnappedPoint s;
+ if (constrained) {
+ Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
+ dedicated_constraint.setPoint(n->pos);
+ s = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta, dedicated_constraint);
+ } else {
+ s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta);
+ }
if (s.getSnapped() && (s.getDistance() < best)) {
best = s.getDistance();
best_abs = s;
@@ -1242,6 +1260,8 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
if (best_abs.getSnapped()) {
nodepath->desktop->snapindicator->set_new_snappoint(best_abs);
+ } else {
+ nodepath->desktop->snapindicator->remove_snappoint();
}
}
NR::Point c;
NR::Point pr;
- Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data;
+ Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data;
n->subpath->nodepath->desktop->snapindicator->remove_snappoint();
- // If either (Shift and some handle retracted), or (we're already dragging out a handle)
+ // If either (Shift and some handle retracted), or (we're already dragging out a handle)
if ( (!n->subpath->nodepath->straight_path) &&
( ((state & GDK_SHIFT_MASK) && ((n->n.other && n->n.pos == n->pos) || (n->p.other && n->p.pos == n->pos)))
|| n->dragging_out ) )
// move the node to the closest point
sp_nodepath_selected_nodes_move(n->subpath->nodepath,
n->origin[NR::X] + c[NR::X] - n->pos[NR::X],
- n->origin[NR::Y] + c[NR::Y] - n->pos[NR::Y]);
+ n->origin[NR::Y] + c[NR::Y] - n->pos[NR::Y],
+ true);
} else { // constraining to hor/vert
if (fabs((*p)[NR::X] - n->origin[NR::X]) > fabs((*p)[NR::Y] - n->origin[NR::Y])) { // snap to hor
- sp_nodepath_selected_nodes_move(n->subpath->nodepath, (*p)[NR::X] - n->pos[NR::X], n->origin[NR::Y] - n->pos[NR::Y]);
+ sp_nodepath_selected_nodes_move(n->subpath->nodepath,
+ (*p)[NR::X] - n->pos[NR::X],
+ n->origin[NR::Y] - n->pos[NR::Y],
+ true,
+ true, Inkscape::Snapper::ConstraintLine(component_vectors[NR::X]));
} else { // snap to vert
- sp_nodepath_selected_nodes_move(n->subpath->nodepath, n->origin[NR::X] - n->pos[NR::X], (*p)[NR::Y] - n->pos[NR::Y]);
+ sp_nodepath_selected_nodes_move(n->subpath->nodepath,
+ n->origin[NR::X] - n->pos[NR::X],
+ (*p)[NR::Y] - n->pos[NR::Y],
+ true,
+ true, Inkscape::Snapper::ConstraintLine(component_vectors[NR::Y]));
}
}
} else { // move freely
} else if ( IS_LIVEPATHEFFECT(object) && key) {
const gchar *svgd = object->repr->attribute(key);
if (svgd) {
- NArtBpath *bpath = sp_svg_read_path(svgd);
- SPCurve *curve_new = SPCurve::new_from_bpath(bpath);
+ Geom::PathVector pv = sp_svg_read_pathv(svgd);
+ SPCurve *curve_new = new SPCurve(pv);
if (curve_new) {
curve = curve_new; // don't do curve_copy because curve_new is already only created for us!
- } else {
- g_free(bpath);
}
}
}
} else if ( IS_LIVEPATHEFFECT(np->object) ) {
// FIXME: this writing to string and then reading from string is bound to be slow.
// create a method to convert from curve directly to 2geom...
- gchar *svgpath = sp_svg_write_path(SP_CURVE_BPATH(np->curve));
+ gchar *svgpath = sp_svg_write_path( np->curve->get_pathvector() );
LIVEPATHEFFECT(np->object)->lpe->setParameter(np->repr_key, svgpath);
g_free(svgpath);
}
}
+SPCanvasItem *
+sp_nodepath_generate_helperpath(SPDesktop *desktop, SPCurve *curve, const SPItem *item, guint32 color = 0xff0000ff) {
+ SPCurve *flash_curve = curve->copy();
+ Geom::Matrix i2d = item ? sp_item_i2d_affine(item) : Geom::identity();
+ flash_curve->transform(i2d);
+ SPCanvasItem * canvasitem = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), flash_curve);
+ // would be nice if its color could be XORed or something, now it is invisible for red stroked objects...
+ // unless we also flash the nodes...
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvasitem), color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(canvasitem), 0, SP_WIND_RULE_NONZERO);
+ sp_canvas_item_show(canvasitem);
+ flash_curve->unref();
+ return canvasitem;
+}
+
+SPCanvasItem *
+sp_nodepath_generate_helperpath(SPDesktop *desktop, SPPath *path) {
+ return sp_nodepath_generate_helperpath(desktop, sp_path_get_curve_for_edit(path), SP_ITEM(path),
+ prefs_get_int_attribute("tools.nodes", "highlight_color", 0xff0000ff));
+}
+
void sp_nodepath_show_helperpath(Inkscape::NodePath::Path *np, bool show) {
np->show_helperpath = show;