Logo Search packages:      
Sourcecode: inkscape version File versions

void sp_node_selected_join_segment ( void   ) 

Join two nodes by adding a segment between them.

Definition at line 1219 of file nodepath.cpp.

References Path::SubPath::closed, Path::Node::code, Path::Path::desktop, Path::SubPath::first, Path::SubPath::last, Path::Node::n, Path::SubPath::nodepath, Path::Node::p, Path::Node::pos, Path::Path::selected, Path::Node::subpath, and Path::Node::type.

{
    Path::Path *nodepath = sp_nodepath_current();
    if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses

    if (g_list_length(nodepath->selected) != 2) {
        nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have <b>two endnodes</b> selected."));
        return;
    }

    Path::Node *a = (Path::Node *) nodepath->selected->data;
    Path::Node *b = (Path::Node *) nodepath->selected->next->data;

    g_assert(a != b);
    g_assert(a->p.other || a->n.other);
    g_assert(b->p.other || b->n.other);

    if (((a->subpath->closed) || (b->subpath->closed)) || (a->p.other && a->n.other) || (b->p.other && b->n.other)) {
        nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have <b>two endnodes</b> selected."));
        return;
    }

    if (a->subpath == b->subpath) {
        Path::SubPath *sp = a->subpath;

        /*similar to sp_nodepath_subpath_close(sp), without the node destruction*/
        sp->closed = TRUE;

        sp->first->p.other = sp->last;
        sp->last->n.other  = sp->first;

        sp_node_control_mirror_p_to_n(sp->last);
        sp_node_control_mirror_n_to_p(sp->first);

        sp->first->code = sp->last->code;
        sp->first       = sp->last;

        sp_nodepath_ensure_ctrls(sp->nodepath);

        update_repr(nodepath);

        return;
    }

    /* a and b are separate subpaths */
    Path::SubPath *sa = a->subpath;
    Path::SubPath *sb = b->subpath;

    Path::Node *n;
    NR::Point p;
    NRPathcode code;
    if (a == sa->first) {
        code = (NRPathcode) sa->first->n.other->code;
        Path::SubPath *t = sp_nodepath_subpath_new(sa->nodepath);
        n = sa->last;
        sp_nodepath_node_new(t, NULL, Path::NODE_CUSP, NR_MOVETO, &n->n.pos, &n->pos, &n->p.pos);
        for (n = n->p.other; n != NULL; n = n->p.other) {
            sp_nodepath_node_new(t, NULL, (Path::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos);
        }
        sp_nodepath_subpath_destroy(sa);
        sa = t;
    } else if (a == sa->last) {
        code = (NRPathcode)sa->last->code;
    } else {
        code = NR_END;
        g_assert_not_reached();
    }

    if (b == sb->first) {
        n = sb->first;
        sp_node_control_mirror_p_to_n(sa->last);
        sp_nodepath_node_new(sa, NULL, Path::NODE_CUSP, code, &n->p.pos, &n->pos, &n->n.pos);
        sp_node_control_mirror_n_to_p(sa->last);
        for (n = n->n.other; n != NULL; n = n->n.other) {
            sp_nodepath_node_new(sa, NULL, (Path::NodeType)n->type, (NRPathcode)n->code, &n->p.pos, &n->pos, &n->n.pos);
        }
    } else if (b == sb->last) {
        n = sb->last;
        sp_node_control_mirror_p_to_n(sa->last);
        sp_nodepath_node_new(sa, NULL, Path::NODE_CUSP, code, &p, &n->pos, &n->p.pos);
        sp_node_control_mirror_n_to_p(sa->last);
        for (n = n->p.other; n != NULL; n = n->p.other) {
            sp_nodepath_node_new(sa, NULL, (Path::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos);
        }
    } else {
        g_assert_not_reached();
    }
    /* and now destroy sb */

    sp_nodepath_subpath_destroy(sb);

    sp_nodepath_ensure_ctrls(sa->nodepath);

    update_repr(nodepath);
}


Generated by  Doxygen 1.6.0   Back to index