コード例 #1
0
ファイル: sp-path.cpp プロジェクト: Spin0za/inkscape
/**
 * Returns \c _curve_before_lpe if it is not NULL and a valid LPE is applied or
 * \c curve if not.
 */
const SPCurve* SPPath::get_curve_reference () const
{
    if (_curve_before_lpe && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(this))) {
        return _curve_before_lpe;
    } else {
        return _curve;
    }
}
コード例 #2
0
ファイル: sp-path.cpp プロジェクト: Spin0za/inkscape
/**
 * Return duplicate of edittable curve which is _curve_before_lpe if it exists or
 * shape->curve if not.
 */
SPCurve* SPPath::get_curve_for_edit () const
{
    if (_curve_before_lpe && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(this))) {
        return get_original_curve();
    } else {
        return getCurve();
    }
}
コード例 #3
0
ファイル: sp-lpe-item.cpp プロジェクト: asitti/inkscape
bool SPLPEItem::hasPathEffectRecursive() const
{
    if (parent && SP_IS_LPE_ITEM(parent)) {
        return hasPathEffect() || SP_LPE_ITEM(parent)->hasPathEffectRecursive();
    }
    else {
        return hasPathEffect();
    }
}
コード例 #4
0
void
sp_selected_path_reverse(SPDesktop *desktop)
{
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
    GSList *items = (GSList *) selection->itemList();

    if (!items) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse."));
        return;
    }


    // set "busy" cursor
    desktop->setWaitingCursor();

    bool did = false;
    desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Reversing paths..."));

    for (GSList *i = items; i != NULL; i = i->next) {

        if (!SP_IS_PATH(i->data))
            continue;

        did = true;
        SPPath *path = SP_PATH(i->data);

        SPCurve *rcurve = sp_path_get_curve_reference(path)->create_reverse();

        gchar *str = sp_svg_write_path(rcurve->get_pathvector());
        if ( sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(path)) ) {
            SP_OBJECT_REPR(path)->setAttribute("inkscape:original-d", str);
        } else {
            SP_OBJECT_REPR(path)->setAttribute("d", str);
        }
        g_free(str);

        rcurve->unref();

        // reverse nodetypes order (Bug #179866)
        gchar *nodetypes = g_strdup(SP_OBJECT_REPR(path)->attribute("sodipodi:nodetypes"));
        if ( nodetypes ) {
            SP_OBJECT_REPR(path)->setAttribute("sodipodi:nodetypes", g_strreverse(nodetypes));
            g_free(nodetypes);
        }
    }

    desktop->clearWaitingCursor();

    if (did) {
        sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_REVERSE,
                         _("Reverse path"));
    } else {
        sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection."));
    }
}
コード例 #5
0
ファイル: sp-lpe-item.cpp プロジェクト: asitti/inkscape
void SPLPEItem::remove_child(Inkscape::XML::Node * child) {
    if (this->hasPathEffectRecursive()) {
        SPObject *ochild = this->get_child_by_repr(child);

        if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
            sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild));
        }
    }

    SPItem::remove_child(child);
}
コード例 #6
0
ファイル: sp-lpe-item.cpp プロジェクト: asitti/inkscape
void SPLPEItem::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) {
    SPItem::child_added(child, ref);

    if (this->hasPathEffectRecursive()) {
        SPObject *ochild = this->get_child_by_repr(child);

        if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
            sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild));
        }
    }
}
コード例 #7
0
ファイル: sp-path.cpp プロジェクト: Spin0za/inkscape
/**
 * Writes the given transform into the repr for the given item.
 */
static Geom::Affine
sp_path_set_transform(SPItem *item, Geom::Affine const &xform)
{
    if (!SP_IS_PATH(item)) {
        return Geom::identity();
    }
    SPPath *path = SP_PATH(item);

    if (!path->_curve) { // 0 nodes, nothing to transform
        return Geom::identity();
    }

    // Transform the original-d path if this is a valid LPE item, other else the (ordinary) path
    if (path->_curve_before_lpe && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(item))) {
        if (sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(item), Inkscape::LivePathEffect::CLONE_ORIGINAL)) {
            // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized'
            return xform;
        } else {
            path->_curve_before_lpe->transform(xform);
        }
    } else {
        path->_curve->transform(xform);
    }

    // Adjust stroke
    item->adjust_stroke(xform.descrim());

    // Adjust pattern fill
    item->adjust_pattern(xform);

    // Adjust gradient fill
    item->adjust_gradient(xform);

    // Adjust LPE
    item->adjust_livepatheffect(xform);

    item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);

    // nothing remains - we've written all of the transform, so return identity
    return Geom::identity();
}
コード例 #8
0
void
LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
{
    if (lpe_list_locked) {
        // this was triggered by selecting a row in the list, so skip reloading
        lpe_list_locked = false;
        return;
    } 

    effectlist_store->clear();
    current_lpeitem = NULL;

    if ( sel && !sel->isEmpty() ) {
        SPItem *item = sel->singleItem();
        if ( item ) {
            if ( SP_IS_LPE_ITEM(item) ) {
                SPLPEItem *lpeitem = SP_LPE_ITEM(item);

                effect_list_reload(lpeitem);

                current_lpeitem = lpeitem;

                set_sensitize_all(true);
                if ( sp_lpe_item_has_path_effect(lpeitem) ) {
                    Inkscape::LivePathEffect::Effect *lpe = sp_lpe_item_get_current_lpe(lpeitem);
                    if (lpe) {
                        showParams(*lpe);
                        lpe_list_locked = true; 
                        selectInList(lpe);
                    } else {
                        showText(_("Unknown effect is applied"));
                    }
                } else {
                    showText(_("No effect applied"));
                    button_remove.set_sensitive(false);
                }
            } else {
                showText(_("Item is not a path or shape"));
                set_sensitize_all(false);
            }
        } else {
            showText(_("Only one item can be selected"));
            set_sensitize_all(false);
        }
    } else {
        showText(_("Empty selection"));
        set_sensitize_all(false);
    }
}
コード例 #9
0
ファイル: sp-path.cpp プロジェクト: Spin0za/inkscape
static void
sp_path_update_patheffect(SPLPEItem *lpeitem, bool write)
{
    SPShape * const shape = (SPShape *) lpeitem;
    Inkscape::XML::Node *repr = shape->getRepr();

#ifdef PATH_VERBOSE
g_message("sp_path_update_patheffect");
#endif

    if (shape->_curve_before_lpe && sp_lpe_item_has_path_effect_recursive(lpeitem)) {
        SPCurve *curve = shape->_curve_before_lpe->copy();
        /* if a path has an lpeitem applied, then reset the curve to the _curve_before_lpe.
         * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
        shape->setCurveInsync(curve, TRUE);

        bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve);
        if (success && write) {
            // could also do shape->getRepr()->updateRepr();  but only the d attribute needs updating.
#ifdef PATH_VERBOSE
g_message("sp_path_update_patheffect writes 'd' attribute");
#endif
            if ( shape->_curve != NULL ) {
                gchar *str = sp_svg_write_path(shape->_curve->get_pathvector());
                repr->setAttribute("d", str);
                g_free(str);
            } else {
                repr->setAttribute("d", NULL);
            }
        } else if (!success) {
            // LPE was unsuccesfull. Read the old 'd'-attribute.
            if (gchar const * value = repr->attribute("d")) {
                Geom::PathVector pv = sp_svg_read_pathv(value);
                SPCurve *oldcurve = new SPCurve(pv);
                if (oldcurve) {
                    shape->setCurve(oldcurve, TRUE);
                    oldcurve->unref();
                }
            }
        }
        shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
        curve->unref();
    }
}
コード例 #10
0
void
KnotHolderEntityEnd::bisector_end_set(Geom::Point const &p, guint state, bool left) {
    LPEPerpBisector *lpe = dynamic_cast<LPEPerpBisector *>(_effect);
    if (!lpe) return;

    Geom::Point const s = snap_knot_position(p, state);

    double lambda = Geom::nearest_point(s, lpe->M, lpe->perp_dir);
    if (left) {
        lpe->C = lpe->M + lpe->perp_dir * lambda;
        lpe->length_left.param_set_value(lambda);
    } else {
        lpe->D = lpe->M + lpe->perp_dir * lambda;
        lpe->length_right.param_set_value(-lambda);
    }

    // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
    sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true);
}
コード例 #11
0
 virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) {
     Geom::Point const s = p - param->origin;
     /// @todo implement angle snapping when holding CTRL
     param->setVector(s);
     sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
 };
コード例 #12
0
 virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
     Geom::Point const s = snap_knot_position(p);
     param->setOrigin(s);
     sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
 };
コード例 #13
0
bool
sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select, bool skip_all_lpeitems)
{
    bool did = false;
    
    for (;
         items != NULL;
         items = items->next) {

        SPItem *item = SP_ITEM(items->data);
    	SPDocument *document = item->document;

        if ( skip_all_lpeitems &&
             SP_IS_LPE_ITEM(item) && 
             !SP_IS_GROUP(item) ) // also convert objects in an SPGroup when skip_all_lpeitems is set.
        { 
            continue;
        }

        if (SP_IS_PATH(item) && !SP_PATH(item)->original_curve) {
            continue; // already a path, and no path effect
        }

        if (SP_IS_BOX3D(item)) {
            // convert 3D box to ordinary group of paths; replace the old element in 'selected' with the new group
            Inkscape::XML::Node *repr = SP_OBJECT_REPR(box3d_convert_to_group(SP_BOX3D(item)));
            
            if (repr) {
                *to_select = g_slist_prepend (*to_select, repr);
                did = true;
                *selected = g_slist_remove (*selected, item);
            }

            continue;
        }
        
        if (SP_IS_GROUP(item)) {
            sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(item), true);
            GSList *item_list = sp_item_group_item_list(SP_GROUP(item));
            
            GSList *item_to_select = NULL;
            GSList *item_selected = NULL;
            
            if (sp_item_list_to_curves(item_list, &item_selected, &item_to_select))
                did = true;

            g_slist_free(item_list);
            g_slist_free(item_to_select);
            g_slist_free(item_selected);

            continue;
        }

        Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr(item, 0);
        if (!repr)
            continue;

        did = true;
        *selected = g_slist_remove (*selected, item);

        // remember the position of the item
        gint pos = SP_OBJECT_REPR(item)->position();
        // remember parent
        Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent();
        // remember id
        char const *id = SP_OBJECT_REPR(item)->attribute("id");
        // remember title
        gchar *title = item->title();
        // remember description
        gchar *desc = item->desc();

        // It's going to resurrect, so we delete without notifying listeners.
        SP_OBJECT(item)->deleteObject(false);

        // restore id
        repr->setAttribute("id", id);
        // add the new repr to the parent
        parent->appendChild(repr);
        SPObject* newObj = document->getObjectByRepr(repr);
        if (title && newObj) {
        	newObj->setTitle(title);
        	g_free(title);
        }
        if (desc && newObj) {
        	newObj->setDesc(desc);
        	g_free(desc);
        }

        // move to the saved position
        repr->setPosition(pos > 0 ? pos : 0);

        /* Buglet: We don't re-add the (new version of the) object to the selection of any other
         * desktops where it was previously selected. */
        *to_select = g_slist_prepend (*to_select, repr);
        Inkscape::GC::release(repr);
    }
    
    return did;
}