From b9bd53c7ede37554aa61c885fbed68f8d062c7d2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 3 Nov 2017 00:27:55 +0100 Subject: [PATCH 01/57] Starting refactor branch --- src/box3d-side.cpp | 8 +- src/live_effects/effect.cpp | 27 +- src/live_effects/effect.h | 8 +- src/live_effects/lpe-fillet-chamfer.cpp | 5 +- src/live_effects/lpe-powerclip.cpp | 206 +++----------- src/live_effects/lpe-powerclip.h | 4 - src/live_effects/lpegroupbbox.cpp | 44 ++- src/live_effects/lpegroupbbox.h | 3 +- src/sp-ellipse.cpp | 8 +- src/sp-item-group.cpp | 50 +++- src/sp-item.cpp | 21 +- src/sp-item.h | 4 + src/sp-lpe-item.cpp | 360 +++++++++++------------- src/sp-lpe-item.h | 12 +- src/sp-mask.cpp | 28 ++ src/sp-mask.h | 4 + src/sp-path.cpp | 12 +- src/sp-spiral.cpp | 7 +- src/sp-star.cpp | 8 +- 19 files changed, 391 insertions(+), 428 deletions(-) diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 3eea8855ca..7b76c0ed41 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -198,13 +198,19 @@ void Box3DSide::set_shape() { if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); + bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { this->setCurveInsync(c_lpe, TRUE); + bool apply_to_clip_mask = this->hasApplyToClipOrMask(); + if (apply_to_clip_mask) { + this->applyToClipPath(); + this->applyToMask(); + } } c_lpe->unref(); + } c->unref(); diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 5674e29dc6..dd08e77fb1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -383,8 +383,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - sp_shape(NULL), - sp_curve(NULL), + current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { @@ -516,17 +515,6 @@ Effect::processObjects(LpeAction lpe_action) } } -void Effect::setCurrentShape(SPShape * shape){ - if(shape){ - sp_shape = shape; - if (!(sp_curve = sp_shape->getCurveBeforeLPE())) { - // oops - return; - } - pathvector_before_effect = sp_curve->get_pathvector(); - } -} - /** * Is performed each time before the effect is updated. */ @@ -551,21 +539,18 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - setCurrentShape(shape); doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - setCurrentShape(shape); - doBeforeEffect(lpeitem); - if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { - sp_lpe_item->applyToClipPath(sp_lpe_item); - sp_lpe_item->applyToMask(sp_lpe_item); + if (current_shape) { + SPCurve* original_curve = current_shape->getCurveBeforeLPE(); + pathvector_before_all_effects = original_curve->get_pathvector(); + original_curve->unref(); } + doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index d0024f8772..38f275cf6f 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -79,8 +79,8 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape(){ return sp_shape; }; - void setCurrentShape(SPShape * shape); + SPShape * getCurrentShape() const { return current_shape; }; + void setCurrentShape(SPShape * shape) { current_shape = shape; } void processObjects(LpeAction lpe_action); /* @@ -136,7 +136,7 @@ public: bool is_load; bool upd_params; BoolParam is_visible; - SPCurve * sp_curve; + Geom::PathVector pathvector_before_all_effects; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; protected: @@ -175,7 +175,7 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. + SPShape * current_shape; // these get stored in performPathEffects. std::vector items; double current_zoom; std::vector selectedNodesPoints; diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 2b052ace13..c01fb0450c 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -316,13 +316,13 @@ void LPEFilletChamfer::setSelected(PathVectorSatellites *_pathvector_satellites) void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) { - if (sp_curve) { + if (!pathvector_before_effect.empty()) { //fillet chamfer specific calls satellites_param.setUseDistance(use_knot_distance); satellites_param.setCurrentZoom(current_zoom); //mandatory call satellites_param.setEffectType(effectType()); - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); //if are diferent sizes call to recalculate //TODO: Update the satellite data in paths modified, Satellites satellites = satellites_param.data(); @@ -334,7 +334,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) size_t number_nodes = pathv.nodes().size(); size_t previous_number_nodes = _pathvector_satellites->getTotalSatellites(); if (number_nodes != previous_number_nodes) { - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); Satellites satellites; double power = radius; if (!flexible) { diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 40a9cdbfb7..0dc50f6bc8 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -35,7 +35,7 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) registerParameter(&flatten); registerParameter(&hide_clip); registerParameter(&is_inverse); - convert_shapes = false; + apply_to_clippath_and_mask = true; } LPEPowerClip::~LPEPowerClip() {} @@ -83,78 +83,13 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ clip_box.appendNew(bottomright); clip_box.appendNew(bottomleft); clip_box.close(); - //clip_box *= sp_lpe_item->i2dt_affine(); std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - SPObject * clip_to_path = NULL; - if (SP_IS_SHAPE(clip_data) && !SP_IS_PATH(clip_data) && convert_shapes) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return; - } - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(SP_ITEM(clip_data), 0); - // remember the position of the item - gint pos = clip_data->getRepr()->position(); - Geom::Affine affine = SP_ITEM(clip_data)->transform; - // remember parent - Inkscape::XML::Node *parent = clip_data->getRepr()->parent(); - // remember id - char const *id = clip_data->getRepr()->attribute("id"); - // remember title - gchar *title = clip_data->title(); - // remember description - gchar *desc = clip_data->desc(); - - // It's going to resurrect, so we delete without notifying listeners. - clip_data->deleteObject(false); - - // restore id - clip_path_node->setAttribute("id", id); - - // add the new repr to the parent - parent->appendChild(clip_path_node); - clip_to_path = document->getObjectByRepr(clip_path_node); - - // transform position - SPCurve * c = NULL; - c = SP_SHAPE(clip_to_path)->getCurve(); - if (c) { - Geom::PathVector c_pv = c->get_pathvector(); - c_pv *= affine; - c->set_pathvector(c_pv); - SP_SHAPE(clip_to_path)->setCurve(c, TRUE); - c->unref(); - } - - clip_path_node->setAttribute("transform", NULL); - - if (title && clip_to_path) { - clip_to_path->setTitle(title); - g_free(title); - } - if (desc && clip_to_path) { - clip_to_path->setDesc(desc); - g_free(desc); - } - // move to the saved position - clip_path_node->setPosition(pos > 0 ? pos : 0); - Inkscape::GC::release(clip_path_node); - clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); - } if( is_inverse.param_getSVGValue() == (Glib::ustring)"false" && inverse && isVisible()) { - if (clip_to_path) { - addInverse(SP_ITEM(clip_to_path)); - } else { - addInverse(SP_ITEM(clip_data)); - } + addInverse(SP_ITEM(clip_data)); } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { - if (clip_to_path) { - removeInverse(SP_ITEM(clip_to_path)); - } else { - removeInverse(SP_ITEM(clip_data)); - } + removeInverse(SP_ITEM(clip_data)); } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ removeInverse(SP_ITEM(clip_data)); } @@ -165,15 +100,18 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ void LPEPowerClip::addInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { - if (SP_IS_GROUP(clip_data)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); + SPPath *path = dynamic_cast(clip_data); + SPShape *shape = dynamic_cast(clip_data); + SPGroup *group = dynamic_cast(clip_data); + if (group) { + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; addInverse(subitem); } - } else if (SP_IS_PATH(clip_data)) { + } else if (shape) { SPCurve * c = NULL; - c = SP_SHAPE(clip_data)->getCurve(); + c = shape->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); //TODO: this can be not correct but no better way @@ -184,7 +122,13 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } c_pv.push_back(clip_box); c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + if (!path) { + shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); + } + shape->setCurve(c, TRUE); + if (!path) { + shape->setCurveInsync( c, TRUE); + } c->unref(); is_inverse.param_setValue((Glib::ustring)"true", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -206,22 +150,31 @@ LPEPowerClip::addInverse (SPItem * clip_data){ void LPEPowerClip::removeInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { - if (SP_IS_GROUP(clip_data)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); + SPPath *path = dynamic_cast(clip_data); + SPShape *shape = dynamic_cast(clip_data); + SPGroup *group = dynamic_cast(clip_data); + if (group) { + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; removeInverse(subitem); } - } else if (SP_IS_PATH(clip_data)) { + } else if (shape) { SPCurve * c = NULL; - c = SP_SHAPE(clip_data)->getCurve(); + c = shape->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); if(c_pv.size() > 1) { c_pv.pop_back(); } c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + if (!path) { + shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); + } + shape->setCurve(c, TRUE); + if (!path) { + shape->setCurveInsync( c, TRUE); + } c->unref(); is_inverse.param_setValue((Glib::ustring)"false", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -240,49 +193,6 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ } } -void -LPEPowerClip::convertShapes() { - convert_shapes = true; - sp_lpe_item_update_patheffect(SP_LPE_ITEM(sp_lpe_item), false, false); -} - -Gtk::Widget * -LPEPowerClip::newWidget() -{ - // use manage here, because after deletion of Effect object, others might still be pointing to this widget. - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(6); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter * param = *it; - Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - ++it; - } - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); - Gtk::Button * topaths_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Convert clips to paths, undoable")))); - topaths_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEPowerClip::convertShapes)); - topaths_button->set_size_request(220,30); - hbox->pack_start(*topaths_button, false, false,2); - vbox->pack_start(*hbox, true,true,2); - return dynamic_cast(vbox); -} - void LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) { @@ -328,62 +238,20 @@ LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem) } -//void -//LPEPowerClip::transform_multiply(Geom::Affine const& postmul, bool set) -//{ -// SPDocument * doc = SP_ACTIVE_DOCUMENT; -// SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); -// if (clip_path && lock) { -// std::vector clip_path_list = clip_path->childList(true); -// Glib::ustring clip_id = (Glib::ustring)clip_path->getId(); -// Glib::ustring box_id = clip_id + (Glib::ustring)"_box"; -// for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { -// SPItem * clip_data = SP_ITEM(*iter); -// if(inverse && lock) { -// removeInverse(clip_data); -// } -// if (lock) { -// clip_data->transform *= postmul; -//// if (!inverse) { -//// SPDesktop *desktop = SP_ACTIVE_DESKTOP; -//// if (desktop) { -//// if (tools_isactive(desktop, TOOLS_NODES)) { -//// Inkscape::Selection * sel = SP_ACTIVE_DESKTOP->getSelection(); -//// SPItem * item = sel->singleItem(); -//// if (item != NULL) { -//// sel->remove(item); -//// sel->add(item); -//// } -//// } -//// } -//// } -// } -// if(inverse && lock) { -// doBeforeEffect(sp_lpe_item); -// } -// } -// } -// //cycle through all parameters. Most parameters will not need transformation, but path and point params -// for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { -// Parameter * param = *it; -// param->param_transform_multiply(postmul, set); -// } -// toggleClipVisibility(); -// toggleClipVisibility(); -//} - void LPEPowerClip::flattenClip(SPItem * clip_data, Geom::PathVector &path_in) { - if (SP_IS_GROUP(clip_data)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); + SPShape *shape = dynamic_cast(clip_data); + SPGroup *group = dynamic_cast(clip_data); + if (group) { + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; flattenClip(subitem, path_in); } - } else if (SP_IS_PATH(clip_data)) { + } else if (shape) { SPCurve * c = NULL; - c = SP_SHAPE(clip_data)->getCurve(); + c = shape->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(c_pv, path_in); diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 38485b798f..1259b2ffbd 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -20,13 +20,10 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); - virtual Gtk::Widget * newWidget(); - //virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); - void convertShapes(); private: HiddenParam is_inverse; HiddenParam uri; @@ -35,7 +32,6 @@ private: BoolParam hide_clip; Geom::Path clip_box; Geom::Affine base; - bool convert_shapes; }; } //namespace LivePathEffect diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 3862ebcc8c..0528c84a89 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -6,6 +6,10 @@ */ #include "live_effects/lpegroupbbox.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-shape.h" +#include "sp-item-group.h" namespace Inkscape { namespace LivePathEffect { @@ -20,7 +24,35 @@ namespace LivePathEffect { * or of the transformed lpeitem (\c absolute = \c true) using sp_item_i2doc_affine. * @post Updated values of boundingbox_X and boundingbox_Y. These intervals are set to empty intervals when the precondition is not met. */ -void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) + +Geom::OptRect +GroupBBoxEffect::getItemClipMaskBounds(SPLPEItem* item, Geom::Affine transform) { + Geom::OptRect bbox; + SPClipPath *clip_path = item->clip_ref->getObject(); + if(clip_path) { + //clip path dont need visualbouds use geometrical + bbox.unionWith(clip_path->geometricBounds(transform)); + } + + SPMask *mask_path = item->mask_ref->getObject(); + if(mask_path) { + bbox.unionWith(mask_path->geometricBounds(transform)); + } + SPGroup * group = dynamic_cast(item); + SPShape * shape = dynamic_cast(item); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPLPEItem *subitem = dynamic_cast(*iter); + bbox.unionWith(getItemClipMaskBounds(subitem, transform)); + } + } else if (shape) { + bbox.unionWith(item->geometricBounds(transform)); + } + return bbox; +} + +void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, bool clipmask) { // Get item bounding box Geom::Affine transform; @@ -30,8 +62,14 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) else { transform = Geom::identity(); } - - Geom::OptRect bbox = lpeitem->geometricBounds(transform); + + Geom::OptRect bbox; + if (clipmask) { + SPLPEItem * item = const_cast(lpeitem); + bbox = getItemClipMaskBounds(item, transform); + } else { + bbox = lpeitem->geometricBounds(transform); + } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/live_effects/lpegroupbbox.h b/src/live_effects/lpegroupbbox.h index cc14203d10..4274fb7d73 100644 --- a/src/live_effects/lpegroupbbox.h +++ b/src/live_effects/lpegroupbbox.h @@ -22,7 +22,8 @@ protected: Geom::Interval boundingbox_Y; //This sets boundingbox_X and boundingbox_Y - void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); + Geom::OptRect getItemClipMaskBounds(SPLPEItem* item, Geom::Affine transform); + void original_bbox(SPLPEItem const* lpeitem, bool absolute = false, bool clipmask = false); }; }; //namespace LivePathEffect diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 166237c8e0..153e9256b2 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -488,10 +488,16 @@ void SPGenericEllipse::set_shape(bool force) if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); - bool success = this->performPathEffect(c_lpe); + bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { this->setCurveInsync(c_lpe, TRUE); + bool apply_to_clip_mask = this->hasApplyToClipOrMask(); + if (apply_to_clip_mask) { + this->applyToClipPath(); + this->applyToMask(); + } + } c_lpe->unref(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 3d4d7b2531..858b8571ce 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -936,16 +936,40 @@ void SPGroup::update_patheffect(bool write) { static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) { - std::vector const item_list = sp_item_group_item_list(group); - - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + std::vector item_list = sp_item_group_item_list(group); +// bool apply_to_clip_mask = SP_LPE_ITEM(top_group)->hasApplyToClipOrMask(); + for ( std::vector::iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; - +// if (apply_to_clip_mask) { +// SPClipPath *clip_path = SP_ITEM(sub_item)->clip_ref->getObject(); +// if(clip_path) { +// std::vector clip_path_list = clip_path->childList(true); +// for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { +// SPItem * clip_data = SP_ITEM(*iter); +// if (clip_data) { +// item_list.push_back(clip_data); +// } +// } +// } + +// SPMask *mask_path = SP_ITEM(sub_item)->mask_ref->getObject(); +// if(mask_path) { +// std::vector mask_path_list = mask_path->childList(true); +// for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { +// SPItem * mask_data = SP_ITEM(*iter); +// if (mask_data) { +// item_list.push_back(mask_data); +// } +// } +// } +// } SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { sp_group_perform_patheffect(sub_group, top_group, write); } else { - SPShape *sub_shape = dynamic_cast(sub_item); + SPShape* sub_shape = dynamic_cast(sub_item); + SPLPEItem* sub_shape_lpeitem = dynamic_cast(sub_item); + SPLPEItem* top_group_lpeitem = dynamic_cast(top_group); if (sub_shape) { SPCurve * c = NULL; // If item is a SPRect, convert it to path first: @@ -967,7 +991,12 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } - c = sub_shape->getCurve(); + + if (sub_shape_lpeitem->getNearestLPEItem() == top_group_lpeitem) { + c = sub_shape->getCurveBeforeLPE(); + } else { + c = sub_shape->getCurve(); + } bool success = false; // only run LPEs when the shape has a curve defined if (c) { @@ -976,12 +1005,9 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - SPPath *sub_path = dynamic_cast(sub_item); - if (!sub_path) { - sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); - sub_shape->setCurve(c, TRUE); - sub_shape->setCurveInsync( c, TRUE); - } + sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); + sub_shape->setCurve(c, TRUE); + sub_shape->setCurveInsync( c, TRUE); if (write) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 3fef28e5b0..1a01066e28 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -31,10 +31,10 @@ #include "desktop.h" #include "style.h" #include "sp-root.h" -#include "sp-clippath.h" -#include "sp-mask.h" #include "sp-rect.h" #include "sp-text.h" +#include "sp-clippath.h" +#include "sp-mask.h" #include "sp-textpath.h" #include "sp-item-rm-unsatisfied-cns.h" #include "sp-pattern.h" @@ -1073,6 +1073,23 @@ bool SPItem::isFiltered() const { return (style && style->filter.href && style->filter.href->getObject()); } + +SPObject* SPItem::isInMask() const { + SPObject* parent = this->parent; + while (parent && !dynamic_cast(parent)) { + parent = parent->parent; + } + return parent; +} + +SPObject* SPItem::isInClipPath() const { + SPObject* parent = this->parent; + while (parent && !dynamic_cast(parent)) { + parent = parent->parent; + } + return parent; +} + unsigned SPItem::display_key_new(unsigned numkeys) { static unsigned dkey = 0; diff --git a/src/sp-item.h b/src/sp-item.h index 36af02edc7..88fca97799 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -290,6 +290,10 @@ public: */ bool isFiltered() const; + SPObject* isInMask() const; + + SPObject* isInClipPath() const; + void invoke_print(SPPrintContext *ctx); /** diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 5be950afaa..d77ae15bbd 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -50,7 +50,7 @@ static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); -static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths); +static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); typedef std::list HRefList; static std::string patheffectlist_svg_string(PathEffectList const & list); @@ -200,55 +200,16 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape return repr; } -/** - * returns true when LPE was successful. - */ -bool SPLPEItem::hasPathEffectOnClipOrMask() const -{ - bool has_clipormask_lpe = false; - if (this->hasPathEffect() && this->pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj) { - return false; - } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!lpe) { - return false; - } - if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - return false; - } - if (lpe->apply_to_clippath_and_mask) { - has_clipormask_lpe = true; - } - } - } - } - return has_clipormask_lpe; -} - -bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive() const -{ - if (parent && SP_IS_LPE_ITEM(parent)) { - return hasPathEffectOnClipOrMask() || SP_LPE_ITEM(parent)->hasPathEffectOnClipOrMaskRecursive(); - } - else { - return hasPathEffectOnClipOrMask(); - } -} /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current) { if (!curve) { return false; } - bool has_clipormask_lpe = false; + if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { @@ -269,49 +230,79 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip return false; } if (lpe->isVisible()) { + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished // yet, we don't alter the path return false; } - if (lpe->apply_to_clippath_and_mask) { - has_clipormask_lpe = true; + // Groups have their doBeforeEffect called elsewhere + lpe->setCurrentShape(current); + lpe->pathvector_before_effect = curve->get_pathvector(); + + if (!SP_IS_GROUP(this)) { + lpe->doBeforeEffect_impl(this); } - if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { - // Groups have their doBeforeEffect called elsewhere - if (current) { - lpe->setCurrentShape(current); - } - if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect_impl(this); - } - try { - lpe->doEffect(curve); - } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); - } - return false; - } - if (!SP_IS_GROUP(this)) { - lpe->pathvector_after_effect = curve->get_pathvector(); - lpe->doAfterEffect(this); + try { + lpe->doEffect(curve); + } + + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); } + return false; + } + + if (!SP_IS_GROUP(this)) { + lpe->pathvector_after_effect = curve->get_pathvector(); + lpe->doAfterEffect(this); } + + lpe->pathvector_after_effect = curve->get_pathvector(); } } - if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_clipormask_lpe){ - this->applyToClipPath(this); - this->applyToMask(this); - } } return true; } +//Sometimes wa need to check if clip ot mask is setted so make it optional to no doble check +bool SPLPEItem::hasApplyToClipOrMask(bool check_clip_mask) const { + if (check_clip_mask) { + SPClipPath *clip_path = this->clip_ref->getObject(); + SPMask *mask_path = this->mask_ref->getObject(); + if(!clip_path && !mask_path) { + return false; + } + } + + if (!this->hasPathEffect() || + !this->pathEffectsEnabled() || + this->path_effect_list->empty() ) + { + return false; + } + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj) { + continue; + } + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (!lpe) { + continue; + } + if (lpe->apply_to_clippath_and_mask) { + return true; + } + } + return false; +} + // CPPIFY: make pure virtual void SPLPEItem::update_patheffect(bool /*write*/) { //throw; @@ -367,15 +358,22 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) - { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPLPEItem * clip_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(clip_data); + } } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + + SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPLPEItem * mask_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(mask_data); + } } if (SP_IS_GROUP(lpeitem)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); @@ -395,22 +393,28 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) } static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) { g_return_if_fail(lpeitem != NULL); - if (SP_IS_GROUP(lpeitem)) { - if (!lpeitem->hasPathEffectOnClipOrMaskRecursive()) { - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } + SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPObject * clip_data = *iter; + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_data), keep_paths, !lpeitem->hasPathEffectRecursive()); + } + } + + SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPObject * mask_data = *iter; + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask_path), keep_paths, !lpeitem->hasPathEffectRecursive()); } + } + + if (SP_IS_GROUP(lpeitem)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; @@ -420,18 +424,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) } } else if (SP_IS_PATH(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } - mask = dynamic_cast(lpeitem->parent); - clip_path = dynamic_cast(lpeitem->parent); - if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("inkscape:original-d")) || - ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("inkscape:original-d"))) + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) { if (!keep_paths) { repr->setAttribute("d", repr->attribute("inkscape:original-d")); @@ -444,18 +437,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) } } else if (SP_IS_SHAPE(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } - mask = dynamic_cast(lpeitem->parent); - clip_path = dynamic_cast(lpeitem->parent); - if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("d")) || - ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("d"))) + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) { if (!keep_paths) { repr->setAttribute("d", NULL); @@ -526,16 +508,6 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); - SPMask * mask = mask_ref->getObject(); - if(mask && !hasPathEffectOnClipOrMaskRecursive()) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), false); - } - SPClipPath * clip_path = clip_ref->getObject(); - if(clip_path && !hasPathEffectOnClipOrMaskRecursive()) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), false); - } //fix bug 1219324 if (SP_ACTIVE_DESKTOP ) { Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; @@ -677,25 +649,6 @@ bool SPLPEItem::hasBrokenPathEffect() const return false; } - -bool SPLPEItem::hasPathEffect() const -{ - if (!path_effect_list || path_effect_list->empty()) { - return false; - } - - // go through the list; if some are unknown or invalid, we are not an LPE item! - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj || !lpeobj->get_lpe()) { - return false; - } - } - - return true; -} - bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { @@ -718,82 +671,106 @@ bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const return false; } +bool SPLPEItem::hasPathEffect() const +{ + if (!path_effect_list || path_effect_list->empty()) { + return false; + } + + // go through the list; if some are unknown or invalid, we are not an LPE item! + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj || !lpeobj->get_lpe()) { + return false; + } + } + + return true; +} + bool SPLPEItem::hasPathEffectRecursive() const { if (parent && SP_IS_LPE_ITEM(parent)) { - return hasPathEffect() || SP_LPE_ITEM(parent)->hasPathEffectRecursive(); + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (!parent_lpe_item) { + return hasPathEffect(); + } + return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); } else { return hasPathEffect(); } } +SPLPEItem * +SPLPEItem::getNearestLPEItem() const +{ + if (parent && SP_IS_LPE_ITEM(parent)) { + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (!parent_lpe_item) { + return hasPathEffect()?this:NULL; + } + return hasPathEffect()?this:parent_lpe_item->getNearestLPEItem(); + } + else { + return hasPathEffect()?this:NULL; + } +} + void -SPLPEItem::applyToClipPath(SPItem *item) +SPLPEItem::applyToClipPath() { - SPClipPath *clip_path = item->clip_ref->getObject(); + SPClipPath *clip_path = this->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data), item); - } - } - if(SP_IS_GROUP(item)){ - std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - applyToClipPath(SP_ITEM(subitem)); + applyToClipPathOrMask(SP_ITEM(clip_data)); } } } void -SPLPEItem::applyToMask(SPItem *item) +SPLPEItem::applyToMask() { - SPMask *mask = item->mask_ref->getObject(); + SPMask *mask = this->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data), item); - } - } - if(SP_IS_GROUP(item)){ - std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - applyToMask(SP_ITEM(subitem)); + applyToClipPathOrMask(SP_ITEM(mask_data)); } } } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask) { - if (SP_IS_GROUP(clip_mask)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_mask)); + SPGroup *group = dynamic_cast(clip_mask); + SPPath *path = dynamic_cast(clip_mask); + SPShape *shape = dynamic_cast(clip_mask); + if (group) { + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; - applyToClipPathOrMask(subitem, item); + applyToClipPathOrMask(subitem); } - } else if (SP_IS_SHAPE(clip_mask)) { + } else if (shape) { SPCurve * c = NULL; - - if (SP_IS_PATH(clip_mask)) { - c = SP_PATH(clip_mask)->get_original_curve(); + if (path) { + c = path->get_original_curve(); } else { - c = SP_SHAPE(clip_mask)->getCurve(); + c = shape->getCurve(); } if (c) { bool success = false; try { - if(SP_IS_GROUP(this)){ - c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); - } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, shape); + if (!path) { + shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); + shape->setCurve(c, TRUE); + shape->setCurveInsync( c, TRUE); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -804,24 +781,13 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE - if (success && c) { - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } - } if (c) { - c->unref(); + if (success) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } + c->unref(); } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 82f3940c10..a05fea8093 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -70,14 +70,14 @@ public: virtual void update_patheffect(bool write); - bool hasPathEffectOnClipOrMask() const; - bool hasPathEffectOnClipOrMaskRecursive() const; - bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); + bool performPathEffect(SPCurve *curve, SPShape *current); bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; + SPLPEItem * getNearestLPEItem() const; + bool hasApplyToClipOrMask(bool check_clip_mask = true) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; @@ -94,9 +94,9 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void applyToMask(SPItem * item); - void applyToClipPath(SPItem * item); - void applyToClipPathOrMask(SPItem * clip_mask, SPItem * item); + void applyToMask(); + void applyToClipPath(); + void applyToClipPathOrMask(SPItem * clip_mask); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 0597d29f78..3b7ed0d286 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -112,6 +112,34 @@ void SPMask::set(unsigned int key, const gchar* value) { } } +Geom::OptRect +SPMask::geometricBounds(Geom::Affine const &transform) { + Geom::OptRect bbox; + + for (auto& i: children) { + if (SP_IS_ITEM(&i)) { + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); + bbox.unionWith(tmp); + } + } + + return bbox; +} + +Geom::OptRect +SPMask::visualBounds(Geom::Affine const &transform) { + Geom::OptRect bbox; + + for (auto& i: children) { + if (SP_IS_ITEM(&i)) { + Geom::OptRect tmp = SP_ITEM(&i)->visualBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); + bbox.unionWith(tmp); + } + } + + return bbox; +} + void SPMask::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { /* Invoke SPObjectGroup implementation */ SPObjectGroup::child_added(child, ref); diff --git a/src/sp-mask.h b/src/sp-mask.h index 02d37b82b0..26e5108300 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -47,6 +47,10 @@ public: Inkscape::DrawingItem *sp_mask_show(Inkscape::Drawing &drawing, unsigned int key); void sp_mask_hide(unsigned int key); + Geom::OptRect geometricBounds(Geom::Affine const &transform); + + Geom::OptRect visualBounds(Geom::Affine const &transform) ; + void sp_mask_set_bbox(unsigned int key, Geom::OptRect const &bbox); protected: diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 0cf2a5f3eb..d7c356f3a1 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -334,13 +334,13 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif - if (_curve_before_lpe && hasPathEffectRecursive()) { + if (_curve_before_lpe && pathEffectsEnabled() && hasPathEffect()) { SPCurve *curve = _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)*/ this->setCurveInsync(curve, TRUE); - bool success = this->performPathEffect(curve); + bool success = this->performPathEffect(curve, SP_SHAPE(this)); if (success && write) { // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. @@ -354,6 +354,7 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); } else { repr->setAttribute("d", NULL); } + } else if (!success) { // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { @@ -369,6 +370,13 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); +// if (success) { +// bool apply_to_clip_mask = this->hasApplyToClipOrMask(); +// if (apply_to_clip_mask) { +// this->applyToClipPath(); +// this->applyToMask(); +// } +// } } } diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index a84fc60412..9e266014a9 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -376,10 +376,15 @@ void SPSpiral::set_shape(bool force) { if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); + bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { this->setCurveInsync( c_lpe, TRUE); + bool apply_to_clip_mask = this->hasApplyToClipOrMask(); + if (apply_to_clip_mask) { + this->applyToClipPath(); + this->applyToMask(); + } } c_lpe->unref(); diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 9844df98af..359986d321 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -458,13 +458,19 @@ void SPStar::set_shape(bool force) { if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); + bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { this->setCurveInsync( c_lpe, TRUE); + bool apply_to_clip_mask = this->hasApplyToClipOrMask(); + if (apply_to_clip_mask) { + this->applyToClipPath(); + this->applyToMask(); + } } c_lpe->unref(); + } c->unref(); -- GitLab From 6d8876329a58ee74312c9ea2263699bbdfe53f17 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 3 Nov 2017 02:33:44 +0100 Subject: [PATCH 02/57] Solve compile bug --- src/sp-lpe-item.cpp | 2 +- src/sp-lpe-item.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index d77ae15bbd..5b904d5454 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -703,7 +703,7 @@ bool SPLPEItem::hasPathEffectRecursive() const } } -SPLPEItem * +SPLPEItem const* SPLPEItem::getNearestLPEItem() const { if (parent && SP_IS_LPE_ITEM(parent)) { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index a05fea8093..888539527e 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -76,7 +76,7 @@ public: bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; - SPLPEItem * getNearestLPEItem() const; + SPLPEItem const* getNearestLPEItem() const; bool hasApplyToClipOrMask(bool check_clip_mask = true) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; -- GitLab From b7fed0d674971167b9e3b88c30d1d0483d88028d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 4 Nov 2017 03:29:26 +0100 Subject: [PATCH 03/57] Working on Clip and Mask --- src/live_effects/lpegroupbbox.cpp | 10 ++--- src/sp-item-group.cpp | 48 ++++++----------------- src/sp-lpe-item.cpp | 65 ++++--------------------------- src/sp-lpe-item.h | 4 +- src/sp-path.cpp | 31 +++++++++++---- 5 files changed, 49 insertions(+), 109 deletions(-) diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 0528c84a89..e0451d5dd3 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -64,12 +64,12 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo } Geom::OptRect bbox; - if (clipmask) { - SPLPEItem * item = const_cast(lpeitem); - bbox = getItemClipMaskBounds(item, transform); - } else { +// if (clipmask) { +// SPLPEItem * item = const_cast(lpeitem); +// bbox = getItemClipMaskBounds(item, transform); +// } else { bbox = lpeitem->geometricBounds(transform); - } +// } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 858b8571ce..4953e9e3bc 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -936,40 +936,17 @@ void SPGroup::update_patheffect(bool write) { static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) { + group->applyToClipPath(); + group->applyToMask(); std::vector item_list = sp_item_group_item_list(group); -// bool apply_to_clip_mask = SP_LPE_ITEM(top_group)->hasApplyToClipOrMask(); for ( std::vector::iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; -// if (apply_to_clip_mask) { -// SPClipPath *clip_path = SP_ITEM(sub_item)->clip_ref->getObject(); -// if(clip_path) { -// std::vector clip_path_list = clip_path->childList(true); -// for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { -// SPItem * clip_data = SP_ITEM(*iter); -// if (clip_data) { -// item_list.push_back(clip_data); -// } -// } -// } - -// SPMask *mask_path = SP_ITEM(sub_item)->mask_ref->getObject(); -// if(mask_path) { -// std::vector mask_path_list = mask_path->childList(true); -// for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { -// SPItem * mask_data = SP_ITEM(*iter); -// if (mask_data) { -// item_list.push_back(mask_data); -// } -// } -// } -// } SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { sp_group_perform_patheffect(sub_group, top_group, write); } else { - SPShape* sub_shape = dynamic_cast(sub_item); - SPLPEItem* sub_shape_lpeitem = dynamic_cast(sub_item); - SPLPEItem* top_group_lpeitem = dynamic_cast(top_group); + SPShape* sub_shape = dynamic_cast(sub_item); + SPPath* sub_path = dynamic_cast(sub_item); if (sub_shape) { SPCurve * c = NULL; // If item is a SPRect, convert it to path first: @@ -991,12 +968,9 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } - - if (sub_shape_lpeitem->getNearestLPEItem() == top_group_lpeitem) { - c = sub_shape->getCurveBeforeLPE(); - } else { - c = sub_shape->getCurve(); - } + sub_shape->applyToClipPath(); + sub_shape->applyToMask(); + c = sub_shape->getCurve(); bool success = false; // only run LPEs when the shape has a curve defined if (c) { @@ -1005,9 +979,11 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); - sub_shape->setCurve(c, TRUE); - sub_shape->setCurveInsync( c, TRUE); + if (!sub_path) { + sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); + sub_shape->setCurve(c, TRUE); + sub_shape->setCurveInsync( c, TRUE); + } if (write) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 5b904d5454..9fe428de83 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -204,7 +204,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool clipmask) { if (!curve) { return false; @@ -236,6 +236,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current) { // yet, we don't alter the path return false; } + if (clipmask && !lpe->apply_to_clippath_and_mask) { + continue; + } // Groups have their doBeforeEffect called elsewhere lpe->setCurrentShape(current); lpe->pathvector_before_effect = curve->get_pathvector(); @@ -257,8 +260,8 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current) { return false; } - if (!SP_IS_GROUP(this)) { lpe->pathvector_after_effect = curve->get_pathvector(); + if (!SP_IS_GROUP(this)) { lpe->doAfterEffect(this); } @@ -269,40 +272,6 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current) { return true; } -//Sometimes wa need to check if clip ot mask is setted so make it optional to no doble check -bool SPLPEItem::hasApplyToClipOrMask(bool check_clip_mask) const { - if (check_clip_mask) { - SPClipPath *clip_path = this->clip_ref->getObject(); - SPMask *mask_path = this->mask_ref->getObject(); - if(!clip_path && !mask_path) { - return false; - } - } - - if (!this->hasPathEffect() || - !this->pathEffectsEnabled() || - this->path_effect_list->empty() ) - { - return false; - } - - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj) { - continue; - } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!lpe) { - continue; - } - if (lpe->apply_to_clippath_and_mask) { - return true; - } - } - return false; -} - // CPPIFY: make pure virtual void SPLPEItem::update_patheffect(bool /*write*/) { //throw; @@ -691,11 +660,8 @@ bool SPLPEItem::hasPathEffect() const bool SPLPEItem::hasPathEffectRecursive() const { - if (parent && SP_IS_LPE_ITEM(parent)) { - SPLPEItem * parent_lpe_item = dynamic_cast(parent); - if (!parent_lpe_item) { - return hasPathEffect(); - } + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (parent_lpe_item) { return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); } else { @@ -703,21 +669,6 @@ bool SPLPEItem::hasPathEffectRecursive() const } } -SPLPEItem const* -SPLPEItem::getNearestLPEItem() const -{ - if (parent && SP_IS_LPE_ITEM(parent)) { - SPLPEItem * parent_lpe_item = dynamic_cast(parent); - if (!parent_lpe_item) { - return hasPathEffect()?this:NULL; - } - return hasPathEffect()?this:parent_lpe_item->getNearestLPEItem(); - } - else { - return hasPathEffect()?this:NULL; - } -} - void SPLPEItem::applyToClipPath() { @@ -766,7 +717,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask) if (c) { bool success = false; try { - success = this->performPathEffect(c, shape); + success = this->performPathEffect(c, shape, true); if (!path) { shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); shape->setCurve(c, TRUE); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 888539527e..e9f9540cd2 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -70,14 +70,12 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, SPShape *current); + bool performPathEffect(SPCurve *curve, SPShape *current, bool clipmask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; - SPLPEItem const* getNearestLPEItem() const; - bool hasApplyToClipOrMask(bool check_clip_mask = true) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index d7c356f3a1..05ab682006 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -334,7 +334,7 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif - if (_curve_before_lpe && pathEffectsEnabled() && hasPathEffect()) { + if (_curve_before_lpe && hasPathEffect()) { SPCurve *curve = _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)*/ @@ -370,13 +370,28 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); -// if (success) { -// bool apply_to_clip_mask = this->hasApplyToClipOrMask(); -// if (apply_to_clip_mask) { -// this->applyToClipPath(); -// this->applyToMask(); -// } -// } + if (success) { + this->applyToClipPath(); + this->applyToMask(); + } + } if (_curve_before_lpe && hasPathEffectRecursive()) { + SPCurve *curve = _curve_before_lpe->copy(); + this->setCurveInsync(curve, TRUE); + if (write) { + // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. +#ifdef PATH_VERBOSE +g_message("sp_path_update_patheffect writes 'd' attribute"); +#endif + if (_curve) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + curve->unref(); } } -- GitLab From 675fbd756b041462c1f2d8bb4e59f57734951728 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 4 Nov 2017 17:07:22 +0100 Subject: [PATCH 04/57] Working on mask --- src/box3d-side.cpp | 5 ----- src/live_effects/lpe-powerclip.cpp | 2 +- src/sp-ellipse.cpp | 6 ------ src/sp-item-group.cpp | 18 ++++++++++++------ src/sp-lpe-item.cpp | 20 ++++++++++---------- src/sp-lpe-item.h | 6 +++--- src/sp-path.cpp | 4 ++-- src/sp-spiral.cpp | 5 ----- src/sp-star.cpp | 5 ----- 9 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 7b76c0ed41..b621573a5b 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -202,11 +202,6 @@ void Box3DSide::set_shape() { if (success) { this->setCurveInsync(c_lpe, TRUE); - bool apply_to_clip_mask = this->hasApplyToClipOrMask(); - if (apply_to_clip_mask) { - this->applyToClipPath(); - this->applyToMask(); - } } c_lpe->unref(); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 611d909700..2f09c64682 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -276,7 +276,7 @@ void sp_inverse_powerclip(Inkscape::Selection *sel) { lpe->getRepr()->setAttribute("inverse", "true"); lpe->getRepr()->setAttribute("flatten", "false"); lpe->getRepr()->setAttribute("hide_clip", "false"); - dynamic_cast(lpe)->convertShapes(); + //dynamic_cast(lpe)->convertShapes(); } } } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 153e9256b2..d1495ee076 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -492,12 +492,6 @@ void SPGenericEllipse::set_shape(bool force) if (success) { this->setCurveInsync(c_lpe, TRUE); - bool apply_to_clip_mask = this->hasApplyToClipOrMask(); - if (apply_to_clip_mask) { - this->applyToClipPath(); - this->applyToMask(); - } - } c_lpe->unref(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 4953e9e3bc..76c3b7d8f2 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -936,8 +936,11 @@ void SPGroup::update_patheffect(bool write) { static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) { - group->applyToClipPath(); - group->applyToMask(); + SPLPEItem* clipmaskto = dynamic_cast(group); + if (clipmaskto) { + top_group->applyToClipPath(clipmaskto); + top_group->applyToMask(clipmaskto); + } std::vector item_list = sp_item_group_item_list(group); for ( std::vector::iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; @@ -945,8 +948,13 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) if (sub_group) { sp_group_perform_patheffect(sub_group, top_group, write); } else { - SPShape* sub_shape = dynamic_cast(sub_item); - SPPath* sub_path = dynamic_cast(sub_item); + SPShape* sub_shape = dynamic_cast(sub_item); + SPPath* sub_path = dynamic_cast(sub_item); + clipmaskto = dynamic_cast(sub_item); + if (clipmaskto) { + top_group->applyToClipPath(clipmaskto); + top_group->applyToMask(clipmaskto); + } if (sub_shape) { SPCurve * c = NULL; // If item is a SPRect, convert it to path first: @@ -968,8 +976,6 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } - sub_shape->applyToClipPath(); - sub_shape->applyToMask(); c = sub_shape->getCurve(); bool success = false; // only run LPEs when the shape has a curve defined diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9fe428de83..a0953ab194 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -670,33 +670,33 @@ bool SPLPEItem::hasPathEffectRecursive() const } void -SPLPEItem::applyToClipPath() +SPLPEItem::applyToClipPath(SPLPEItem* to) { - SPClipPath *clip_path = this->clip_ref->getObject(); + SPClipPath *clip_path = to->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data)); + applyToClipPathOrMask(SP_ITEM(clip_data), to); } } } void -SPLPEItem::applyToMask() +SPLPEItem::applyToMask(SPLPEItem* to) { - SPMask *mask = this->mask_ref->getObject(); + SPMask *mask = to->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data)); + applyToClipPathOrMask(SP_ITEM(mask_data), to); } } } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPLPEItem* to) { SPGroup *group = dynamic_cast(clip_mask); SPPath *path = dynamic_cast(clip_mask); @@ -705,12 +705,12 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask) std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; - applyToClipPathOrMask(subitem); + applyToClipPathOrMask(subitem, to); } } else if (shape) { SPCurve * c = NULL; - if (path) { - c = path->get_original_curve(); + if (to == this) { + c = shape->getCurveBeforeLPE(); } else { c = shape->getCurve(); } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index e9f9540cd2..2c3554952e 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -92,9 +92,9 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void applyToMask(); - void applyToClipPath(); - void applyToClipPathOrMask(SPItem * clip_mask); + void applyToMask(SPLPEItem* to); + void applyToClipPath(SPLPEItem* to); + void applyToClipPathOrMask(SPItem * clip_mask, SPLPEItem* to); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 05ab682006..eee67c4bb4 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -371,8 +371,8 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); if (success) { - this->applyToClipPath(); - this->applyToMask(); + this->applyToClipPath(this); + this->applyToMask(this); } } if (_curve_before_lpe && hasPathEffectRecursive()) { SPCurve *curve = _curve_before_lpe->copy(); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 9e266014a9..cf5486e4c3 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -380,11 +380,6 @@ void SPSpiral::set_shape(bool force) { if (success) { this->setCurveInsync( c_lpe, TRUE); - bool apply_to_clip_mask = this->hasApplyToClipOrMask(); - if (apply_to_clip_mask) { - this->applyToClipPath(); - this->applyToMask(); - } } c_lpe->unref(); diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 359986d321..68db119999 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -462,11 +462,6 @@ void SPStar::set_shape(bool force) { if (success) { this->setCurveInsync( c_lpe, TRUE); - bool apply_to_clip_mask = this->hasApplyToClipOrMask(); - if (apply_to_clip_mask) { - this->applyToClipPath(); - this->applyToMask(); - } } c_lpe->unref(); -- GitLab From 92b8c5beee45758aed0aacdbbd8b8ad6c75e777e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 4 Nov 2017 18:35:30 +0100 Subject: [PATCH 05/57] Working on Clip And Mask --- src/live_effects/effect.cpp | 5 - src/live_effects/effect.h | 1 - src/live_effects/lpe-powerclip.cpp | 208 +++++++++++++++++++++++------ src/live_effects/lpe-powerclip.h | 4 + src/sp-item-group.cpp | 4 +- src/sp-lpe-item.cpp | 68 ++++++---- src/sp-lpe-item.h | 8 +- src/sp-path.cpp | 2 +- 8 files changed, 223 insertions(+), 77 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index dd08e77fb1..f083a1d53d 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -545,11 +545,6 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - if (current_shape) { - SPCurve* original_curve = current_shape->getCurveBeforeLPE(); - pathvector_before_all_effects = original_curve->get_pathvector(); - original_curve->unref(); - } doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 38f275cf6f..f1330d45ea 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -136,7 +136,6 @@ public: bool is_load; bool upd_params; BoolParam is_visible; - Geom::PathVector pathvector_before_all_effects; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; protected: diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 2f09c64682..18276270d6 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -35,7 +35,7 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) registerParameter(&flatten); registerParameter(&hide_clip); registerParameter(&is_inverse); - apply_to_clippath_and_mask = true; + convert_shapes = false; } LPEPowerClip::~LPEPowerClip() {} @@ -83,13 +83,78 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ clip_box.appendNew(bottomright); clip_box.appendNew(bottomleft); clip_box.close(); + //clip_box *= sp_lpe_item->i2dt_affine(); std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; + SPObject * clip_to_path = NULL; + if (SP_IS_SHAPE(clip_data) && !SP_IS_PATH(clip_data) && convert_shapes) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(SP_ITEM(clip_data), 0); + // remember the position of the item + gint pos = clip_data->getRepr()->position(); + Geom::Affine affine = SP_ITEM(clip_data)->transform; + // remember parent + Inkscape::XML::Node *parent = clip_data->getRepr()->parent(); + // remember id + char const *id = clip_data->getRepr()->attribute("id"); + // remember title + gchar *title = clip_data->title(); + // remember description + gchar *desc = clip_data->desc(); + + // It's going to resurrect, so we delete without notifying listeners. + clip_data->deleteObject(false); + + // restore id + clip_path_node->setAttribute("id", id); + + // add the new repr to the parent + parent->appendChild(clip_path_node); + clip_to_path = document->getObjectByRepr(clip_path_node); + + // transform position + SPCurve * c = NULL; + c = SP_SHAPE(clip_to_path)->getCurve(); + if (c) { + Geom::PathVector c_pv = c->get_pathvector(); + c_pv *= affine; + c->set_pathvector(c_pv); + SP_SHAPE(clip_to_path)->setCurve(c, TRUE); + c->unref(); + } + + clip_path_node->setAttribute("transform", NULL); + + if (title && clip_to_path) { + clip_to_path->setTitle(title); + g_free(title); + } + if (desc && clip_to_path) { + clip_to_path->setDesc(desc); + g_free(desc); + } + // move to the saved position + clip_path_node->setPosition(pos > 0 ? pos : 0); + Inkscape::GC::release(clip_path_node); + clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); + } if( is_inverse.param_getSVGValue() == (Glib::ustring)"false" && inverse && isVisible()) { - addInverse(SP_ITEM(clip_data)); + if (clip_to_path) { + addInverse(SP_ITEM(clip_to_path)); + } else { + addInverse(SP_ITEM(clip_data)); + } } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { - removeInverse(SP_ITEM(clip_data)); + if (clip_to_path) { + removeInverse(SP_ITEM(clip_to_path)); + } else { + removeInverse(SP_ITEM(clip_data)); + } } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ removeInverse(SP_ITEM(clip_data)); } @@ -100,18 +165,15 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ void LPEPowerClip::addInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { - SPPath *path = dynamic_cast(clip_data); - SPShape *shape = dynamic_cast(clip_data); - SPGroup *group = dynamic_cast(clip_data); - if (group) { - std::vector item_list = sp_item_group_item_list(group); + if (SP_IS_GROUP(clip_data)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; addInverse(subitem); } - } else if (shape) { + } else if (SP_IS_PATH(clip_data)) { SPCurve * c = NULL; - c = shape->getCurve(); + c = SP_SHAPE(clip_data)->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); //TODO: this can be not correct but no better way @@ -122,13 +184,7 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } c_pv.push_back(clip_box); c->set_pathvector(c_pv); - if (!path) { - shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); - } - shape->setCurve(c, TRUE); - if (!path) { - shape->setCurveInsync( c, TRUE); - } + SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); is_inverse.param_setValue((Glib::ustring)"true", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -150,31 +206,22 @@ LPEPowerClip::addInverse (SPItem * clip_data){ void LPEPowerClip::removeInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { - SPPath *path = dynamic_cast(clip_data); - SPShape *shape = dynamic_cast(clip_data); - SPGroup *group = dynamic_cast(clip_data); - if (group) { - std::vector item_list = sp_item_group_item_list(group); + if (SP_IS_GROUP(clip_data)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; removeInverse(subitem); } - } else if (shape) { + } else if (SP_IS_PATH(clip_data)) { SPCurve * c = NULL; - c = shape->getCurve(); + c = SP_SHAPE(clip_data)->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); if(c_pv.size() > 1) { c_pv.pop_back(); } c->set_pathvector(c_pv); - if (!path) { - shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); - } - shape->setCurve(c, TRUE); - if (!path) { - shape->setCurveInsync( c, TRUE); - } + SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); is_inverse.param_setValue((Glib::ustring)"false", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -193,6 +240,49 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ } } +void +LPEPowerClip::convertShapes() { + convert_shapes = true; + sp_lpe_item_update_patheffect(SP_LPE_ITEM(sp_lpe_item), false, false); +} + +Gtk::Widget * +LPEPowerClip::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(6); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + ++it; + } + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::Button * topaths_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Convert clips to paths, undoable")))); + topaths_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEPowerClip::convertShapes)); + topaths_button->set_size_request(220,30); + hbox->pack_start(*topaths_button, false, false,2); + vbox->pack_start(*hbox, true,true,2); + return dynamic_cast(vbox); +} + void LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) { @@ -238,20 +328,62 @@ LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem) } +//void +//LPEPowerClip::transform_multiply(Geom::Affine const& postmul, bool set) +//{ +// SPDocument * doc = SP_ACTIVE_DOCUMENT; +// SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); +// if (clip_path && lock) { +// std::vector clip_path_list = clip_path->childList(true); +// Glib::ustring clip_id = (Glib::ustring)clip_path->getId(); +// Glib::ustring box_id = clip_id + (Glib::ustring)"_box"; +// for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { +// SPItem * clip_data = SP_ITEM(*iter); +// if(inverse && lock) { +// removeInverse(clip_data); +// } +// if (lock) { +// clip_data->transform *= postmul; +//// if (!inverse) { +//// SPDesktop *desktop = SP_ACTIVE_DESKTOP; +//// if (desktop) { +//// if (tools_isactive(desktop, TOOLS_NODES)) { +//// Inkscape::Selection * sel = SP_ACTIVE_DESKTOP->getSelection(); +//// SPItem * item = sel->singleItem(); +//// if (item != NULL) { +//// sel->remove(item); +//// sel->add(item); +//// } +//// } +//// } +//// } +// } +// if(inverse && lock) { +// doBeforeEffect(sp_lpe_item); +// } +// } +// } +// //cycle through all parameters. Most parameters will not need transformation, but path and point params +// for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { +// Parameter * param = *it; +// param->param_transform_multiply(postmul, set); +// } +// toggleClipVisibility(); +// toggleClipVisibility(); +//} + void LPEPowerClip::flattenClip(SPItem * clip_data, Geom::PathVector &path_in) { - SPShape *shape = dynamic_cast(clip_data); - SPGroup *group = dynamic_cast(clip_data); - if (group) { - std::vector item_list = sp_item_group_item_list(group); + if (SP_IS_GROUP(clip_data)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; flattenClip(subitem, path_in); } - } else if (shape) { + } else if (SP_IS_PATH(clip_data)) { SPCurve * c = NULL; - c = shape->getCurve(); + c = SP_SHAPE(clip_data)->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(c_pv, path_in); @@ -276,7 +408,7 @@ void sp_inverse_powerclip(Inkscape::Selection *sel) { lpe->getRepr()->setAttribute("inverse", "true"); lpe->getRepr()->setAttribute("flatten", "false"); lpe->getRepr()->setAttribute("hide_clip", "false"); - //dynamic_cast(lpe)->convertShapes(); + dynamic_cast(lpe)->convertShapes(); } } } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index f5e50ab9e9..6f99d220f6 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -20,10 +20,13 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual Gtk::Widget * newWidget(); + //virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); + void convertShapes(); private: HiddenParam is_inverse; HiddenParam uri; @@ -32,6 +35,7 @@ private: BoolParam hide_clip; Geom::Path clip_box; Geom::Affine base; + bool convert_shapes; }; void sp_inverse_powerclip(Inkscape::Selection *sel); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 76c3b7d8f2..b63d1635ee 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -941,8 +941,8 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) top_group->applyToClipPath(clipmaskto); top_group->applyToMask(clipmaskto); } - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::iterator iter=item_list.begin();iter!=item_list.end();++iter) { + std::vector const item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index a0953ab194..7542f292c5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -204,7 +204,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool clipmask) { +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { if (!curve) { return false; @@ -236,13 +236,13 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool clipmas // yet, we don't alter the path return false; } - if (clipmask && !lpe->apply_to_clippath_and_mask) { + if (is_clip_or_mask && !lpe->apply_to_clippath_and_mask) { continue; } - // Groups have their doBeforeEffect called elsewhere + lpe->setCurrentShape(current); lpe->pathvector_before_effect = curve->get_pathvector(); - + // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); } @@ -260,13 +260,11 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool clipmas return false; } - lpe->pathvector_after_effect = curve->get_pathvector(); + lpe->pathvector_after_effect = curve->get_pathvector(); if (!SP_IS_GROUP(this)) { lpe->doAfterEffect(this); } - - lpe->pathvector_after_effect = curve->get_pathvector(); - } + } } } return true; @@ -670,7 +668,7 @@ bool SPLPEItem::hasPathEffectRecursive() const } void -SPLPEItem::applyToClipPath(SPLPEItem* to) +SPLPEItem::applyToClipPath(SPItem* to) { SPClipPath *clip_path = to->clip_ref->getObject(); if(clip_path) { @@ -683,7 +681,7 @@ SPLPEItem::applyToClipPath(SPLPEItem* to) } void -SPLPEItem::applyToMask(SPLPEItem* to) +SPLPEItem::applyToMask(SPItem* to) { SPMask *mask = to->mask_ref->getObject(); if(mask) { @@ -696,11 +694,10 @@ SPLPEItem::applyToMask(SPLPEItem* to) } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPLPEItem* to) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) { - SPGroup *group = dynamic_cast(clip_mask); - SPPath *path = dynamic_cast(clip_mask); - SPShape *shape = dynamic_cast(clip_mask); + SPGroup *group = dynamic_cast(clip_mask); + SPShape *shape = dynamic_cast(clip_mask); if (group) { std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -709,7 +706,9 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPLPEItem* to) } } else if (shape) { SPCurve * c = NULL; - if (to == this) { + SPLPEItem *tolpe = dynamic_cast(to); + SPPath *path = dynamic_cast(clip_mask); + if (tolpe && tolpe == this) { c = shape->getCurveBeforeLPE(); } else { c = shape->getCurve(); @@ -717,11 +716,17 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPLPEItem* to) if (c) { bool success = false; try { - success = this->performPathEffect(c, shape, true); - if (!path) { - shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); - shape->setCurve(c, TRUE); - shape->setCurveInsync( c, TRUE); + if(SP_IS_GROUP(this)){ + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + if (!path) { + shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); + shape->setCurve(c, TRUE); + shape->setCurveInsync( c, TRUE); + } } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -732,13 +737,24 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPLPEItem* to) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - if (c) { - if (success) { - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); + // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE + if (success && c) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull or doeffect stack return null.. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } } - c->unref(); + } + if (c) { + c->unref(); } } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 2c3554952e..a9d0864d83 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -70,7 +70,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, SPShape *current, bool clipmask = false); + bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; @@ -92,9 +92,9 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void applyToMask(SPLPEItem* to); - void applyToClipPath(SPLPEItem* to); - void applyToClipPathOrMask(SPItem * clip_mask, SPLPEItem* to); + void applyToMask(SPItem* to); + void applyToClipPath(SPItem* to); + void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index eee67c4bb4..3713b2844a 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -374,7 +374,7 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->applyToClipPath(this); this->applyToMask(this); } - } if (_curve_before_lpe && hasPathEffectRecursive()) { + } else if (_curve_before_lpe && hasPathEffectRecursive()) { SPCurve *curve = _curve_before_lpe->copy(); this->setCurveInsync(curve, TRUE); if (write) { -- GitLab From 423f21e45349cfdcf381d9c63b2e6ed6d9e9fab3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 5 Nov 2017 13:14:49 +0100 Subject: [PATCH 06/57] woring on clipmask --- src/live_effects/effect.cpp | 5 +++-- src/live_effects/effect.h | 3 ++- src/live_effects/lpe-bendpath.cpp | 8 +++++--- src/live_effects/lpe-knot.cpp | 2 +- src/live_effects/lpe-knot.h | 2 +- src/live_effects/lpe-line_segment.cpp | 2 +- src/live_effects/lpe-line_segment.h | 2 +- src/live_effects/lpe-perspective-envelope.cpp | 2 +- src/live_effects/lpe-perspective-envelope.h | 2 +- src/live_effects/lpe-perspective_path.cpp | 2 +- src/live_effects/lpe-perspective_path.h | 2 +- src/live_effects/lpe-powerclip.cpp | 4 ++-- src/live_effects/lpe-powerclip.h | 2 +- src/live_effects/lpe-powermask.cpp | 4 ++-- src/live_effects/lpe-powermask.h | 2 +- src/live_effects/lpe-rough-hatches.cpp | 2 +- src/live_effects/lpe-rough-hatches.h | 2 +- src/live_effects/lpe-simplify.cpp | 2 +- src/live_effects/lpe-simplify.h | 2 +- src/live_effects/lpe-vonkoch.cpp | 2 +- src/live_effects/lpe-vonkoch.h | 2 +- src/sp-item-group.cpp | 10 +++++++--- src/sp-lpe-item.cpp | 14 +++++--------- src/sp-path.cpp | 8 +++----- 24 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index f083a1d53d..c0cf797256 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -524,6 +524,7 @@ Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) //Do nothing for simple effects } + void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) { is_load = false; @@ -542,10 +543,10 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) doOnApply(lpeitem); } -void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) +void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool is_clip_or_mask) { sp_lpe_item = const_cast(lpeitem); - doBeforeEffect(lpeitem); + doBeforeEffect(lpeitem, is_clip_or_mask); update_helperpath(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index f1330d45ea..26b10eea43 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -68,7 +68,7 @@ public: void setSelectedNodePoints(std::vector sNP); bool isNodePointSelected(Geom::Point const &nodePoint) const; virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void doOnRemove (SPLPEItem const* lpeitem); @@ -132,6 +132,7 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_mask; + bool is_clip_or_mask;//Not a group and the effect is applied to clip or mask bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool is_load; bool upd_params; diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index ff5f738ebc..487b11c27d 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -76,11 +76,13 @@ LPEBendPath::~LPEBendPath() } void -LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) +LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { // get the item bounding box - original_bbox(lpeitem); - original_height = boundingbox_Y.max() - boundingbox_Y.min(); + if (!is_clip_or_mask) { + original_bbox(lpeitem); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); + } } Geom::Piecewise > diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 22c548c1d6..b28ff1706f 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -529,7 +529,7 @@ collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::v void -LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem) +LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { using namespace Geom; original_bbox(lpeitem); diff --git a/src/live_effects/lpe-knot.h b/src/live_effects/lpe-knot.h index ac518b97c6..adfbd67933 100644 --- a/src/live_effects/lpe-knot.h +++ b/src/live_effects/lpe-knot.h @@ -56,7 +56,7 @@ public: LPEKnot(LivePathEffectObject *lpeobject); virtual ~LPEKnot(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual Geom::PathVector doEffect_path (Geom::PathVector const & input_path); /* the knotholder entity classes must be declared friends */ diff --git a/src/live_effects/lpe-line_segment.cpp b/src/live_effects/lpe-line_segment.cpp index fd23da8049..30f8cb58d5 100644 --- a/src/live_effects/lpe-line_segment.cpp +++ b/src/live_effects/lpe-line_segment.cpp @@ -41,7 +41,7 @@ LPELineSegment::~LPELineSegment() } void -LPELineSegment::doBeforeEffect (SPLPEItem const* lpeitem) +LPELineSegment::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { Inkscape::UI::Tools::lpetool_get_limiting_bbox_corners(lpeitem->document, bboxA, bboxB); } diff --git a/src/live_effects/lpe-line_segment.h b/src/live_effects/lpe-line_segment.h index def828fe27..9f41d65c7b 100644 --- a/src/live_effects/lpe-line_segment.h +++ b/src/live_effects/lpe-line_segment.h @@ -32,7 +32,7 @@ public: LPELineSegment(LivePathEffectObject *lpeobject); virtual ~LPELineSegment(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 3cff83fedc..f2f4a4a195 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -460,7 +460,7 @@ LPEPerspectiveEnvelope::horizontal(PointParam ¶m_one, PointParam ¶m_two, } void -LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) +LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { original_bbox(lpeitem); Geom::Line vert(Geom::Point(boundingbox_X.middle(),boundingbox_Y.max()), Geom::Point(boundingbox_X.middle(), boundingbox_Y.min())); diff --git a/src/live_effects/lpe-perspective-envelope.h b/src/live_effects/lpe-perspective-envelope.h index 727b7839d4..b3214fcd00 100644 --- a/src/live_effects/lpe-perspective-envelope.h +++ b/src/live_effects/lpe-perspective-envelope.h @@ -46,7 +46,7 @@ public: virtual void horizontal(PointParam ¶mA,PointParam ¶mB,Geom::Line horiz); - virtual void doBeforeEffect(SPLPEItem const* lpeitem); + virtual void doBeforeEffect(SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual Gtk::Widget * newWidget(); diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 435c91c2d7..9712846906 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -80,7 +80,7 @@ LPEPerspectivePath::doOnApply(SPLPEItem const* lpeitem) } } void -LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) +LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { original_bbox(lpeitem, true); SPLPEItem * item = const_cast(lpeitem); diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index 87ee453ff8..24e2a5e3ca 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -33,7 +33,7 @@ class LPEPerspectivePath : public Effect, GroupBBoxEffect { public: LPEPerspectivePath(LivePathEffectObject *lpeobject); virtual ~LPEPerspectivePath(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 18276270d6..f03b0538b5 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -41,7 +41,7 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) LPEPowerClip::~LPEPowerClip() {} void -LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ +LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask){ SPObject * clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); if(hide_clip && clip_path) { SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -324,7 +324,7 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ void LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem) { - doBeforeEffect(lpeitem); + doBeforeEffect(lpeitem, false); } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 6f99d220f6..b16cd8eb65 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -17,7 +17,7 @@ class LPEPowerClip : public Effect { public: LPEPowerClip(LivePathEffectObject *lpeobject); virtual ~LPEPowerClip(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 883467b6a2..c85c7d4fb2 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -46,7 +46,7 @@ LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) LPEPowerMask::~LPEPowerMask() {} void -LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ +LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask){ //To avoid close of color dialog and better performance on change color SPObject * mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); if(hide_mask && mask) { @@ -274,7 +274,7 @@ LPEPowerMask::setMask(){ void LPEPowerMask::doOnVisibilityToggled(SPLPEItem const* lpeitem) { - doBeforeEffect(lpeitem); + doBeforeEffect(lpeitem, false); } void diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index e81b34fe33..4f7970e7a3 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -19,7 +19,7 @@ class LPEPowerMask : public Effect { public: LPEPowerMask(LivePathEffectObject *lpeobject); virtual ~LPEPowerMask(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual void doEffect (SPCurve * curve); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp index d832b36150..59c2d3f86a 100644 --- a/src/live_effects/lpe-rough-hatches.cpp +++ b/src/live_effects/lpe-rough-hatches.cpp @@ -532,7 +532,7 @@ LPERoughHatches::smoothSnake(std::vector > const &linearSnake } void -LPERoughHatches::doBeforeEffect (SPLPEItem const*/*lpeitem*/) +LPERoughHatches::doBeforeEffect (SPLPEItem const*/*lpeitem*/, bool is_clip_or_mask) { using namespace Geom; top_edge_variation.resetRandomizer(); diff --git a/src/live_effects/lpe-rough-hatches.h b/src/live_effects/lpe-rough-hatches.h index f8454e1eae..4526e1144a 100644 --- a/src/live_effects/lpe-rough-hatches.h +++ b/src/live_effects/lpe-rough-hatches.h @@ -33,7 +33,7 @@ public: virtual void resetDefaults(SPItem const* item); - virtual void doBeforeEffect(SPLPEItem const* item); + virtual void doBeforeEffect(SPLPEItem const* item, bool is_clip_or_mask); std::vector generateLevels(Geom::Interval const &domain, double x_org); diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 5de9816bb9..aff42918bd 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -58,7 +58,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) LPESimplify::~LPESimplify() {} void -LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) +LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { if(!hp.empty()) { hp.clear(); diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index 6c407f572c..52c7875658 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -21,7 +21,7 @@ public: virtual void doEffect(SPCurve *curve); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); virtual void generateHelperPathAndSmooth(Geom::PathVector &result); diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index b9fd8908a6..b5db1b8bd3 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -236,7 +236,7 @@ LPEVonKoch::doEffect_path (Geom::PathVector const & path_in) */ void -LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) +LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) { using namespace Geom; original_bbox(lpeitem); diff --git a/src/live_effects/lpe-vonkoch.h b/src/live_effects/lpe-vonkoch.h index bffbebd544..8b6ecbb044 100644 --- a/src/live_effects/lpe-vonkoch.h +++ b/src/live_effects/lpe-vonkoch.h @@ -53,7 +53,7 @@ public: virtual void resetDefaults(SPItem const* item); - virtual void doBeforeEffect(SPLPEItem const* item); + virtual void doBeforeEffect(SPLPEItem const* item, bool is_clip_or_mask); //Usefull?? // protected: diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index b63d1635ee..e1743d9f27 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -916,7 +916,7 @@ void SPGroup::update_patheffect(bool write) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj && lpeobj->get_lpe()) { - lpeobj->get_lpe()->doBeforeEffect_impl(this); + lpeobj->get_lpe()->doBeforeEffect_impl(this, false); } } @@ -930,13 +930,17 @@ void SPGroup::update_patheffect(bool write) { lpeobj->get_lpe()->doAfterEffect(this); } } + } else if (pathEffectsEnabled()) { + //here force reset lpe + this->applyToClipPath(this); + this->applyToMask(this); } } static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) { - SPLPEItem* clipmaskto = dynamic_cast(group); + SPItem* clipmaskto = dynamic_cast(group); if (clipmaskto) { top_group->applyToClipPath(clipmaskto); top_group->applyToMask(clipmaskto); @@ -950,7 +954,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } else { SPShape* sub_shape = dynamic_cast(sub_item); SPPath* sub_path = dynamic_cast(sub_item); - clipmaskto = dynamic_cast(sub_item); + clipmaskto = dynamic_cast(sub_item); if (clipmaskto) { top_group->applyToClipPath(clipmaskto); top_group->applyToMask(clipmaskto); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 7542f292c5..e5e55bb132 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -244,7 +244,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip lpe->pathvector_before_effect = curve->get_pathvector(); // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect_impl(this); + lpe->doBeforeEffect_impl(this, is_clip_or_mask); } try { @@ -705,14 +705,10 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) applyToClipPathOrMask(subitem, to); } } else if (shape) { - SPCurve * c = NULL; - SPLPEItem *tolpe = dynamic_cast(to); - SPPath *path = dynamic_cast(clip_mask); - if (tolpe && tolpe == this) { - c = shape->getCurveBeforeLPE(); - } else { - c = shape->getCurve(); - } + SPCurve* c = NULL; + SPPath* path = dynamic_cast(clip_mask); + shape->update_patheffect(true); + c = shape->getCurve(); if (c) { bool success = false; try { diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 3713b2844a..59d916dfb2 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -370,11 +370,7 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); - if (success) { - this->applyToClipPath(this); - this->applyToMask(this); - } - } else if (_curve_before_lpe && hasPathEffectRecursive()) { + } else if(_curve_before_lpe) { SPCurve *curve = _curve_before_lpe->copy(); this->setCurveInsync(curve, TRUE); if (write) { @@ -393,6 +389,8 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); } + this->applyToClipPath(this); + this->applyToMask(this); } -- GitLab From 9ae07f82beede303e4e93169846295eb25770887 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 5 Nov 2017 20:29:20 +0100 Subject: [PATCH 07/57] woring on clipmask --- src/box3d-side.cpp | 2 + src/live_effects/effect.cpp | 6 +- src/live_effects/effect.h | 4 +- src/live_effects/lpe-bendpath.cpp | 2 +- src/live_effects/lpe-bendpath.cpp.orig | 247 ++++++++++++++++++ src/live_effects/lpe-knot.cpp | 2 +- src/live_effects/lpe-knot.h | 2 +- src/live_effects/lpe-line_segment.cpp | 2 +- src/live_effects/lpe-line_segment.h | 2 +- src/live_effects/lpe-perspective-envelope.cpp | 2 +- src/live_effects/lpe-perspective-envelope.h | 2 +- src/live_effects/lpe-perspective_path.cpp | 2 +- src/live_effects/lpe-perspective_path.h | 2 +- src/live_effects/lpe-powerclip.cpp | 4 +- src/live_effects/lpe-powerclip.h | 2 +- src/live_effects/lpe-powermask.cpp | 4 +- src/live_effects/lpe-powermask.h | 2 +- src/live_effects/lpe-rough-hatches.cpp | 2 +- src/live_effects/lpe-rough-hatches.h | 2 +- src/live_effects/lpe-simplify.cpp | 2 +- src/live_effects/lpe-simplify.h | 2 +- src/live_effects/lpe-vonkoch.cpp | 2 +- src/live_effects/lpe-vonkoch.h | 2 +- src/sp-ellipse.cpp | 2 + src/sp-item-group.cpp | 16 +- src/sp-lpe-item.cpp | 30 ++- src/sp-lpe-item.h | 1 + src/sp-path.cpp | 43 +-- src/sp-shape.cpp | 6 +- src/sp-shape.h | 2 +- src/sp-spiral.cpp | 2 + src/sp-star.cpp | 2 + 32 files changed, 342 insertions(+), 63 deletions(-) create mode 100644 src/live_effects/lpe-bendpath.cpp.orig diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index b621573a5b..af3703224b 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -202,6 +202,8 @@ void Box3DSide::set_shape() { if (success) { this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); } c_lpe->unref(); diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index c0cf797256..9586155654 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -372,6 +372,7 @@ Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) Effect::Effect(LivePathEffectObject *lpeobject) : apply_to_clippath_and_mask(false), + is_clip_or_mask(false), _provides_knotholder_entities(false), oncanvasedit_it(0), is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), @@ -543,10 +544,11 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) doOnApply(lpeitem); } -void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool is_clip_or_mask) +void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask) { sp_lpe_item = const_cast(lpeitem); - doBeforeEffect(lpeitem, is_clip_or_mask); + is_clip_or_mask = clip_or_mask; + doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 26b10eea43..9b1b8a7eb2 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -63,12 +63,12 @@ public: //basically, to get this method called before the derived classes, a bit //of indirection is needed. We first call these methods, then the below. void doOnApply_impl(SPLPEItem const* lpeitem); - void doBeforeEffect_impl(SPLPEItem const* lpeitem); + void doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask); void setCurrentZoom(double cZ); void setSelectedNodePoints(std::vector sNP); bool isNodePointSelected(Geom::Point const &nodePoint) const; virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void doOnRemove (SPLPEItem const* lpeitem); diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 487b11c27d..2fd2b75c26 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -76,7 +76,7 @@ LPEBendPath::~LPEBendPath() } void -LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box if (!is_clip_or_mask) { diff --git a/src/live_effects/lpe-bendpath.cpp.orig b/src/live_effects/lpe-bendpath.cpp.orig new file mode 100644 index 0000000000..487b11c27d --- /dev/null +++ b/src/live_effects/lpe-bendpath.cpp.orig @@ -0,0 +1,247 @@ +/* + * Copyright (C) Johan Engelen 2007 + * Copyright (C) Steren Giannini 2008 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-bendpath.h" +#include "sp-item-group.h" +#include "knot-holder-entity.h" +#include "knotholder.h" +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +using std::vector; + + +/* Theory in e-mail from J.F. Barraud +Let B be the skeleton path, and P the pattern (the path to be deformed). + +P is a map t --> P(t) = ( x(t), y(t) ). +B is a map t --> B(t) = ( a(t), b(t) ). + +The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to +U(s) is s itself. + +We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90�. Call this normal vector N(s). + +The basic deformation associated to B is then given by: + + (x,y) --> U(x)+y*N(x) + +(i.e. we go for distance x along the path, and then for distance y along the normal) + +Of course this formula needs some minor adaptations (as is it depends on the absolute position of P for instance, so a little translation is needed +first) but I think we can first forget about them. +*/ + +namespace Inkscape { +namespace LivePathEffect { + +Geom::PathVector bp_helper_path; +namespace BeP { +class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthBendPath(LPEBendPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // BeP + +LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), + original_height(0.0), + prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), + scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), + vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) +{ + registerParameter( &bend_path ); + registerParameter( &prop_scale); + registerParameter( &scale_y_rel); + registerParameter( &vertical_pattern); + + prop_scale.param_set_digits(3); + prop_scale.param_set_increments(0.01, 0.10); + + _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; + concatenate_before_pwd2 = true; +} + +LPEBendPath::~LPEBendPath() +{ + +} + +void +LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +{ + // get the item bounding box + if (!is_clip_or_mask) { + original_bbox(lpeitem); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); + } +} + +Geom::Piecewise > +LPEBendPath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + using namespace Geom; + +/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */ + + if (bend_path.changed) { + uskeleton = arc_length_parametrization(Piecewise >(bend_path.get_pwd2()),2,.1); + uskeleton = remove_short_cuts(uskeleton,.01); + n = rot90(derivative(uskeleton)); + n = force_continuity(remove_short_cuts(n,.01)); + + bend_path.changed = false; + } + + if (uskeleton.empty()) { + return pwd2_in; /// \todo or throw an exception instead? might be better to throw an exception so that the UI can display an error message or smth + } + + D2 > patternd2 = make_cuts_independent(pwd2_in); + Piecewise x = vertical_pattern.get_value() ? Piecewise(patternd2[1]) : Piecewise(patternd2[0]); + Piecewise y = vertical_pattern.get_value() ? Piecewise(patternd2[0]) : Piecewise(patternd2[1]); + + Interval bboxHorizontal = vertical_pattern.get_value() ? boundingbox_Y : boundingbox_X; + Interval bboxVertical = vertical_pattern.get_value() ? boundingbox_X : boundingbox_Y; + + //+0.1 in x fix bug #1658855 + //We use the group bounding box size or the path bbox size to translate well x and y + x-= bboxHorizontal.min() + 0.1; + y-= bboxVertical.middle(); + + double scaling = uskeleton.cuts.back()/bboxHorizontal.extent(); + + if (scaling != 1.0) { + x*=scaling; + } + + if ( scale_y_rel.get_value() ) { + y*=(scaling*prop_scale); + } else { + if (prop_scale != 1.0) y *= prop_scale; + } + + Piecewise > output = compose(uskeleton,x) + y*compose(n,x); + return output; +} + +void +LPEBendPath::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + + original_bbox(SP_LPE_ITEM(item)); + + Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); + Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); + + if ( Geom::are_near(start,end) ) { + end += Geom::Point(1.,0.); + } + + Geom::Path path; + path.start( start ); + path.appendNew( end ); + bend_path.set_new_value( path.toPwSb(), true ); +} + +void +LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) +{ + if (sp_lpe_item) { + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); + } +} + +void +LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(bp_helper_path); +} + +void +LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) +{ + KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this); + e->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace BeP { + +void +KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEBendPath *lpe = dynamic_cast (_effect); + + Geom::Point const s = snap_knot_position(p, state); + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/live_effect/bend/width", lpe->prop_scale); + + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthBendPath::knot_get() const +{ + LPEBendPath *lpe = dynamic_cast (_effect); + + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA,(*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; + + bp_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew(ptA); + bp_helper_path.push_back(hp); + hp.clear(); + + return result_point; +} +} // namespace BeP +} // namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index b28ff1706f..22c548c1d6 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -529,7 +529,7 @@ collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::v void -LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); diff --git a/src/live_effects/lpe-knot.h b/src/live_effects/lpe-knot.h index adfbd67933..ac518b97c6 100644 --- a/src/live_effects/lpe-knot.h +++ b/src/live_effects/lpe-knot.h @@ -56,7 +56,7 @@ public: LPEKnot(LivePathEffectObject *lpeobject); virtual ~LPEKnot(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & input_path); /* the knotholder entity classes must be declared friends */ diff --git a/src/live_effects/lpe-line_segment.cpp b/src/live_effects/lpe-line_segment.cpp index 30f8cb58d5..fd23da8049 100644 --- a/src/live_effects/lpe-line_segment.cpp +++ b/src/live_effects/lpe-line_segment.cpp @@ -41,7 +41,7 @@ LPELineSegment::~LPELineSegment() } void -LPELineSegment::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPELineSegment::doBeforeEffect (SPLPEItem const* lpeitem) { Inkscape::UI::Tools::lpetool_get_limiting_bbox_corners(lpeitem->document, bboxA, bboxB); } diff --git a/src/live_effects/lpe-line_segment.h b/src/live_effects/lpe-line_segment.h index 9f41d65c7b..def828fe27 100644 --- a/src/live_effects/lpe-line_segment.h +++ b/src/live_effects/lpe-line_segment.h @@ -32,7 +32,7 @@ public: LPELineSegment(LivePathEffectObject *lpeobject); virtual ~LPELineSegment(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index f2f4a4a195..3cff83fedc 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -460,7 +460,7 @@ LPEPerspectiveEnvelope::horizontal(PointParam ¶m_one, PointParam ¶m_two, } void -LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem); Geom::Line vert(Geom::Point(boundingbox_X.middle(),boundingbox_Y.max()), Geom::Point(boundingbox_X.middle(), boundingbox_Y.min())); diff --git a/src/live_effects/lpe-perspective-envelope.h b/src/live_effects/lpe-perspective-envelope.h index b3214fcd00..727b7839d4 100644 --- a/src/live_effects/lpe-perspective-envelope.h +++ b/src/live_effects/lpe-perspective-envelope.h @@ -46,7 +46,7 @@ public: virtual void horizontal(PointParam ¶mA,PointParam ¶mB,Geom::Line horiz); - virtual void doBeforeEffect(SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect(SPLPEItem const* lpeitem); virtual Gtk::Widget * newWidget(); diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 9712846906..435c91c2d7 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -80,7 +80,7 @@ LPEPerspectivePath::doOnApply(SPLPEItem const* lpeitem) } } void -LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem, true); SPLPEItem * item = const_cast(lpeitem); diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index 24e2a5e3ca..87ee453ff8 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -33,7 +33,7 @@ class LPEPerspectivePath : public Effect, GroupBBoxEffect { public: LPEPerspectivePath(LivePathEffectObject *lpeobject); virtual ~LPEPerspectivePath(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index f03b0538b5..18276270d6 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -41,7 +41,7 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) LPEPowerClip::~LPEPowerClip() {} void -LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask){ +LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ SPObject * clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); if(hide_clip && clip_path) { SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -324,7 +324,7 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ void LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem) { - doBeforeEffect(lpeitem, false); + doBeforeEffect(lpeitem); } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index b16cd8eb65..6f99d220f6 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -17,7 +17,7 @@ class LPEPowerClip : public Effect { public: LPEPowerClip(LivePathEffectObject *lpeobject); virtual ~LPEPowerClip(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index c85c7d4fb2..883467b6a2 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -46,7 +46,7 @@ LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) LPEPowerMask::~LPEPowerMask() {} void -LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask){ +LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ //To avoid close of color dialog and better performance on change color SPObject * mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); if(hide_mask && mask) { @@ -274,7 +274,7 @@ LPEPowerMask::setMask(){ void LPEPowerMask::doOnVisibilityToggled(SPLPEItem const* lpeitem) { - doBeforeEffect(lpeitem, false); + doBeforeEffect(lpeitem); } void diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index 4f7970e7a3..e81b34fe33 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -19,7 +19,7 @@ class LPEPowerMask : public Effect { public: LPEPowerMask(LivePathEffectObject *lpeobject); virtual ~LPEPowerMask(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doEffect (SPCurve * curve); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp index 59c2d3f86a..d832b36150 100644 --- a/src/live_effects/lpe-rough-hatches.cpp +++ b/src/live_effects/lpe-rough-hatches.cpp @@ -532,7 +532,7 @@ LPERoughHatches::smoothSnake(std::vector > const &linearSnake } void -LPERoughHatches::doBeforeEffect (SPLPEItem const*/*lpeitem*/, bool is_clip_or_mask) +LPERoughHatches::doBeforeEffect (SPLPEItem const*/*lpeitem*/) { using namespace Geom; top_edge_variation.resetRandomizer(); diff --git a/src/live_effects/lpe-rough-hatches.h b/src/live_effects/lpe-rough-hatches.h index 4526e1144a..f8454e1eae 100644 --- a/src/live_effects/lpe-rough-hatches.h +++ b/src/live_effects/lpe-rough-hatches.h @@ -33,7 +33,7 @@ public: virtual void resetDefaults(SPItem const* item); - virtual void doBeforeEffect(SPLPEItem const* item, bool is_clip_or_mask); + virtual void doBeforeEffect(SPLPEItem const* item); std::vector generateLevels(Geom::Interval const &domain, double x_org); diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index aff42918bd..5de9816bb9 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -58,7 +58,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) LPESimplify::~LPESimplify() {} void -LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) { if(!hp.empty()) { hp.clear(); diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index 52c7875658..6c407f572c 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -21,7 +21,7 @@ public: virtual void doEffect(SPCurve *curve); - virtual void doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void generateHelperPathAndSmooth(Geom::PathVector &result); diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index b5db1b8bd3..b9fd8908a6 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -236,7 +236,7 @@ LPEVonKoch::doEffect_path (Geom::PathVector const & path_in) */ void -LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem, bool is_clip_or_mask) +LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); diff --git a/src/live_effects/lpe-vonkoch.h b/src/live_effects/lpe-vonkoch.h index 8b6ecbb044..bffbebd544 100644 --- a/src/live_effects/lpe-vonkoch.h +++ b/src/live_effects/lpe-vonkoch.h @@ -53,7 +53,7 @@ public: virtual void resetDefaults(SPItem const* item); - virtual void doBeforeEffect(SPLPEItem const* item, bool is_clip_or_mask); + virtual void doBeforeEffect(SPLPEItem const* item); //Usefull?? // protected: diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index d1495ee076..b3780314db 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -492,6 +492,8 @@ void SPGenericEllipse::set_shape(bool force) if (success) { this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); } c_lpe->unref(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index e1743d9f27..e4645ebb4e 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -930,10 +930,6 @@ void SPGroup::update_patheffect(bool write) { lpeobj->get_lpe()->doAfterEffect(this); } } - } else if (pathEffectsEnabled()) { - //here force reset lpe - this->applyToClipPath(this); - this->applyToMask(this); } } @@ -952,9 +948,9 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) if (sub_group) { sp_group_perform_patheffect(sub_group, top_group, write); } else { - SPShape* sub_shape = dynamic_cast(sub_item); - SPPath* sub_path = dynamic_cast(sub_item); - clipmaskto = dynamic_cast(sub_item); + SPShape* sub_shape = dynamic_cast(sub_item); + SPPath* sub_path = dynamic_cast(sub_item); + clipmaskto = dynamic_cast(sub_item); if (clipmaskto) { top_group->applyToClipPath(clipmaskto); top_group->applyToMask(clipmaskto); @@ -980,7 +976,11 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } - c = sub_shape->getCurve(); + if (sub_shape->isFirstLPE(top_group)) { + c = sub_shape->getCurveBeforeLPE(); + } else { + c = sub_shape->getCurve(); + } bool success = false; // only run LPEs when the shape has a curve defined if (c) { diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e5e55bb132..dab1eb9da2 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -368,7 +368,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_data), keep_paths, !lpeitem->hasPathEffectRecursive()); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_data), keep_paths, SP_IS_PATH(lpeitem) && !lpeitem->hasPathEffectRecursive()); } } @@ -377,7 +377,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, std::vector mask_path_list = mask_path->childList(true); for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { SPObject * mask_data = *iter; - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask_path), keep_paths, !lpeitem->hasPathEffectRecursive()); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask_path), keep_paths, SP_IS_PATH(lpeitem) && !lpeitem->hasPathEffectRecursive()); } } @@ -386,7 +386,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths, false); } } } else if (SP_IS_PATH(lpeitem)) { @@ -667,6 +667,18 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +bool SPLPEItem::isFirstLPE(SPLPEItem const* compare) const +{ + if (hasPathEffectRecursive()) { + SPLPEItem const* nearest = this; + while (!nearest->hasPathEffect()) { + nearest = SP_LPE_ITEM(nearest->parent); + } + return nearest == compare; + } + return false; +} + void SPLPEItem::applyToClipPath(SPItem* to) { @@ -696,8 +708,9 @@ SPLPEItem::applyToMask(SPItem* to) void SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) { - SPGroup *group = dynamic_cast(clip_mask); - SPShape *shape = dynamic_cast(clip_mask); + SPGroup* group = dynamic_cast(clip_mask); + SPShape* shape = dynamic_cast(clip_mask); + SPLPEItem* tolpe = dynamic_cast(to); if (group) { std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -707,8 +720,11 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) } else if (shape) { SPCurve* c = NULL; SPPath* path = dynamic_cast(clip_mask); - shape->update_patheffect(true); - c = shape->getCurve(); + if (tolpe->isFirstLPE(this)) { + c = shape->getCurveBeforeLPE(true); + } else { + c = shape->getCurve(); + } if (c) { bool success = false; try { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index a9d0864d83..54394f62e5 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -76,6 +76,7 @@ public: bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; + bool isFirstLPE(SPLPEItem const* compare) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 59d916dfb2..e767b489e4 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -354,7 +354,8 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); } else { repr->setAttribute("d", NULL); } - + this->applyToClipPath(this); + this->applyToMask(this); } else if (!success) { // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { @@ -370,27 +371,27 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); - } else if(_curve_before_lpe) { - SPCurve *curve = _curve_before_lpe->copy(); - this->setCurveInsync(curve, TRUE); - if (write) { - // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. -#ifdef PATH_VERBOSE -g_message("sp_path_update_patheffect writes 'd' attribute"); -#endif - if (_curve) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - curve->unref(); - } - this->applyToClipPath(this); - this->applyToMask(this); +// } else if(_curve_before_lpe) { +// SPCurve *curve = _curve_before_lpe->copy(); +// this->setCurveInsync(curve, TRUE); +// if (write) { +// // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. +//#ifdef PATH_VERBOSE +//g_message("sp_path_update_patheffect writes 'd' attribute"); +//#endif +// if (_curve) { +// gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); +// repr->setAttribute("d", str); +// g_free(str); +// } else { +// repr->setAttribute("d", NULL); +// } +// } +// this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +// curve->unref(); +// } + } diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 9edf03cbfc..14083dbc3a 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -1025,13 +1025,17 @@ SPCurve * SPShape::getCurve() const /** * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurveBeforeLPE() const +SPCurve * SPShape::getCurveBeforeLPE(bool force) const { if (hasPathEffectRecursive()) { if (_curve_before_lpe) { return this->_curve_before_lpe->copy(); } } else { + //We can force for mask and clippath that dont have real path effect + if (force && _curve_before_lpe) { + return this->_curve_before_lpe->copy(); + } if (_curve) { return _curve->copy(); } diff --git a/src/sp-shape.h b/src/sp-shape.h index fe9d032755..c35233d173 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -40,7 +40,7 @@ public: virtual ~SPShape(); SPCurve * getCurve () const; - SPCurve * getCurveBeforeLPE () const; + SPCurve * getCurveBeforeLPE (bool force = false) const; void setCurve (SPCurve *curve, unsigned int owner); void setCurveInsync (SPCurve *curve, unsigned int owner); void setCurveBeforeLPE (SPCurve *curve); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index cf5486e4c3..1223cecfaf 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -380,6 +380,8 @@ void SPSpiral::set_shape(bool force) { if (success) { this->setCurveInsync( c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); } c_lpe->unref(); diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 68db119999..0af9e04721 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -462,6 +462,8 @@ void SPStar::set_shape(bool force) { if (success) { this->setCurveInsync( c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); } c_lpe->unref(); -- GitLab From d0e80b9393e136bcc0d4fc2cc25587d3375c3faf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 5 Nov 2017 23:25:53 +0100 Subject: [PATCH 08/57] woring on clipmask --- src/sp-lpe-item.cpp | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index dab1eb9da2..44b48ec390 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -363,33 +363,38 @@ static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) { g_return_if_fail(lpeitem != NULL); - SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + SPItem *item = dynamic_cast(lpeitem); + if (!item) { + return; + } + SPGroup *group = dynamic_cast(lpeitem); + SPShape *shape = dynamic_cast(lpeitem); + SPPath *path = dynamic_cast(lpeitem); + SPClipPath *clip_path = item->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPObject * clip_data = *iter; - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_data), keep_paths, SP_IS_PATH(lpeitem) && !lpeitem->hasPathEffectRecursive()); + SPLPEItem* clip_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, shape && !shape->hasPathEffectRecursive()); } } - SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); + SPMask *mask_path = item->mask_ref->getObject(); if(mask_path) { std::vector mask_path_list = mask_path->childList(true); for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { - SPObject * mask_data = *iter; - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask_path), keep_paths, SP_IS_PATH(lpeitem) && !lpeitem->hasPathEffectRecursive()); + SPLPEItem* mask_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, shape && !shape->hasPathEffectRecursive()); } } - if (SP_IS_GROUP(lpeitem)) { + if (group) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - if (SP_IS_LPE_ITEM(subitem)) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths, false); - } + SPLPEItem* subitem = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths, false); } - } else if (SP_IS_PATH(lpeitem)) { + } else if (path) { Inkscape::XML::Node *repr = lpeitem->getRepr(); if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) { @@ -402,7 +407,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, sp_lpe_item_update_patheffect(lpeitem, true, true); } } - } else if (SP_IS_SHAPE(lpeitem)) { + } else if (shape) { Inkscape::XML::Node *repr = lpeitem->getRepr(); if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) { @@ -734,11 +739,6 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); } else { success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - if (!path) { - shape->setCurveInsync( shape->getCurveBeforeLPE(), TRUE); - shape->setCurve(c, TRUE); - shape->setCurveInsync( c, TRUE); - } } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -749,8 +749,12 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE if (success && c) { + if (!path) { + shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); + shape->setCurve(c, TRUE); + shape->setCurveInsync( c, TRUE); + } gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); -- GitLab From 87580ef0b0593f81e3b70eb94acddb12fe1ff086 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 10 Nov 2017 00:24:42 +0100 Subject: [PATCH 09/57] Merge effect fixes with defaults --- src/live_effects/effect.cpp | 32 +- src/live_effects/effect.cpp.orig | 1028 +++++++++++++++++ src/live_effects/effect.h | 1 + src/live_effects/lpe-bspline.cpp | 3 + src/live_effects/lpe-clone-original.cpp | 12 +- src/live_effects/lpe-copy_rotate.cpp | 3 + src/live_effects/lpe-fillet-chamfer.cpp | 12 +- src/live_effects/lpe-fillet-chamfer.cpp.orig | 636 ++++++++++ src/live_effects/lpe-lattice2.cpp | 3 + src/live_effects/lpe-measure-segments.cpp | 91 +- src/live_effects/lpe-mirror_symmetry.cpp | 5 +- src/live_effects/lpe-perspective-envelope.cpp | 3 + src/live_effects/lpe-perspective_path.cpp | 3 + src/live_effects/lpe-powerclip.cpp | 34 +- src/live_effects/lpe-powermask.cpp | 14 +- src/live_effects/lpe-roughen.cpp | 3 + src/live_effects/lpe-simplify.cpp | 3 + src/live_effects/lpe-transform_2pts.cpp | 3 + src/live_effects/parameter/message.cpp | 12 +- src/live_effects/parameter/message.h | 4 +- .../parameter/originalpatharray.cpp | 2 +- src/ui/dialog/livepatheffect-editor.cpp | 32 +- 22 files changed, 1834 insertions(+), 105 deletions(-) create mode 100644 src/live_effects/effect.cpp.orig create mode 100644 src/live_effects/lpe-fillet-chamfer.cpp.orig diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index ab1807819c..b198ea7fbf 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -81,7 +81,7 @@ #include "display/curve.h" #include #include -#include + namespace Inkscape { @@ -386,6 +386,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) upd_params(true), current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden + defaultsopen(false), is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { registerParameter( dynamic_cast(&is_visible) ); @@ -785,6 +786,9 @@ Effect::newWidget() ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -796,7 +800,6 @@ Effect::defaultParamSet() { // use manage here, because after deletion of Effect object, others might still be pointing to this widget. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() ); Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType()); Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType()); @@ -807,21 +810,22 @@ Effect::defaultParamSet() if ((*it)->widget_is_visible) { has_params = true; Parameter * param = *it; + char * param_value_char = param->param_getSVGValue(); Glib::ustring * tip = param->param_getTooltip(); const gchar * key = param->param_key.c_str(); const gchar * value = param->param_label.c_str(); - + gchar* defvalue = param->param_getDefaultSVGValue(); Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + effectkey + (Glib::ustring)"/" + (Glib::ustring)key; bool valid = prefs->getEntry(pref_path).isValid(); const gchar * set_or_upd; - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); if (valid) { set_or_upd = _("Update"); - def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); } else { set_or_upd = _("Set"); ove = Glib::ustring(_("Default value overridden: None\n")); @@ -837,9 +841,9 @@ Effect::defaultParamSet() vbox_param->pack_start(*parameter_label, true, true, 2); Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); - unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param_value_char, defvalue, parameter_label, set, unset)); - set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param_value_char, defvalue, parameter_label, set, unset)); if (!valid) { unset->set_sensitive(false); } @@ -847,6 +851,8 @@ Effect::defaultParamSet() vbox_param->pack_start(*unset, true, true, 2); vbox_expander->pack_start(*vbox_param, true, true, 2); + g_free(defvalue); + g_free(param_value_char); } ++it; } @@ -854,10 +860,10 @@ Effect::defaultParamSet() Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip)); expander->set_use_markup(true); expander->add(*vbox_expander); - expander->set_expanded(false); - vbox->pack_start(*dynamic_cast (expander), true, true, 2); + expander->set_expanded(defaultsopen); + expander->property_expanded().signal_changed().connect(sigc::bind<0>(sigc::mem_fun(*this, &Effect::onDefaultsExpanderChanged), expander )); if (has_params) { - Gtk::Widget *vboxwidg = dynamic_cast(vbox); + Gtk::Widget *vboxwidg = dynamic_cast(expander); vboxwidg->set_margin_bottom(10); vboxwidg->set_margin_top(5); return vboxwidg; @@ -866,6 +872,12 @@ Effect::defaultParamSet() } } +void +Effect::onDefaultsExpanderChanged(Gtk::Expander * expander) +{ + defaultsopen = expander->get_expanded(); +} + void Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { diff --git a/src/live_effects/effect.cpp.orig b/src/live_effects/effect.cpp.orig new file mode 100644 index 0000000000..ab1807819c --- /dev/null +++ b/src/live_effects/effect.cpp.orig @@ -0,0 +1,1028 @@ +/* + * Copyright (C) Johan Engelen 2007 + * Abhishek Sharma + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects + +#ifdef HAVE_CONFIG_H +#include +#endif + +// include effects: +#include "live_effects/lpe-patternalongpath.h" +#include "live_effects/lpe-angle_bisector.h" +#include "live_effects/lpe-attach-path.h" +#include "live_effects/lpe-bendpath.h" +#include "live_effects/lpe-bounding-box.h" +#include "live_effects/lpe-bspline.h" +#include "live_effects/lpe-circle_3pts.h" +#include "live_effects/lpe-circle_with_radius.h" +#include "live_effects/lpe-clone-original.h" +#include "live_effects/lpe-constructgrid.h" +#include "live_effects/lpe-copy_rotate.h" +#include "live_effects/lpe-curvestitch.h" +#include "live_effects/lpe-dynastroke.h" +#include "live_effects/lpe-ellipse_5pts.h" +#include "live_effects/lpe-envelope.h" +#include "live_effects/lpe-extrude.h" +#include "live_effects/lpe-fill-between-many.h" +#include "live_effects/lpe-fill-between-strokes.h" +#include "live_effects/lpe-fillet-chamfer.h" +#include "live_effects/lpe-gears.h" +#include "live_effects/lpe-interpolate.h" +#include "live_effects/lpe-interpolate_points.h" +#include "live_effects/lpe-jointype.h" +#include "live_effects/lpe-knot.h" +#include "live_effects/lpe-lattice2.h" +#include "live_effects/lpe-lattice.h" +#include "live_effects/lpe-line_segment.h" +#include "live_effects/lpe-measure-segments.h" +#include "live_effects/lpe-mirror_symmetry.h" +#include "live_effects/lpe-offset.h" +#include "live_effects/lpe-parallel.h" +#include "live_effects/lpe-path_length.h" +#include "live_effects/lpe-perp_bisector.h" +#include "live_effects/lpe-perspective-envelope.h" +#include "live_effects/lpe-perspective_path.h" +#include "live_effects/lpe-powerclip.h" +#include "live_effects/lpe-powermask.h" +#include "live_effects/lpe-powerstroke.h" +#include "live_effects/lpe-recursiveskeleton.h" +#include "live_effects/lpe-roughen.h" +#include "live_effects/lpe-rough-hatches.h" +#include "live_effects/lpe-ruler.h" +#include "live_effects/lpe-show_handles.h" +#include "live_effects/lpe-simplify.h" +#include "live_effects/lpe-sketch.h" +#include "live_effects/lpe-spiro.h" +#include "live_effects/lpe-tangent_to_curve.h" +#include "live_effects/lpe-transform_2pts.h" +#include "live_effects/lpe-taperstroke.h" +#include "live_effects/lpe-test-doEffect-stack.h" +#include "live_effects/lpe-text_label.h" +#include "live_effects/lpe-vonkoch.h" +#include "live_effects/lpe-embrodery-stitch.h" +#include "live_effects/lpe-bool.h" + +#include "xml/node-event-vector.h" +#include "message-stack.h" +#include "document-private.h" +#include "ui/tools/pen-tool.h" +#include "ui/tools/node-tool.h" +#include "ui/tools-switch.h" +#include "knotholder.h" +#include "path-chemistry.h" +#include "xml/sp-css-attr.h" +#include "live_effects/lpeobject.h" +#include +#include "display/curve.h" +#include +#include +#include + +namespace Inkscape { + +namespace LivePathEffect { + +const Util::EnumData LPETypeData[] = { + // {constant defined in effect-enum.h, N_("name of your effect"), "name of your effect in SVG"} +/* 0.46 */ + {BEND_PATH, N_("Bend"), "bend_path"}, + {GEARS, N_("Gears"), "gears"}, + {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG + {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"}, +/* 0.47 */ + {VONKOCH, N_("VonKoch"), "vonkoch"}, + {KNOT, N_("Knot"), "knot"}, + {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"}, + {SPIRO, N_("Spiro spline"), "spiro"}, + {ENVELOPE, N_("Envelope Deformation"), "envelope"}, + {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"}, + {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"}, + {SKETCH, N_("Sketch"), "sketch"}, + {RULER, N_("Ruler"), "ruler"}, +/* 0.91 */ + {POWERSTROKE, N_("Power stroke"), "powerstroke"}, + {CLONE_ORIGINAL, N_("Clone original"), "clone_original"}, +/* 0.92 */ + {SIMPLIFY, N_("Simplify"), "simplify"}, + {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, + {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, //TODO:Wrong name with "-" + {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, + {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"}, + {SHOW_HANDLES, N_("Show handles"), "show_handles"}, + {ROUGHEN, N_("Roughen"), "roughen"}, + {BSPLINE, N_("BSpline"), "bspline"}, + {JOIN_TYPE, N_("Join type"), "join_type"}, + {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, + {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, + {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, +/* Ponyscape -> Inkscape 0.92*/ + {ATTACH_PATH, N_("Attach path"), "attach_path"}, + {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, + {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, + {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, + {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, +/* 9.93 */ + {MEASURE_SEGMENTS, N_("Measure Segments"), "measure_segments"}, + {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, + {BOOL_OP, N_("Boolean operation"), "bool_op"}, + {EMBRODERY_STITCH, N_("Embrodery stitch"), "embrodery_stitch"}, + {POWERCLIP, N_("Power clip"), "powerclip"}, + {POWERMASK, N_("Power mask"), "powermask"}, +#ifdef LPE_ENABLE_TEST_EFFECTS + {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"}, + {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"}, + {CIRCLE_WITH_RADIUS, N_("Circle (by center and radius)"), "circle_with_radius"}, + {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"}, + {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"}, + {EXTRUDE, N_("Extrude"), "extrude"}, + {LATTICE, N_("Lattice Deformation"), "lattice"}, + {LINE_SEGMENT, N_("Line Segment"), "line_segment"}, + {OFFSET, N_("Offset"), "offset"}, + {PARALLEL, N_("Parallel"), "parallel"}, + {PATH_LENGTH, N_("Path length"), "path_length"}, + {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"}, + {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"}, + {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, + {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, + {TEXT_LABEL, N_("Text label"), "text_label"}, +#endif + +}; +const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); + +int +Effect::acceptsNumClicks(EffectType type) { + switch (type) { + case INVALID_LPE: return -1; // in case we want to distinguish between invalid LPE and valid ones that expect zero clicks + case ANGLE_BISECTOR: return 3; + case CIRCLE_3PTS: return 3; + case CIRCLE_WITH_RADIUS: return 2; + case LINE_SEGMENT: return 2; + case PERP_BISECTOR: return 2; + default: return 0; + } +} + +Effect* +Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) +{ + Effect* neweffect = NULL; + switch (lpenr) { + case EMBRODERY_STITCH: + neweffect = static_cast ( new LPEEmbroderyStitch(lpeobj) ); + break; + case BOOL_OP: + neweffect = static_cast ( new LPEBool(lpeobj) ); + break; + case PATTERN_ALONG_PATH: + neweffect = static_cast ( new LPEPatternAlongPath(lpeobj) ); + break; + case BEND_PATH: + neweffect = static_cast ( new LPEBendPath(lpeobj) ); + break; + case SKETCH: + neweffect = static_cast ( new LPESketch(lpeobj) ); + break; + case ROUGH_HATCHES: + neweffect = static_cast ( new LPERoughHatches(lpeobj) ); + break; + case VONKOCH: + neweffect = static_cast ( new LPEVonKoch(lpeobj) ); + break; + case KNOT: + neweffect = static_cast ( new LPEKnot(lpeobj) ); + break; + case GEARS: + neweffect = static_cast ( new LPEGears(lpeobj) ); + break; + case CURVE_STITCH: + neweffect = static_cast ( new LPECurveStitch(lpeobj) ); + break; + case LATTICE: + neweffect = static_cast ( new LPELattice(lpeobj) ); + break; + case ENVELOPE: + neweffect = static_cast ( new LPEEnvelope(lpeobj) ); + break; + case CIRCLE_WITH_RADIUS: + neweffect = static_cast ( new LPECircleWithRadius(lpeobj) ); + break; + case PERSPECTIVE_PATH: + neweffect = static_cast ( new LPEPerspectivePath(lpeobj) ); + break; + case SPIRO: + neweffect = static_cast ( new LPESpiro(lpeobj) ); + break; + case CONSTRUCT_GRID: + neweffect = static_cast ( new LPEConstructGrid(lpeobj) ); + break; + case PERP_BISECTOR: + neweffect = static_cast ( new LPEPerpBisector(lpeobj) ); + break; + case TANGENT_TO_CURVE: + neweffect = static_cast ( new LPETangentToCurve(lpeobj) ); + break; + case MIRROR_SYMMETRY: + neweffect = static_cast ( new LPEMirrorSymmetry(lpeobj) ); + break; + case CIRCLE_3PTS: + neweffect = static_cast ( new LPECircle3Pts(lpeobj) ); + break; + case ANGLE_BISECTOR: + neweffect = static_cast ( new LPEAngleBisector(lpeobj) ); + break; + case PARALLEL: + neweffect = static_cast ( new LPEParallel(lpeobj) ); + break; + case COPY_ROTATE: + neweffect = static_cast ( new LPECopyRotate(lpeobj) ); + break; + case OFFSET: + neweffect = static_cast ( new LPEOffset(lpeobj) ); + break; + case RULER: + neweffect = static_cast ( new LPERuler(lpeobj) ); + break; + case INTERPOLATE: + neweffect = static_cast ( new LPEInterpolate(lpeobj) ); + break; + case INTERPOLATE_POINTS: + neweffect = static_cast ( new LPEInterpolatePoints(lpeobj) ); + break; + case TEXT_LABEL: + neweffect = static_cast ( new LPETextLabel(lpeobj) ); + break; + case PATH_LENGTH: + neweffect = static_cast ( new LPEPathLength(lpeobj) ); + break; + case LINE_SEGMENT: + neweffect = static_cast ( new LPELineSegment(lpeobj) ); + break; + case DOEFFECTSTACK_TEST: + neweffect = static_cast ( new LPEdoEffectStackTest(lpeobj) ); + break; + case BSPLINE: + neweffect = static_cast ( new LPEBSpline(lpeobj) ); + break; + case DYNASTROKE: + neweffect = static_cast ( new LPEDynastroke(lpeobj) ); + break; + case RECURSIVE_SKELETON: + neweffect = static_cast ( new LPERecursiveSkeleton(lpeobj) ); + break; + case EXTRUDE: + neweffect = static_cast ( new LPEExtrude(lpeobj) ); + break; + case POWERSTROKE: + neweffect = static_cast ( new LPEPowerStroke(lpeobj) ); + break; + case CLONE_ORIGINAL: + neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); + break; + case ATTACH_PATH: + neweffect = static_cast ( new LPEAttachPath(lpeobj) ); + break; + case FILL_BETWEEN_STROKES: + neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); + break; + case FILL_BETWEEN_MANY: + neweffect = static_cast ( new LPEFillBetweenMany(lpeobj) ); + break; + case ELLIPSE_5PTS: + neweffect = static_cast ( new LPEEllipse5Pts(lpeobj) ); + break; + case BOUNDING_BOX: + neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); + break; + case JOIN_TYPE: + neweffect = static_cast ( new LPEJoinType(lpeobj) ); + break; + case TAPER_STROKE: + neweffect = static_cast ( new LPETaperStroke(lpeobj) ); + break; + case SIMPLIFY: + neweffect = static_cast ( new LPESimplify(lpeobj) ); + break; + case LATTICE2: + neweffect = static_cast ( new LPELattice2(lpeobj) ); + break; + case PERSPECTIVE_ENVELOPE: + neweffect = static_cast ( new LPEPerspectiveEnvelope(lpeobj) ); + break; + case FILLET_CHAMFER: + neweffect = static_cast ( new LPEFilletChamfer(lpeobj) ); + break; + case POWERCLIP: + neweffect = static_cast ( new LPEPowerClip(lpeobj) ); + break; + case POWERMASK: + neweffect = static_cast ( new LPEPowerMask(lpeobj) ); + break; + case ROUGHEN: + neweffect = static_cast ( new LPERoughen(lpeobj) ); + break; + case SHOW_HANDLES: + neweffect = static_cast ( new LPEShowHandles(lpeobj) ); + break; + case TRANSFORM_2PTS: + neweffect = static_cast ( new LPETransform2Pts(lpeobj) ); + break; + case MEASURE_SEGMENTS: + neweffect = static_cast ( new LPEMeasureSegments(lpeobj) ); + break; + default: + g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); + neweffect = NULL; + break; + } + + if (neweffect) { + neweffect->readallParameters(lpeobj->getRepr()); + } + + return neweffect; +} + +void Effect::createAndApply(const char* name, SPDocument *doc, SPItem *item) +{ + // Path effect definition + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); + repr->setAttribute("effect", name); + + doc->getDefs()->getRepr()->addChild(repr, NULL); // adds to and assigns the 'id' attribute + const gchar * repr_id = repr->attribute("id"); + Inkscape::GC::release(repr); + + gchar *href = g_strdup_printf("#%s", repr_id); + SP_LPE_ITEM(item)->addPathEffect(href, true); + g_free(href); +} + +void +Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) +{ + createAndApply(LPETypeConverter.get_key(type).c_str(), doc, item); +} + +Effect::Effect(LivePathEffectObject *lpeobject) + : apply_to_clippath_and_mask(false), + is_clip_or_mask(false), + _provides_knotholder_entities(false), + oncanvasedit_it(0), + is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), + show_orig_path(false), + keep_paths(false), + is_load(true), + lpeobj(lpeobject), + concatenate_before_pwd2(false), + sp_lpe_item(NULL), + current_zoom(1), + upd_params(true), + current_shape(NULL), + provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden + is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden +{ + registerParameter( dynamic_cast(&is_visible) ); + is_visible.widget_is_visible = false; + current_zoom = 0.0; +} + +Effect::~Effect() +{ +} + +Glib::ustring +Effect::getName() const +{ + if (lpeobj->effecttype_set && LPETypeConverter.is_valid_id(lpeobj->effecttype) ) + return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) ); + else + return Glib::ustring( _("No effect") ); +} + +EffectType +Effect::effectType() const { + return lpeobj->effecttype; +} + +/** + * Is performed a single time when the effect is freshly applied to a path + */ +void +Effect::doOnApply (SPLPEItem const*/*lpeitem*/) +{ +} + +void +Effect::setCurrentZoom(double cZ) +{ + current_zoom = cZ; +} + +void +Effect::setSelectedNodePoints(std::vector sNP) +{ + selectedNodesPoints = sNP; +} + +bool +Effect::isNodePointSelected(Geom::Point const &nodePoint) const +{ + if (selectedNodesPoints.size() > 0) { + using Geom::X; + using Geom::Y; + for (std::vector::const_iterator i = selectedNodesPoints.begin(); + i != selectedNodesPoints.end(); ++i) { + Geom::Point p = *i; + Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); + Geom::Point p2(nodePoint[X],nodePoint[Y]); + p2 *= transformCoordinate; + if (Geom::are_near(p, p2, 0.01)) { + return true; + } + } + } + return false; +} + +void +Effect::processObjects(LpeAction lpe_action) +{ + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return; + } + for (std::vector::iterator el_it = items.begin(); + el_it != items.end(); ++el_it) { + const char * id = *el_it; + if (!id) { + return; + } + SPObject *elemref = NULL; + if ((elemref = document->getObjectById(id))) { + Inkscape::XML::Node * elemnode = elemref->getRepr(); + std::vector item_list; + item_list.push_back(SP_ITEM(elemref)); + std::vector item_to_select; + std::vector item_selected; + SPCSSAttr *css; + Glib::ustring css_str; + SPItem *item = SP_ITEM(elemref); + switch (lpe_action){ + case LPE_TO_OBJECTS: + if (item->isHidden()) { + sp_object_ref(item, 0 ); + item->deleteObject(true); + sp_object_unref(item); + } else { + if (elemnode->attribute("inkscape:path-effect")) { + sp_item_list_to_curves(item_list, item_selected, item_to_select); + } + elemnode->setAttribute("sodipodi:insensitive", NULL); + } + break; + + case LPE_ERASE: + sp_object_ref(item, 0 ); + item->deleteObject(true); + sp_object_unref(item); + break; + + case LPE_VISIBILITY: + css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); + if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { + css->setAttribute("display", "none"); + } else { + css->setAttribute("display", NULL); + } + sp_repr_css_write_string(css,css_str); + elemnode->setAttribute("style", css_str.c_str()); + break; + + default: + break; + } + } + } + if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { + items.clear(); + } +} + +/** + * Is performed each time before the effect is updated. + */ +void +Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) +{ + //Do nothing for simple effects +} + + +void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) +{ + is_load = false; +} + +void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ +} +void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ +} +//secret impl methods (shhhh!) +void Effect::doOnApply_impl(SPLPEItem const* lpeitem) +{ + sp_lpe_item = const_cast(lpeitem); + doOnApply(lpeitem); +} + +void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask) +{ + sp_lpe_item = const_cast(lpeitem); + is_clip_or_mask = clip_or_mask; + doBeforeEffect(lpeitem); + update_helperpath(); +} + +/** + * Effects can have a parameter path set before they are applied by accepting a nonzero number of + * mouse clicks. This method activates the pen context, which waits for the specified number of + * clicks. Override Effect::acceptsNumClicks() to return the number of expected mouse clicks. + */ +void +Effect::doAcceptPathPreparations(SPLPEItem *lpeitem) +{ + // switch to pen context + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // TODO: Is there a better method to find the item's desktop? + if (!tools_isactive(desktop, TOOLS_FREEHAND_PEN)) { + tools_switch(desktop, TOOLS_FREEHAND_PEN); + } + + Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; + Inkscape::UI::Tools::PenTool *pc = SP_PEN_CONTEXT(ec); + pc->expecting_clicks_for_LPE = this->acceptsNumClicks(); + pc->waiting_LPE = this; + pc->waiting_item = lpeitem; + pc->polylines_only = true; + + ec->desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, + g_strdup_printf(_("Please specify a parameter path for the LPE '%s' with %d mouse clicks"), + getName().c_str(), acceptsNumClicks())); +} + +void +Effect::writeParamsToSVG() { + std::vector::iterator p; + for (p = param_vector.begin(); p != param_vector.end(); ++p) { + (*p)->write_to_SVG(); + } +} + +/** + * If the effect expects a path parameter (specified by a number of mouse clicks) before it is + * applied, this is the method that processes the resulting path. Override it to customize it for + * your LPE. But don't forget to call the parent method so that is_ready is set to true! + */ +void +Effect::acceptParamPath (SPPath const*/*param_path*/) { + setReady(); +} + +/* + * Here be the doEffect function chain: + */ +void +Effect::doEffect (SPCurve * curve) +{ + Geom::PathVector orig_pathv = curve->get_pathvector(); + + Geom::PathVector result_pathv = doEffect_path(orig_pathv); + + curve->set_pathvector(result_pathv); +} + +Geom::PathVector +Effect::doEffect_path (Geom::PathVector const & path_in) +{ + Geom::PathVector path_out; + + if ( !concatenate_before_pwd2 ) { + // default behavior + for (unsigned int i=0; i < path_in.size(); i++) { + Geom::Piecewise > pwd2_in = path_in[i].toPwSb(); + Geom::Piecewise > pwd2_out = doEffect_pwd2(pwd2_in); + Geom::PathVector path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE); + // add the output path vector to the already accumulated vector: + for (unsigned int j=0; j < path.size(); j++) { + path_out.push_back(path[j]); + } + } + } else { + // concatenate the path into possibly discontinuous pwd2 + Geom::Piecewise > pwd2_in; + for (unsigned int i=0; i < path_in.size(); i++) { + pwd2_in.concat( path_in[i].toPwSb() ); + } + Geom::Piecewise > pwd2_out = doEffect_pwd2(pwd2_in); + path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE); + } + + return path_out; +} + +Geom::Piecewise > +Effect::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + g_warning("Effect has no doEffect implementation"); + return pwd2_in; +} + +void +Effect::readallParameters(Inkscape::XML::Node const* repr) +{ + std::vector::iterator it = param_vector.begin(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + while (it != param_vector.end()) { + Parameter * param = *it; + const gchar * key = param->param_key.c_str(); + const gchar * value = repr->attribute(key); + if (value) { + bool accepted = param->param_readSVGValue(value); + if (!accepted) { + g_warning("Effect::readallParameters - '%s' not accepted for %s", value, key); + } + } else { + Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + + (Glib::ustring)LPETypeConverter.get_key(effectType()).c_str() + + (Glib::ustring)"/" + + (Glib::ustring)key; + bool valid = prefs->getEntry(pref_path).isValid(); + if(valid){ + param->param_update_default(prefs->getString(pref_path).c_str()); + } else { + param->param_set_default(); + } + } + ++it; + } +} + +/* This function does not and SHOULD NOT write to XML */ +void +Effect::setParameter(const gchar * key, const gchar * new_value) +{ + Parameter * param = getParameter(key); + if (param) { + if (new_value) { + bool accepted = param->param_readSVGValue(new_value); + if (!accepted) { + g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key); + } + } else { + // set default value + param->param_set_default(); + } + } +} + +void +Effect::registerParameter(Parameter * param) +{ + param_vector.push_back(param); +} + + +/** + * Add all registered LPE knotholder handles to the knotholder + */ +void +Effect::addHandles(KnotHolder *knotholder, SPItem *item) { + using namespace Inkscape::LivePathEffect; + + // add handles provided by the effect itself + addKnotHolderEntities(knotholder, item); + + // add handles provided by the effect's parameters (if any) + for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { + (*p)->addKnotHolderEntities(knotholder, item); + } +} + +/** + * Return a vector of PathVectors which contain all canvas indicators for this effect. + * This is the function called by external code to get all canvas indicators (effect and its parameters) + * lpeitem = the item onto which this effect is applied + * @todo change return type to one pathvector, add all paths to one pathvector instead of maintaining a vector of pathvectors + */ +std::vector +Effect::getCanvasIndicators(SPLPEItem const* lpeitem) +{ + std::vector hp_vec; + + // add indicators provided by the effect itself + addCanvasIndicators(lpeitem, hp_vec); + + // add indicators provided by the effect's parameters + for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { + (*p)->addCanvasIndicators(lpeitem, hp_vec); + } + + return hp_vec; +} + +/** + * Add possible canvas indicators (i.e., helperpaths other than the original path) to \a hp_vec + * This function should be overwritten by derived effects if they want to provide their own helperpaths. + */ +void +Effect::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &/*hp_vec*/) +{ +} + +/** + * Call to a method on nodetool to update the helper path from the effect + */ +void +Effect::update_helperpath() { + Inkscape::UI::Tools::sp_update_helperpath(); +} + +/** + * This *creates* a new widget, management of deletion should be done by the caller + */ +Gtk::Widget * +Effect::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); + + vbox->set_border_width(5); + + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = param->param_newWidget(); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + +/** + * This *creates* a new widget, with default values setter + */ +Gtk::Widget * +Effect::defaultParamSet() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); + Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() ); + Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType()); + Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType()); + std::vector::iterator it = param_vector.begin(); + Inkscape::UI::Widget::Registry * wr; + bool has_params = false; + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + has_params = true; + Parameter * param = *it; + Glib::ustring * tip = param->param_getTooltip(); + const gchar * key = param->param_key.c_str(); + const gchar * value = param->param_label.c_str(); + + Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + + effectkey + + (Glib::ustring)"/" + + (Glib::ustring)key; + bool valid = prefs->getEntry(pref_path).isValid(); + const gchar * set_or_upd; + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); + if (valid) { + set_or_upd = _("Update"); + def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + } else { + set_or_upd = _("Set"); + ove = Glib::ustring(_("Default value overridden: None\n")); + } + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(param->param_getSVGValue()); + Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) ); + Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START)); + parameter_label->set_use_markup(true); + parameter_label->set_use_underline(true); + Glib::ustring tooltip = Glib::ustring("") + parameter_label->get_text () + Glib::ustring("\n") + param->param_tooltip + Glib::ustring("\n\n"); + parameter_label->set_ellipsize(Pango::ELLIPSIZE_END); + parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); + vbox_param->pack_start(*parameter_label, true, true, 2); + Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); + Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); + unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + + set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + if (!valid) { + unset->set_sensitive(false); + } + vbox_param->pack_start(*set, true, true, 2); + vbox_param->pack_start(*unset, true, true, 2); + + vbox_expander->pack_start(*vbox_param, true, true, 2); + } + ++it; + } + Glib::ustring tip = "" + effectname + (Glib::ustring)_(": Set default parameters"); + Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip)); + expander->set_use_markup(true); + expander->add(*vbox_expander); + expander->set_expanded(false); + vbox->pack_start(*dynamic_cast (expander), true, true, 2); + if (has_params) { + Gtk::Widget *vboxwidg = dynamic_cast(vbox); + vboxwidg->set_margin_bottom(10); + vboxwidg->set_margin_top(5); + return vboxwidg; + } else { + return NULL; + } +} + +void +Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(pref_path, (Glib::ustring)value); + gchar * label = _("Update"); + set->set_label((Glib::ustring)label); + unset->set_sensitive(true); + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(value) + Glib::ustring("\n"); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); +} + +void +Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->remove(pref_path); + gchar * label = _("Set"); + set->set_label((Glib::ustring)label); + unset->set_sensitive(false); + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: None\n")); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); +} + +Inkscape::XML::Node *Effect::getRepr() +{ + return lpeobj->getRepr(); +} + +SPDocument *Effect::getSPDoc() +{ + if (lpeobj->document == NULL) { + g_message("Effect::getSPDoc() returns NULL"); + } + return lpeobj->document; +} + +Parameter * +Effect::getParameter(const char * key) +{ + Glib::ustring stringkey(key); + + if (param_vector.empty()) return NULL; + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + Parameter * param = *it; + if ( param->param_key == key) { + return param; + } + + ++it; + } + + return NULL; +} + +Parameter * +Effect::getNextOncanvasEditableParam() +{ + if (param_vector.size() == 0) // no parameters + return NULL; + + oncanvasedit_it++; + if (oncanvasedit_it >= static_cast(param_vector.size())) { + oncanvasedit_it = 0; + } + int old_it = oncanvasedit_it; + + do { + Parameter * param = param_vector[oncanvasedit_it]; + if(param && param->oncanvas_editable) { + return param; + } else { + oncanvasedit_it++; + if (oncanvasedit_it == static_cast(param_vector.size())) { // loop round the map + oncanvasedit_it = 0; + } + } + } while (oncanvasedit_it != old_it); // iterate until complete loop through map has been made + + return NULL; +} + +void +Effect::editNextParamOncanvas(SPItem * item, SPDesktop * desktop) +{ + if (!desktop) return; + + Parameter * param = getNextOncanvasEditableParam(); + if (param) { + param->param_editOncanvas(item, desktop); + gchar *message = g_strdup_printf(_("Editing parameter %s."), param->param_label.c_str()); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message); + g_free(message); + } else { + desktop->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("None of the applied path effect's parameters can be edited on-canvas.") ); + } +} + +/* This function should reset the defaults and is used for example to initialize an effect right after it has been applied to a path +* The nice thing about this is that this function can use knowledge of the original path and set things accordingly for example to the size or origin of the original path! +*/ +void +Effect::resetDefaults(SPItem const* /*item*/) +{ + std::vector::iterator p; + for (p = param_vector.begin(); p != param_vector.end(); ++p) { + (*p)->param_set_default(); + (*p)->write_to_SVG(); + } +} + +//Activate handle your transform filling your effect on SPPath.cpp +void +Effect::transform_multiply(Geom::Affine const& postmul, bool set) +{ + // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); + } +} + +bool +Effect::providesKnotholder() const +{ + // does the effect actively provide any knotholder entities of its own? + if (_provides_knotholder_entities) { + return true; + } + + // otherwise: are there any parameters that have knotholderentities? + for (std::vector::const_iterator p = param_vector.begin(); p != param_vector.end(); ++p) { + if ((*p)->providesKnotHolderEntities()) { + return true; + } + } + + return false; +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 9b1b8a7eb2..f59b2a7320 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -10,6 +10,7 @@ #include #include <2geom/forward.h> #include "ui/widget/registry.h" +#include #include "parameter/bool.h" #include "effect-enum.h" diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 721a4ecab6..ca9698fffc 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -139,6 +139,9 @@ Gtk::Widget *LPEBSpline::newWidget() ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 15968dd56c..0830fd76c1 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -196,15 +196,17 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ if (method != CLM_NONE) { attr += Glib::ustring("d,"); } - attr += Glib::ustring(attributes.param_getSVGValue()) + Glib::ustring(","); - if (attr.size() && !Glib::ustring(attributes.param_getSVGValue()).size()) { + gchar * attributes_str = attributes.param_getSVGValue(); + attr += Glib::ustring(attributes_str) + Glib::ustring(","); + if (attr.size() && !Glib::ustring(attributes_str).size()) { attr.erase (attr.size()-1, 1); } + gchar * style_attributes_str = style_attributes.param_getSVGValue(); Glib::ustring style_attr = ""; - if (style_attr.size() && !Glib::ustring(style_attributes.param_getSVGValue()).size()) { + if (style_attr.size() && !Glib::ustring( style_attributes_str).size()) { style_attr.erase (style_attr.size()-1, 1); } - style_attr += Glib::ustring(style_attributes.param_getSVGValue()) + Glib::ustring(","); + style_attr += Glib::ustring( style_attributes_str) + Glib::ustring(","); SPItem * orig = SP_ITEM(linkeditem.getObject()); SPItem * dest = SP_ITEM(sp_lpe_item); @@ -253,6 +255,8 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } linked = g_strdup(id); + g_free(style_attributes_str); + g_free(attributes_str); g_free(id); } else { linked = g_strdup(""); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 3abcbf2174..007e189530 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -337,6 +337,9 @@ Gtk::Widget * LPECopyRotate::newWidget() reset_button->set_size_request(110,20); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index f4269d36c3..4738eaad2b 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -107,7 +107,9 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + gchar * mode_str = mode.param_getSVGValue(); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); + g_free(mode_str); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } @@ -246,7 +248,9 @@ Gtk::Widget *LPEFilletChamfer::newWidget() vbox->pack_start(*fillet_container, true, true, 2); vbox->pack_start(*chamfer_container, true, true, 2); - + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return vbox; } @@ -345,7 +349,9 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + gchar * mode_str = mode.param_getSVGValue(); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); + g_free(mode_str); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp.orig b/src/live_effects/lpe-fillet-chamfer.cpp.orig new file mode 100644 index 0000000000..f4269d36c3 --- /dev/null +++ b/src/live_effects/lpe-fillet-chamfer.cpp.orig @@ -0,0 +1,636 @@ +/* + * Author(s): + * Jabiertxo Arraiza Cenoz + * + * Copyright (C) 2014 Author(s) + * + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-fillet-chamfer.h" +#include "helper/geom.h" +#include "display/curve.h" +#include "helper/geom-curves.h" +#include "helper/geom-satellite.h" +#include <2geom/elliptical-arc.h> +#include "knotholder.h" +#include + +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +namespace Inkscape { +namespace LivePathEffect { + +static const Util::EnumData FilletmethodData[] = { + { FM_AUTO, N_("Auto"), "auto" }, + { FM_ARC, N_("Force arc"), "arc" }, + { FM_BEZIER, N_("Force bezier"), "bezier" } +}; +static const Util::EnumDataConverter FMConverter(FilletmethodData, FM_END); + +LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + unit(_("Unit"), _("Unit"), "unit", &wr, this, "px"), + satellites_param("Satellites_param", "Satellites_param", + "satellites_param", &wr, this), + method(_("Method:"), _("Methods to calculate the fillet or chamfer"), + "method", FMConverter, &wr, this, FM_AUTO), + mode(_("Mode:"), _("Mode, fillet or chamfer"), + "mode", &wr, this, "F", true), + radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, + this, 0.0), + chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", + &wr, this, 1), + flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), + "flexible", &wr, this, false), + mirror_knots(_("Mirror Knots"), _("Mirror Knots"), "mirror_knots", &wr, + this, true), + only_selected(_("Change only selected nodes"), + _("Change only selected nodes"), "only_selected", &wr, this, + false), + use_knot_distance(_("Use knots distance instead radius"), + _("Use knots distance instead radius"), + "use_knot_distance", &wr, this, false), + hide_knots(_("Hide knots"), _("Hide knots"), "hide_knots", &wr, this, + false), + apply_no_radius(_("Apply changes if radius = 0"), _("Apply changes if radius = 0"), "apply_no_radius", &wr, this, true), + apply_with_radius(_("Apply changes if radius > 0"), _("Apply changes if radius > 0"), "apply_with_radius", &wr, this, true), + helper_size(_("Helper path size with direction to node:"), + _("Helper path size with direction to node"), "helper_size", &wr, this, 0), + _pathvector_satellites(NULL), + _degenerate_hide(false) +{ + registerParameter(&satellites_param); + registerParameter(&unit); + registerParameter(&method); + registerParameter(&mode); + registerParameter(&radius); + registerParameter(&chamfer_steps); + registerParameter(&helper_size); + registerParameter(&flexible); + registerParameter(&use_knot_distance); + registerParameter(&mirror_knots); + registerParameter(&apply_no_radius); + registerParameter(&apply_with_radius); + registerParameter(&only_selected); + registerParameter(&hide_knots); + + radius.param_set_range(0.0, Geom::infinity()); + radius.param_set_increments(1, 1); + radius.param_set_digits(4); + radius.param_set_undo(false); + chamfer_steps.param_set_range(1, 999); + chamfer_steps.param_set_increments(1, 1); + chamfer_steps.param_set_digits(0); + helper_size.param_set_range(0, 999); + helper_size.param_set_increments(5, 5); + helper_size.param_set_digits(0); + _provides_knotholder_entities = true; +} + +void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) +{ + SPLPEItem *splpeitem = const_cast(lpeItem); + SPShape *shape = dynamic_cast(splpeitem); + if (shape) { + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); + Satellites satellites; + double power = radius; + if (!flexible) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + SPNamedView *nv = sp_document_namedview(document, NULL); + Glib::ustring display_unit = nv->display_units->abbr; + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + } + SatelliteType satellite_type = FILLET; + std::map gchar_map_to_satellite_type = + boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + if (it != gchar_map_to_satellite_type.end()) { + satellite_type = it->second; + } + for (Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { + if (path_it->empty()) { + continue; + } + std::vector subpath_satellites; + for (Geom::Path::const_iterator curve_it = path_it->begin(); curve_it != path_it->end(); ++curve_it) { + //Maybe we want this satellites... + //if (curve_it->isDegenerate()) { + // continue + //} + Satellite satellite(satellite_type); + satellite.setSteps(chamfer_steps); + satellite.setAmount(power); + satellite.setIsTime(flexible); + satellite.setHasMirror(mirror_knots); + satellite.setHidden(hide_knots); + subpath_satellites.push_back(satellite); + } + //we add the last satellite on open path because _pathvector_satellites is related to nodes, not curves + //so maybe in the future we can need this last satellite in other effects + //don't remove for this effect because _pathvector_satellites class has methods when the path is modiffied + //and we want one method for all uses + if (!path_it->closed()) { + Satellite satellite(satellite_type); + satellite.setSteps(chamfer_steps); + satellite.setAmount(power); + satellite.setIsTime(flexible); + satellite.setHasMirror(mirror_knots); + satellite.setHidden(hide_knots); + subpath_satellites.push_back(satellite); + } + satellites.push_back(subpath_satellites); + } + _pathvector_satellites = new PathVectorSatellites(); + _pathvector_satellites->setPathVector(pathv); + _pathvector_satellites->setSatellites(satellites); + satellites_param.setPathVectorSatellites(_pathvector_satellites); + } else { + g_warning("LPE Fillet/Chamfer can only be applied to shapes (not groups)."); + SPLPEItem *item = const_cast(lpeItem); + item->removeCurrentPathEffect(false); + } +} + +Gtk::Widget *LPEFilletChamfer::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = param->param_newWidget(); + if (param->param_key == "radius") { + Inkscape::UI::Widget::Scalar *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg_registered->signal_value_changed().connect( + sigc::mem_fun(*this, &LPEFilletChamfer::updateAmount)); + widg = widg_registered; + if (widg) { + Gtk::HBox *scalar_parameter = dynamic_cast(widg); + std::vector childList = scalar_parameter->get_children(); + Gtk::Entry *entry_widget = dynamic_cast(childList[1]); + entry_widget->set_width_chars(6); + } +// } else if (param->param_key == "unit") { +// Inkscape::UI::Widget::RegisteredUnitMenu* widg_registered = +// Gtk::manage(dynamic_cast< Inkscape::UI::Widget::RegisteredUnitMenu *>(widg)); +// widg_registered->setUnit(unit.get_abbreviation()); +// widg_registered->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change unit parameter")); +// widg_registered->getUnitMenu()->signal_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::convertUnit)); +// widg = widg_registered; + } else if (param->param_key == "chamfer_steps") { + Inkscape::UI::Widget::Scalar *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg_registered->signal_value_changed().connect( + sigc::mem_fun(*this, &LPEFilletChamfer::updateChamferSteps)); + widg = widg_registered; + if (widg) { + Gtk::HBox *scalar_parameter = dynamic_cast(widg); + std::vector childList = scalar_parameter->get_children(); + Gtk::Entry *entry_widget = dynamic_cast(childList[1]); + entry_widget->set_width_chars(3); + } + } else if (param->param_key == "helper_size") { + Inkscape::UI::Widget::Scalar *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg_registered->signal_value_changed().connect( + sigc::mem_fun(*this, &LPEFilletChamfer::refreshKnots)); + } else if (param->param_key == "only_selected") { + Gtk::manage(widg); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + ++it; + } + + Gtk::HBox *fillet_container = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); + fillet->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),FILLET)); + + fillet_container->pack_start(*fillet, true, true, 2); + Gtk::Button *inverse_fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverse_fillet->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),INVERSE_FILLET)); + fillet_container->pack_start(*inverse_fillet, true, true, 2); + + Gtk::HBox *chamfer_container = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); + chamfer->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),CHAMFER)); + + chamfer_container->pack_start(*chamfer, true, true, 2); + Gtk::Button *inverse_chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer")))); + inverse_chamfer->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),INVERSE_CHAMFER)); + chamfer_container->pack_start(*inverse_chamfer, true, true, 2); + + vbox->pack_start(*fillet_container, true, true, 2); + vbox->pack_start(*chamfer_container, true, true, 2); + + return vbox; +} + +void LPEFilletChamfer::refreshKnots() +{ + if (satellites_param._knoth) { + satellites_param._knoth->update_knots(); + } +} + +void LPEFilletChamfer::updateAmount() +{ + setSelected(_pathvector_satellites); + double power = radius; + if (!flexible) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + SPNamedView *nv = sp_document_namedview(document, NULL); + Glib::ustring display_unit = nv->display_units->abbr; + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + } + _pathvector_satellites->updateAmount(power, apply_no_radius, apply_with_radius, only_selected, + use_knot_distance, flexible); + satellites_param.setPathVectorSatellites(_pathvector_satellites); +} + +//void LPEFilletChamfer::convertUnit() +//{ +// SPDocument * document = SP_ACTIVE_DOCUMENT; +// SPNamedView *nv = sp_document_namedview(document, NULL); +// Glib::ustring display_unit = nv->display_units->abbr; +// _pathvector_satellites->convertUnit(unit.get_abbreviation(), display_unit, apply_no_radius, apply_with_radius); +// satellites_param.setPathVectorSatellites(_pathvector_satellites); +//} + +void LPEFilletChamfer::updateChamferSteps() +{ + setSelected(_pathvector_satellites); + _pathvector_satellites->updateSteps(chamfer_steps, apply_no_radius, apply_with_radius, only_selected); + satellites_param.setPathVectorSatellites(_pathvector_satellites); +} + +void LPEFilletChamfer::updateSatelliteType(SatelliteType satellitetype) +{ + std::map satellite_type_to_gchar_map = + boost::assign::map_list_of(FILLET, "F")(INVERSE_FILLET, "IF")(CHAMFER, "C")(INVERSE_CHAMFER, "IC")(INVALID_SATELLITE, "KO"); + mode.param_setValue((Glib::ustring)satellite_type_to_gchar_map.at(satellitetype)); + setSelected(_pathvector_satellites); + _pathvector_satellites->updateSatelliteType(satellitetype, apply_no_radius, apply_with_radius, only_selected); + satellites_param.setPathVectorSatellites(_pathvector_satellites); +} + +void LPEFilletChamfer::setSelected(PathVectorSatellites *_pathvector_satellites){ + Geom::PathVector const pathv = _pathvector_satellites->getPathVector(); + Satellites satellites = _pathvector_satellites->getSatellites(); + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + Geom::Curve const &curve_in = pathv[i][j]; + if (only_selected && isNodePointSelected(curve_in.initialPoint()) ){ + satellites[i][j].setSelected(true); + } else { + satellites[i][j].setSelected(false); + } + } + } + _pathvector_satellites->setSatellites(satellites); +} + +void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) +{ + if (!pathvector_before_effect.empty()) { + //fillet chamfer specific calls + satellites_param.setUseDistance(use_knot_distance); + satellites_param.setCurrentZoom(current_zoom); + //mandatory call + satellites_param.setEffectType(effectType()); + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); + //if are diferent sizes call to recalculate + //TODO: Update the satellite data in paths modified, + Satellites satellites = satellites_param.data(); + if (satellites.empty()) { + doOnApply(lpeItem); + satellites = satellites_param.data(); + } + if (_pathvector_satellites) { + size_t number_nodes = pathv.nodes().size(); + size_t previous_number_nodes = _pathvector_satellites->getTotalSatellites(); + if (number_nodes != previous_number_nodes) { + Satellites satellites; + double power = radius; + if (!flexible) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + SPNamedView *nv = sp_document_namedview(document, NULL); + Glib::ustring display_unit = nv->display_units->abbr; + power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); + } + SatelliteType satellite_type = FILLET; + std::map gchar_map_to_satellite_type = + boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + if (it != gchar_map_to_satellite_type.end()) { + satellite_type = it->second; + } + Satellite satellite(satellite_type); + satellite.setSteps(chamfer_steps); + satellite.setAmount(power); + satellite.setIsTime(flexible); + satellite.setHasMirror(mirror_knots); + satellite.setHidden(hide_knots); + _pathvector_satellites->recalculateForNewPathVector(pathv, satellite); + satellites = _pathvector_satellites->getSatellites(); + } + } + if (_degenerate_hide) { + satellites_param.setGlobalKnotHide(true); + } else { + satellites_param.setGlobalKnotHide(false); + } + if (hide_knots) { + satellites_param.setHelperSize(0); + } else { + satellites_param.setHelperSize(helper_size); + } + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + if (j >= pathv[i].size()) { + continue; + } + Geom::Curve const &curve_in = pathv[i][j]; + if (satellites[i][j].is_time != flexible) { + satellites[i][j].is_time = flexible; + double amount = satellites[i][j].amount; + if (satellites[i][j].is_time) { + double time = timeAtArcLength(amount, curve_in); + satellites[i][j].amount = time; + } else { + double size = arcLengthAt(amount, curve_in); + satellites[i][j].amount = size; + } + } + if (satellites[i][j].has_mirror != mirror_knots) { + satellites[i][j].has_mirror = mirror_knots; + } + satellites[i][j].hidden = hide_knots; + if (only_selected && isNodePointSelected(curve_in.initialPoint()) ){ + satellites[i][j].setSelected(true); + } + } + } + if (!_pathvector_satellites) { + _pathvector_satellites = new PathVectorSatellites(); + } + _pathvector_satellites->setPathVector(pathv); + _pathvector_satellites->setSatellites(satellites); + satellites_param.setPathVectorSatellites(_pathvector_satellites, false); + refreshKnots(); + } else { + g_warning("LPE Fillet can only be applied to shapes (not groups)."); + } +} + +void +LPEFilletChamfer::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(_hp); +} + +void +LPEFilletChamfer::addChamferSteps(Geom::Path &tmp_path, Geom::Path path_chamfer, Geom::Point end_arc_point, size_t steps) +{ + setSelected(_pathvector_satellites); + double path_subdivision = 1.0 / steps; + for (size_t i = 1; i < steps; i++) { + Geom::Point chamfer_step = path_chamfer.pointAt(path_subdivision * i); + tmp_path.appendNew(chamfer_step); + } + tmp_path.appendNew(end_arc_point); +} + +Geom::PathVector +LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) +{ + const double GAP_HELPER = 0.00001; + Geom::PathVector path_out; + size_t path = 0; + const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); + _degenerate_hide = false; + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(path_in); + Satellites satellites = _pathvector_satellites->getSatellites(); + for (Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { + if (path_it->empty()) { + continue; + } + Geom::Path tmp_path; + if (path_it->size() == 1) { + path++; + tmp_path.start(path_it[0].pointAt(0)); + tmp_path.append(path_it[0]); + path_out.push_back(tmp_path); + continue; + } + double time0 = 0; + size_t curve = 0; + for (Geom::Path::const_iterator curve_it1 = path_it->begin(); curve_it1 != path_it->end(); ++curve_it1) { + size_t next_index = curve + 1; + if (curve == pathv[path].size() - 1 && pathv[path].closed()) { + next_index = 0; + } + //append last extreme of paths on open paths + if (curve == pathv[path].size() -1 && !pathv[path].closed()) { //the path is open and we are at end of path + if (time0 != 1) { //Previous satellite not at 100% amount + Geom::Curve *last_curve = curve_it1->portion(time0, 1); + last_curve->setInitial(tmp_path.finalPoint()); + tmp_path.append(*last_curve); + } + continue; + } + Geom::Curve const &curve_it2 = pathv[path][next_index]; + Satellite satellite = satellites[path][next_index]; + if (Geom::are_near((*curve_it1).initialPoint(), (*curve_it1).finalPoint())) { + _degenerate_hide = true; + g_warning("Knots hidden if consecutive nodes has the same position."); + return path_in; + } + if (!curve) { //curve == 0 + if (!path_it->closed()) { + time0 = 0; + } else { + time0 = satellites[path][0].time(*curve_it1); + } + } + double s = satellite.arcDistance(curve_it2); + double time1 = satellite.time(s, true, (*curve_it1)); + double time2 = satellite.time(curve_it2); + if (time1 <= time0) { + time1 = time0; + } + if (time2 > 1) { + time2 = 1; + } + Geom::Curve *knot_curve_1 = curve_it1->portion(time0, time1); + Geom::Curve *knot_curve_2 = curve_it2.portion(time2, 1); + if (curve > 0) { + knot_curve_1->setInitial(tmp_path.finalPoint()); + } else { + tmp_path.start((*curve_it1).pointAt(time0)); + } + + Geom::Point start_arc_point = knot_curve_1->finalPoint(); + Geom::Point end_arc_point = curve_it2.pointAt(time2); + //add a gap helper + if (time2 == 1) { + end_arc_point = curve_it2.pointAt(time2 - GAP_HELPER); + } + if (time1 == time0) { + start_arc_point = curve_it1->pointAt(time1 + GAP_HELPER); + } + + double k1 = distance(start_arc_point, curve_it1->finalPoint()) * K; + double k2 = distance(curve_it2.initialPoint(), end_arc_point) * K; + Geom::CubicBezier const *cubic_1 = dynamic_cast(&*knot_curve_1); + Geom::CubicBezier const *cubic_2 = dynamic_cast(&*knot_curve_2); + Geom::Ray ray_1(start_arc_point, curve_it1->finalPoint()); + Geom::Ray ray_2(curve_it2.initialPoint(), end_arc_point); + if (cubic_1) { + ray_1.setPoints((*cubic_1)[2], start_arc_point); + } + if (cubic_2) { + ray_2.setPoints(end_arc_point, (*cubic_2)[1]); + } + bool ccw_toggle = cross(curve_it1->finalPoint() - start_arc_point, end_arc_point - start_arc_point) < 0; + double angle = angle_between(ray_1, ray_2, ccw_toggle); + double handle_angle_1 = ray_1.angle() - angle; + double handle_angle_2 = ray_2.angle() + angle; + if (ccw_toggle) { + handle_angle_1 = ray_1.angle() + angle; + handle_angle_2 = ray_2.angle() - angle; + } + Geom::Point handle_1 = Geom::Point::polar(ray_1.angle(), k1) + start_arc_point; + Geom::Point handle_2 = end_arc_point - Geom::Point::polar(ray_2.angle(), k2); + Geom::Point inverse_handle_1 = Geom::Point::polar(handle_angle_1, k1) + start_arc_point; + Geom::Point inverse_handle_2 = end_arc_point - Geom::Point::polar(handle_angle_2, k2); + if (time0 == 1) { + handle_1 = start_arc_point; + inverse_handle_1 = start_arc_point; + } + //remove gap helper + if (time2 == 1) { + end_arc_point = curve_it2.pointAt(time2); + } + if (time1 == time0) { + start_arc_point = curve_it1->pointAt(time0); + } + if (time1 != 1) { + if (time1 != time0 || (time1 == 1 && time0 == 1)) { + if (!knot_curve_1->isDegenerate()) { + tmp_path.append(*knot_curve_1); + } + } + SatelliteType type = satellite.satellite_type; + size_t steps = satellite.steps; + if (!steps) steps = 1; + Geom::Line const x_line(Geom::Point(0, 0), Geom::Point(1, 0)); + Geom::Line const angled_line(start_arc_point, end_arc_point); + double arc_angle = Geom::angle_between(x_line, angled_line); + double radius = Geom::distance(start_arc_point, middle_point(start_arc_point, end_arc_point)) / + sin(angle / 2.0); + Geom::Coord rx = radius; + Geom::Coord ry = rx; + bool eliptical = (is_straight_curve(*curve_it1) && + is_straight_curve(curve_it2) && method != FM_BEZIER) || + method == FM_ARC; + switch (type) { + case CHAMFER: + { + Geom::Path path_chamfer; + path_chamfer.start(tmp_path.finalPoint()); + if (eliptical) { + ccw_toggle = ccw_toggle ? 0 : 1; + path_chamfer.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); + } else { + path_chamfer.appendNew(handle_1, handle_2, end_arc_point); + } + addChamferSteps(tmp_path, path_chamfer, end_arc_point, steps); + } + break; + case INVERSE_CHAMFER: + { + Geom::Path path_chamfer; + path_chamfer.start(tmp_path.finalPoint()); + if (eliptical) { + path_chamfer.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); + } else { + path_chamfer.appendNew(inverse_handle_1, inverse_handle_2, end_arc_point); + } + addChamferSteps(tmp_path, path_chamfer, end_arc_point, steps); + } + break; + case INVERSE_FILLET: + { + if (eliptical) { + tmp_path.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); + } else { + tmp_path.appendNew(inverse_handle_1, inverse_handle_2, end_arc_point); + } + } + break; + default: //fillet + { + if (eliptical) { + ccw_toggle = ccw_toggle ? 0 : 1; + tmp_path.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); + } else { + tmp_path.appendNew(handle_1, handle_2, end_arc_point); + } + } + break; + } + } else { + if (!knot_curve_1->isDegenerate()) { + tmp_path.append(*knot_curve_1); + } + } + curve++; + time0 = time2; + } + if (path_it->closed()) { + tmp_path.close(); + } + path++; + path_out.push_back(tmp_path); + } + return path_out; +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offset:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index e8642d4e7a..4670ac06ef 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -262,6 +262,9 @@ LPELattice2::newWidget() expander->set_expanded(expanded); vbox->pack_start(*expander, true, true, 2); expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPELattice2::onExpanderChanged) ); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 4bc9278fca..5c75ed363c 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -101,7 +101,6 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : registerParameter(&rotate_anotation); registerParameter(&hide_back); registerParameter(&message); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring format_value = prefs->getString("/live_effects/measure-line/format"); @@ -228,12 +227,13 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng } else { doc_scale = 1.0; } - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + char * id = g_strdup((Glib::ustring("text-on-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str()); SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; if ((elemref = document->getObjectById(id))) { if (remove) { elemref->deleteObject(); + g_free(id); return; } rtext = elemref->getRepr(); @@ -243,6 +243,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtext->setAttribute("transform", NULL); } else { if (remove) { + g_free(id); return; } rtext = xml_doc->createElement("svg:text"); @@ -274,7 +275,9 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng g_free(transform); SPCSSAttr *css = sp_repr_css_attr_new(); Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); - fontlister->fill_css(css, Glib::ustring(fontbutton.param_getSVGValue())); + gchar * fontbutton_str = fontbutton.param_getSVGValue(); + fontlister->fill_css(css, Glib::ustring(fontbutton_str)); + g_free(fontbutton_str); std::stringstream font_size; font_size.imbue(std::locale::classic()); font_size << fontsize << "pt"; @@ -301,7 +304,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::GC::release(rtspan); } length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation()); - char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); + gchar const* oldlocale = strdup(setlocale(LC_NUMERIC, NULL)); if (local_locale) { setlocale (LC_NUMERIC, ""); } else { @@ -310,8 +313,9 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng gchar length_str[64]; g_snprintf(length_str, 64, "%.*f", (int)precision, length); setlocale (LC_NUMERIC, oldlocale); - g_free (oldlocale); - Glib::ustring label_value(format.param_getSVGValue()); + gchar * format_str = format.param_getSVGValue(); + Glib::ustring label_value(format_str); + g_free(format_str); size_t s = label_value.find(Glib::ustring("{measure}"),0); if(s < label_value.length()) { label_value.replace(s,s+9,length_str); @@ -349,6 +353,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng if (bounds) { anotation_width = bounds->width() * 1.15; } + g_free(id); } void @@ -533,7 +538,9 @@ LPEMeasureSegments::doOnApply(SPLPEItem const* lpeitem) bool LPEMeasureSegments::hasMeassure (size_t i) { - std::string listsegments(std::string(blacklist.param_getSVGValue()) + std::string(",")); + gchar * blacklist_str = blacklist.param_getSVGValue(); + std::string listsegments(std::string(blacklist_str) + std::string(",")); + g_free(blacklist_str); listsegments.erase(std::remove(listsegments.begin(), listsegments.end(), ' '), listsegments.end()); size_t s = listsegments.find(std::to_string(i) + std::string(","),0); if(s < listsegments.length()) { @@ -570,7 +577,6 @@ void LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) { SPLPEItem * splpeitem = const_cast(lpeitem); - SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; @@ -604,9 +610,11 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { pathvector *= writed_transform; } - if ((Glib::ustring(format.param_getSVGValue()).empty())) { + gchar * format_str = format.param_getSVGValue(); + if (Glib::ustring(format_str).empty()) { format.param_setValue(Glib::ustring("{measure}{unit}")); } + g_free(format_str); size_t ncurves = pathvector.curveCount(); items.clear(); double start_angle_cross = 0; @@ -631,15 +639,29 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else if (pathvector[i].size() > j + 1) { next = pathvector[i].pointAt(j+2); } - const char * idstart = Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); + const char * idstart = (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); SPObject *elemref = NULL; - if ((elemref = document->getObjectById(idstart))) { - start_stored = *SP_PATH(elemref)->get_curve()->first_point(); + if (elemref = document->getObjectById(idstart)) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* startcurve = path->get_curve(); + if (startcurve) { + start_stored = *startcurve->first_point(); + } + startcurve->unref(); + } } - const char * idend = Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); + const char * idend = (Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")) + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); elemref = NULL; - if ((elemref = document->getObjectById(idend))) { - end_stored = *SP_PATH(elemref)->get_curve()->first_point(); + if (elemref = document->getObjectById(idend)) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* endcurve = path->get_curve(); + if (endcurve) { + end_stored = *endcurve->first_point(); + } + endcurve->unref(); + } } if (Geom::are_near(start, start_stored, 0.01) && Geom::are_near(end, end_stored, 0.01)) @@ -713,7 +735,7 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { hstart = hstart - Point::polar(angle_cross, position); } - createLine(start, hstart, g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); + createLine(start, hstart, (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), false, remove); if (fix_overlaps != 180 && end_angle_cross != 0) { double position_turned = position / sin(end_angle_cross/2.0); @@ -731,9 +753,13 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) createArrowMarker("ArrowDIN-end"); } //We get the font size to offset the text to the middle - Pango::FontDescription fontdesc(Glib::ustring(fontbutton.param_getSVGValue())); + gchar * fontbutton_str = fontbutton.param_getSVGValue(); + Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); + Pango::FontDescription fontdesc(fontdesc_ustring); fontsize = fontdesc.get_size()/(double)Pango::SCALE; fontsize *= document->getRoot()->c2p.inverse().expansionX(); + g_free(fontbutton_str); + fontsize *= document->getRoot()->c2p.inverse().expansionX(); if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); @@ -752,38 +778,37 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { createTextLabel(pos, counter, length, angle, remove, true); } - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-")+ Glib::ustring(this->getRepr()->attribute("id"))).c_str(); arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); - char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); + gchar const* oldlocale = setlocale(LC_NUMERIC, NULL); setlocale (LC_NUMERIC, "C"); double width_line = atof(sp_repr_css_property(css,"stroke-width","-1")); setlocale (LC_NUMERIC, oldlocale); - g_free (oldlocale); if (width_line > -0.0001) { arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str()); } if(flip_side) { arrow_gap *= -1; } - createLine(end, hend, g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); + createLine(end, hend,(Glib::ustring("infoline-on-end-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), false, remove); if (!arrows_outside) { hstart = hstart + Point::polar(angle, arrow_gap); hend = hend - Point::polar(angle, arrow_gap ); } if ((anotation_width/2) < Geom::distance(hstart,hend)/2.0) { - createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, remove, true); + createLine(hstart, hend, (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, remove, true); } else { - createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(hstart, hend, (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); } } else { - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-end-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + const char * id = (Glib::ustring("text-on-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); SPObject *elemref = NULL; if ((elemref = document->getObjectById(id))) { elemref->deleteObject(); @@ -792,12 +817,12 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } } for (size_t k = ncurves; k <= previous_size; k++) { - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-start-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-end-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + const char * id = (Glib::ustring("text-on-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); SPObject *elemref = NULL; if ((elemref = document->getObjectById(id))) { elemref->deleteObject(); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 5d80d65fed..7207eb2fa7 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -241,8 +241,9 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) SPDocument * document = SP_ACTIVE_DOCUMENT; if (document) { Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * id_origin_char = id_origin.param_getSVGValue(); - const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); + char * id_origin_char = id_origin.param_getSVGValue(); + const char * elemref_id = (Glib::ustring("mirror-") + Glib::ustring(id_origin_char)).c_str(); + g_free(id_origin_char); items.clear(); items.push_back(elemref_id); SPObject *elemref= NULL; diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 3cff83fedc..f6930f81f6 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -414,6 +414,9 @@ LPEPerspectiveEnvelope::newWidget() reset_button->set_size_request(140,30); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 435c91c2d7..2a3bc2b355 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -252,6 +252,9 @@ LPEPerspectivePath::newWidget() Gtk::Widget* apply3DWidget = dynamic_cast(apply3D); apply3DWidget->set_tooltip_text("Refresh perspective"); vbox->pack_start(*apply3DWidget, true, true,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 18276270d6..f981f1c87f 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -43,11 +43,12 @@ LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ SPObject * clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); + gchar * uri_str = uri.param_getSVGValue(); if(hide_clip && clip_path) { SP_ITEM(sp_lpe_item)->clip_ref->detach(); - } else if (!hide_clip && !clip_path && uri.param_getSVGValue()) { + } else if (!hide_clip && !clip_path && uri_str) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -61,9 +62,10 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ if(!bbox) { return; } - if (uri.param_getSVGValue()) { + uri_str = uri.param_getSVGValue(); + if (uri_str) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -71,6 +73,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ } else { SP_ITEM(sp_lpe_item)->clip_ref->detach(); } + g_free(uri_str); Geom::Rect bboxrect = (*bbox); bboxrect.expandBy(1); Geom::Point topleft = bboxrect.corner(0); @@ -143,28 +146,31 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Inkscape::GC::release(clip_path_node); clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); } - if( is_inverse.param_getSVGValue() == (Glib::ustring)"false" && inverse && isVisible()) { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"false") && inverse && isVisible()) { if (clip_to_path) { addInverse(SP_ITEM(clip_to_path)); } else { addInverse(SP_ITEM(clip_data)); } - } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { + } else if(!strcmp(is_inverse_str,"true") && !inverse && isVisible()) { if (clip_to_path) { removeInverse(SP_ITEM(clip_to_path)); } else { removeInverse(SP_ITEM(clip_data)); } - } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ + } else if (inverse && !is_visible && is_inverse_str == (Glib::ustring)"true"){ removeInverse(SP_ITEM(clip_data)); } + g_free(is_inverse_str); } } } void LPEPowerClip::addInverse (SPItem * clip_data){ - if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"false")) { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -201,11 +207,13 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } } } + g_free(is_inverse_str); } void LPEPowerClip::removeInverse (SPItem * clip_data){ - if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"true")) { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -238,6 +246,7 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ } } } + g_free(is_inverse_str); } void @@ -280,6 +289,9 @@ LPEPowerClip::newWidget() topaths_button->set_size_request(220,30); hbox->pack_start(*topaths_button, false, false,2); vbox->pack_start(*hbox, true,true,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -289,13 +301,15 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); if(!keep_paths) { if(clip_path) { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + if(!strcmp(is_inverse_str,"true")) { removeInverse(SP_ITEM(clip_data)); } } + g_free(is_inverse_str); } } else { if (flatten && clip_path) { diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 883467b6a2..1dc722ace1 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -47,13 +47,14 @@ LPEPowerMask::~LPEPowerMask() {} void LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ - //To avoid close of color dialog and better performance on change color + //To avoid close of color dialog and better performance on change color SPObject * mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); + gchar * uri_str = uri.param_getSVGValue(); if(hide_mask && mask) { SP_ITEM(sp_lpe_item)->mask_ref->detach(); - } else if (!hide_mask && !mask && uri.param_getSVGValue()) { + } else if (!hide_mask && !mask && uri_str) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -69,11 +70,13 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ SP_ITEM(sp_lpe_item)->mask_ref->detach(); Geom::OptRect bbox = sp_lpe_item->visualBounds(); if(!bbox) { + g_free(uri_str); return; } - if (uri.param_getSVGValue()) { + uri_str = uri.param_getSVGValue(); + if (uri_str) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -96,6 +99,7 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ setMask(); } } + g_free(uri_str); } void diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index e847494a2f..e78ab99fda 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -163,6 +163,9 @@ Gtk::Widget *LPERoughen::newWidget() } ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 5de9816bb9..e676f37a08 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -115,6 +115,9 @@ LPESimplify::newWidget() ++it; } vbox->pack_start(*buttons,true, true, 2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index ab05b880c6..693c9332c2 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -360,6 +360,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->pack_start(*button2, true, true, 2); vbox->pack_start(*button3, true, true, 2); vbox->pack_start(*button4, true, true, 2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 0e19c07e10..f565f3db6d 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -17,8 +17,8 @@ MessageParam::MessageParam( const Glib::ustring& label, const Glib::ustring& tip const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, const gchar * default_message ) : Parameter(label, tip, key, wr, effect), - message(g_strdup(default_message)), - defmessage(g_strdup(default_message)) + message(default_message), + defmessage(default_message) { _label = NULL; _min_height = -1; @@ -33,7 +33,7 @@ MessageParam::param_set_default() void MessageParam::param_update_default(const gchar * default_message) { - defmessage = g_strdup(default_message); + defmessage = default_message; } bool @@ -46,13 +46,13 @@ MessageParam::param_readSVGValue(const gchar * strvalue) gchar * MessageParam::param_getSVGValue() const { - return message; + return g_strdup(message); } gchar * MessageParam::param_getDefaultSVGValue() const { - return defmessage; + return g_strdup(defmessage); } void @@ -93,7 +93,7 @@ MessageParam::param_setValue(const gchar * strvalue) if (strcmp(strvalue, message) != 0) { param_effect->upd_params = true; } - message = g_strdup(strvalue); + message = strvalue; } diff --git a/src/live_effects/parameter/message.h b/src/live_effects/parameter/message.h index 2ac2c791a6..fd850a7675 100644 --- a/src/live_effects/parameter/message.h +++ b/src/live_effects/parameter/message.h @@ -41,8 +41,8 @@ private: int _min_height; MessageParam(const MessageParam&); MessageParam& operator=(const MessageParam&); - gchar * message; - gchar * defmessage; + const gchar * message; + const gchar * defmessage; }; } //namespace LivePathEffect diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index a98c917700..22630d9332 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -528,7 +528,7 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const gchar * OriginalPathArrayParam::param_getDefaultSVGValue() const { - return ""; + return g_strdup(""); } void OriginalPathArrayParam::update() diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 28a42929b9..4c642404eb 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -199,42 +199,16 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect) lpe_changed = false; return; } - bool expanderopen = false; - Gtk::Widget * defaultswidget = effect.defaultParamSet(); - if (effectwidget) { - if (defaultswidget) { - Gtk::Expander * expander = NULL; - std::vector childs = dynamic_cast (effectwidget)->get_children(); - if (childs.size()) { - std::vector childs_default = dynamic_cast (childs[childs.size()-1])->get_children(); - if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ - expanderopen = expander->get_expanded(); - } - } - } effectcontrol_vbox.remove(*effectwidget); delete effectwidget; effectwidget = NULL; } - + effectwidget = effect.newWidget_impl(); effectcontrol_frame.set_label(effect.getName()); + effectcontrol_vbox.pack_start(*effectwidget, true, true); - effectwidget = effect.newWidget(); - if (effectwidget) { - - if (defaultswidget) { - Gtk::Expander * expander = NULL; - std::vector childs_default = dynamic_cast (defaultswidget)->get_children(); - if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ - expander->set_expanded(expanderopen); - } - dynamic_cast (effectwidget)->pack_start(*defaultswidget, true, true); - } - effectcontrol_vbox.pack_start(*effectwidget, true, true); - } button_remove.show(); - status_label.hide(); effectcontrol_frame.show(); effectcontrol_vbox.show_all_children(); @@ -248,7 +222,7 @@ LivePathEffectEditor::selectInList(LivePathEffect::Effect* effect) { Gtk::TreeNodeChildren chi = effectlist_view.get_model()->children(); for (Gtk::TreeIter ci = chi.begin() ; ci != chi.end(); ci++) { - if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect) + if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect && effectlist_view.get_selection()) effectlist_view.get_selection()->select(ci); } } -- GitLab From 827972250ca8ccc7d8b6f0e97cc9b68238a58532 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 10 Nov 2017 00:25:29 +0100 Subject: [PATCH 10/57] Remove orig files --- src/live_effects/effect.cpp.orig | 1028 ------------------ src/live_effects/lpe-fillet-chamfer.cpp.orig | 636 ----------- 2 files changed, 1664 deletions(-) delete mode 100644 src/live_effects/effect.cpp.orig delete mode 100644 src/live_effects/lpe-fillet-chamfer.cpp.orig diff --git a/src/live_effects/effect.cpp.orig b/src/live_effects/effect.cpp.orig deleted file mode 100644 index ab1807819c..0000000000 --- a/src/live_effects/effect.cpp.orig +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * Copyright (C) Johan Engelen 2007 - * Abhishek Sharma - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects - -#ifdef HAVE_CONFIG_H -#include -#endif - -// include effects: -#include "live_effects/lpe-patternalongpath.h" -#include "live_effects/lpe-angle_bisector.h" -#include "live_effects/lpe-attach-path.h" -#include "live_effects/lpe-bendpath.h" -#include "live_effects/lpe-bounding-box.h" -#include "live_effects/lpe-bspline.h" -#include "live_effects/lpe-circle_3pts.h" -#include "live_effects/lpe-circle_with_radius.h" -#include "live_effects/lpe-clone-original.h" -#include "live_effects/lpe-constructgrid.h" -#include "live_effects/lpe-copy_rotate.h" -#include "live_effects/lpe-curvestitch.h" -#include "live_effects/lpe-dynastroke.h" -#include "live_effects/lpe-ellipse_5pts.h" -#include "live_effects/lpe-envelope.h" -#include "live_effects/lpe-extrude.h" -#include "live_effects/lpe-fill-between-many.h" -#include "live_effects/lpe-fill-between-strokes.h" -#include "live_effects/lpe-fillet-chamfer.h" -#include "live_effects/lpe-gears.h" -#include "live_effects/lpe-interpolate.h" -#include "live_effects/lpe-interpolate_points.h" -#include "live_effects/lpe-jointype.h" -#include "live_effects/lpe-knot.h" -#include "live_effects/lpe-lattice2.h" -#include "live_effects/lpe-lattice.h" -#include "live_effects/lpe-line_segment.h" -#include "live_effects/lpe-measure-segments.h" -#include "live_effects/lpe-mirror_symmetry.h" -#include "live_effects/lpe-offset.h" -#include "live_effects/lpe-parallel.h" -#include "live_effects/lpe-path_length.h" -#include "live_effects/lpe-perp_bisector.h" -#include "live_effects/lpe-perspective-envelope.h" -#include "live_effects/lpe-perspective_path.h" -#include "live_effects/lpe-powerclip.h" -#include "live_effects/lpe-powermask.h" -#include "live_effects/lpe-powerstroke.h" -#include "live_effects/lpe-recursiveskeleton.h" -#include "live_effects/lpe-roughen.h" -#include "live_effects/lpe-rough-hatches.h" -#include "live_effects/lpe-ruler.h" -#include "live_effects/lpe-show_handles.h" -#include "live_effects/lpe-simplify.h" -#include "live_effects/lpe-sketch.h" -#include "live_effects/lpe-spiro.h" -#include "live_effects/lpe-tangent_to_curve.h" -#include "live_effects/lpe-transform_2pts.h" -#include "live_effects/lpe-taperstroke.h" -#include "live_effects/lpe-test-doEffect-stack.h" -#include "live_effects/lpe-text_label.h" -#include "live_effects/lpe-vonkoch.h" -#include "live_effects/lpe-embrodery-stitch.h" -#include "live_effects/lpe-bool.h" - -#include "xml/node-event-vector.h" -#include "message-stack.h" -#include "document-private.h" -#include "ui/tools/pen-tool.h" -#include "ui/tools/node-tool.h" -#include "ui/tools-switch.h" -#include "knotholder.h" -#include "path-chemistry.h" -#include "xml/sp-css-attr.h" -#include "live_effects/lpeobject.h" -#include -#include "display/curve.h" -#include -#include -#include - -namespace Inkscape { - -namespace LivePathEffect { - -const Util::EnumData LPETypeData[] = { - // {constant defined in effect-enum.h, N_("name of your effect"), "name of your effect in SVG"} -/* 0.46 */ - {BEND_PATH, N_("Bend"), "bend_path"}, - {GEARS, N_("Gears"), "gears"}, - {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG - {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"}, -/* 0.47 */ - {VONKOCH, N_("VonKoch"), "vonkoch"}, - {KNOT, N_("Knot"), "knot"}, - {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"}, - {SPIRO, N_("Spiro spline"), "spiro"}, - {ENVELOPE, N_("Envelope Deformation"), "envelope"}, - {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"}, - {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"}, - {SKETCH, N_("Sketch"), "sketch"}, - {RULER, N_("Ruler"), "ruler"}, -/* 0.91 */ - {POWERSTROKE, N_("Power stroke"), "powerstroke"}, - {CLONE_ORIGINAL, N_("Clone original"), "clone_original"}, -/* 0.92 */ - {SIMPLIFY, N_("Simplify"), "simplify"}, - {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, - {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, //TODO:Wrong name with "-" - {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, - {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"}, - {SHOW_HANDLES, N_("Show handles"), "show_handles"}, - {ROUGHEN, N_("Roughen"), "roughen"}, - {BSPLINE, N_("BSpline"), "bspline"}, - {JOIN_TYPE, N_("Join type"), "join_type"}, - {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, - {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, - {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, -/* Ponyscape -> Inkscape 0.92*/ - {ATTACH_PATH, N_("Attach path"), "attach_path"}, - {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, - {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, - {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, - {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, -/* 9.93 */ - {MEASURE_SEGMENTS, N_("Measure Segments"), "measure_segments"}, - {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, - {BOOL_OP, N_("Boolean operation"), "bool_op"}, - {EMBRODERY_STITCH, N_("Embrodery stitch"), "embrodery_stitch"}, - {POWERCLIP, N_("Power clip"), "powerclip"}, - {POWERMASK, N_("Power mask"), "powermask"}, -#ifdef LPE_ENABLE_TEST_EFFECTS - {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"}, - {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"}, - {CIRCLE_WITH_RADIUS, N_("Circle (by center and radius)"), "circle_with_radius"}, - {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"}, - {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"}, - {EXTRUDE, N_("Extrude"), "extrude"}, - {LATTICE, N_("Lattice Deformation"), "lattice"}, - {LINE_SEGMENT, N_("Line Segment"), "line_segment"}, - {OFFSET, N_("Offset"), "offset"}, - {PARALLEL, N_("Parallel"), "parallel"}, - {PATH_LENGTH, N_("Path length"), "path_length"}, - {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"}, - {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"}, - {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, - {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, - {TEXT_LABEL, N_("Text label"), "text_label"}, -#endif - -}; -const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); - -int -Effect::acceptsNumClicks(EffectType type) { - switch (type) { - case INVALID_LPE: return -1; // in case we want to distinguish between invalid LPE and valid ones that expect zero clicks - case ANGLE_BISECTOR: return 3; - case CIRCLE_3PTS: return 3; - case CIRCLE_WITH_RADIUS: return 2; - case LINE_SEGMENT: return 2; - case PERP_BISECTOR: return 2; - default: return 0; - } -} - -Effect* -Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) -{ - Effect* neweffect = NULL; - switch (lpenr) { - case EMBRODERY_STITCH: - neweffect = static_cast ( new LPEEmbroderyStitch(lpeobj) ); - break; - case BOOL_OP: - neweffect = static_cast ( new LPEBool(lpeobj) ); - break; - case PATTERN_ALONG_PATH: - neweffect = static_cast ( new LPEPatternAlongPath(lpeobj) ); - break; - case BEND_PATH: - neweffect = static_cast ( new LPEBendPath(lpeobj) ); - break; - case SKETCH: - neweffect = static_cast ( new LPESketch(lpeobj) ); - break; - case ROUGH_HATCHES: - neweffect = static_cast ( new LPERoughHatches(lpeobj) ); - break; - case VONKOCH: - neweffect = static_cast ( new LPEVonKoch(lpeobj) ); - break; - case KNOT: - neweffect = static_cast ( new LPEKnot(lpeobj) ); - break; - case GEARS: - neweffect = static_cast ( new LPEGears(lpeobj) ); - break; - case CURVE_STITCH: - neweffect = static_cast ( new LPECurveStitch(lpeobj) ); - break; - case LATTICE: - neweffect = static_cast ( new LPELattice(lpeobj) ); - break; - case ENVELOPE: - neweffect = static_cast ( new LPEEnvelope(lpeobj) ); - break; - case CIRCLE_WITH_RADIUS: - neweffect = static_cast ( new LPECircleWithRadius(lpeobj) ); - break; - case PERSPECTIVE_PATH: - neweffect = static_cast ( new LPEPerspectivePath(lpeobj) ); - break; - case SPIRO: - neweffect = static_cast ( new LPESpiro(lpeobj) ); - break; - case CONSTRUCT_GRID: - neweffect = static_cast ( new LPEConstructGrid(lpeobj) ); - break; - case PERP_BISECTOR: - neweffect = static_cast ( new LPEPerpBisector(lpeobj) ); - break; - case TANGENT_TO_CURVE: - neweffect = static_cast ( new LPETangentToCurve(lpeobj) ); - break; - case MIRROR_SYMMETRY: - neweffect = static_cast ( new LPEMirrorSymmetry(lpeobj) ); - break; - case CIRCLE_3PTS: - neweffect = static_cast ( new LPECircle3Pts(lpeobj) ); - break; - case ANGLE_BISECTOR: - neweffect = static_cast ( new LPEAngleBisector(lpeobj) ); - break; - case PARALLEL: - neweffect = static_cast ( new LPEParallel(lpeobj) ); - break; - case COPY_ROTATE: - neweffect = static_cast ( new LPECopyRotate(lpeobj) ); - break; - case OFFSET: - neweffect = static_cast ( new LPEOffset(lpeobj) ); - break; - case RULER: - neweffect = static_cast ( new LPERuler(lpeobj) ); - break; - case INTERPOLATE: - neweffect = static_cast ( new LPEInterpolate(lpeobj) ); - break; - case INTERPOLATE_POINTS: - neweffect = static_cast ( new LPEInterpolatePoints(lpeobj) ); - break; - case TEXT_LABEL: - neweffect = static_cast ( new LPETextLabel(lpeobj) ); - break; - case PATH_LENGTH: - neweffect = static_cast ( new LPEPathLength(lpeobj) ); - break; - case LINE_SEGMENT: - neweffect = static_cast ( new LPELineSegment(lpeobj) ); - break; - case DOEFFECTSTACK_TEST: - neweffect = static_cast ( new LPEdoEffectStackTest(lpeobj) ); - break; - case BSPLINE: - neweffect = static_cast ( new LPEBSpline(lpeobj) ); - break; - case DYNASTROKE: - neweffect = static_cast ( new LPEDynastroke(lpeobj) ); - break; - case RECURSIVE_SKELETON: - neweffect = static_cast ( new LPERecursiveSkeleton(lpeobj) ); - break; - case EXTRUDE: - neweffect = static_cast ( new LPEExtrude(lpeobj) ); - break; - case POWERSTROKE: - neweffect = static_cast ( new LPEPowerStroke(lpeobj) ); - break; - case CLONE_ORIGINAL: - neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); - break; - case ATTACH_PATH: - neweffect = static_cast ( new LPEAttachPath(lpeobj) ); - break; - case FILL_BETWEEN_STROKES: - neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); - break; - case FILL_BETWEEN_MANY: - neweffect = static_cast ( new LPEFillBetweenMany(lpeobj) ); - break; - case ELLIPSE_5PTS: - neweffect = static_cast ( new LPEEllipse5Pts(lpeobj) ); - break; - case BOUNDING_BOX: - neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); - break; - case JOIN_TYPE: - neweffect = static_cast ( new LPEJoinType(lpeobj) ); - break; - case TAPER_STROKE: - neweffect = static_cast ( new LPETaperStroke(lpeobj) ); - break; - case SIMPLIFY: - neweffect = static_cast ( new LPESimplify(lpeobj) ); - break; - case LATTICE2: - neweffect = static_cast ( new LPELattice2(lpeobj) ); - break; - case PERSPECTIVE_ENVELOPE: - neweffect = static_cast ( new LPEPerspectiveEnvelope(lpeobj) ); - break; - case FILLET_CHAMFER: - neweffect = static_cast ( new LPEFilletChamfer(lpeobj) ); - break; - case POWERCLIP: - neweffect = static_cast ( new LPEPowerClip(lpeobj) ); - break; - case POWERMASK: - neweffect = static_cast ( new LPEPowerMask(lpeobj) ); - break; - case ROUGHEN: - neweffect = static_cast ( new LPERoughen(lpeobj) ); - break; - case SHOW_HANDLES: - neweffect = static_cast ( new LPEShowHandles(lpeobj) ); - break; - case TRANSFORM_2PTS: - neweffect = static_cast ( new LPETransform2Pts(lpeobj) ); - break; - case MEASURE_SEGMENTS: - neweffect = static_cast ( new LPEMeasureSegments(lpeobj) ); - break; - default: - g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); - neweffect = NULL; - break; - } - - if (neweffect) { - neweffect->readallParameters(lpeobj->getRepr()); - } - - return neweffect; -} - -void Effect::createAndApply(const char* name, SPDocument *doc, SPItem *item) -{ - // Path effect definition - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); - repr->setAttribute("effect", name); - - doc->getDefs()->getRepr()->addChild(repr, NULL); // adds to and assigns the 'id' attribute - const gchar * repr_id = repr->attribute("id"); - Inkscape::GC::release(repr); - - gchar *href = g_strdup_printf("#%s", repr_id); - SP_LPE_ITEM(item)->addPathEffect(href, true); - g_free(href); -} - -void -Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) -{ - createAndApply(LPETypeConverter.get_key(type).c_str(), doc, item); -} - -Effect::Effect(LivePathEffectObject *lpeobject) - : apply_to_clippath_and_mask(false), - is_clip_or_mask(false), - _provides_knotholder_entities(false), - oncanvasedit_it(0), - is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), - show_orig_path(false), - keep_paths(false), - is_load(true), - lpeobj(lpeobject), - concatenate_before_pwd2(false), - sp_lpe_item(NULL), - current_zoom(1), - upd_params(true), - current_shape(NULL), - provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden - is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden -{ - registerParameter( dynamic_cast(&is_visible) ); - is_visible.widget_is_visible = false; - current_zoom = 0.0; -} - -Effect::~Effect() -{ -} - -Glib::ustring -Effect::getName() const -{ - if (lpeobj->effecttype_set && LPETypeConverter.is_valid_id(lpeobj->effecttype) ) - return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) ); - else - return Glib::ustring( _("No effect") ); -} - -EffectType -Effect::effectType() const { - return lpeobj->effecttype; -} - -/** - * Is performed a single time when the effect is freshly applied to a path - */ -void -Effect::doOnApply (SPLPEItem const*/*lpeitem*/) -{ -} - -void -Effect::setCurrentZoom(double cZ) -{ - current_zoom = cZ; -} - -void -Effect::setSelectedNodePoints(std::vector sNP) -{ - selectedNodesPoints = sNP; -} - -bool -Effect::isNodePointSelected(Geom::Point const &nodePoint) const -{ - if (selectedNodesPoints.size() > 0) { - using Geom::X; - using Geom::Y; - for (std::vector::const_iterator i = selectedNodesPoints.begin(); - i != selectedNodesPoints.end(); ++i) { - Geom::Point p = *i; - Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); - Geom::Point p2(nodePoint[X],nodePoint[Y]); - p2 *= transformCoordinate; - if (Geom::are_near(p, p2, 0.01)) { - return true; - } - } - } - return false; -} - -void -Effect::processObjects(LpeAction lpe_action) -{ - SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return; - } - for (std::vector::iterator el_it = items.begin(); - el_it != items.end(); ++el_it) { - const char * id = *el_it; - if (!id) { - return; - } - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { - Inkscape::XML::Node * elemnode = elemref->getRepr(); - std::vector item_list; - item_list.push_back(SP_ITEM(elemref)); - std::vector item_to_select; - std::vector item_selected; - SPCSSAttr *css; - Glib::ustring css_str; - SPItem *item = SP_ITEM(elemref); - switch (lpe_action){ - case LPE_TO_OBJECTS: - if (item->isHidden()) { - sp_object_ref(item, 0 ); - item->deleteObject(true); - sp_object_unref(item); - } else { - if (elemnode->attribute("inkscape:path-effect")) { - sp_item_list_to_curves(item_list, item_selected, item_to_select); - } - elemnode->setAttribute("sodipodi:insensitive", NULL); - } - break; - - case LPE_ERASE: - sp_object_ref(item, 0 ); - item->deleteObject(true); - sp_object_unref(item); - break; - - case LPE_VISIBILITY: - css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, elemref->getRepr()->attribute("style")); - if (!this->isVisible()/* && std::strcmp(elemref->getId(),sp_lpe_item->getId()) != 0*/) { - css->setAttribute("display", "none"); - } else { - css->setAttribute("display", NULL); - } - sp_repr_css_write_string(css,css_str); - elemnode->setAttribute("style", css_str.c_str()); - break; - - default: - break; - } - } - } - if (lpe_action == LPE_ERASE || lpe_action == LPE_TO_OBJECTS) { - items.clear(); - } -} - -/** - * Is performed each time before the effect is updated. - */ -void -Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) -{ - //Do nothing for simple effects -} - - -void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) -{ - is_load = false; -} - -void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) -{ -} -void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) -{ -} -//secret impl methods (shhhh!) -void Effect::doOnApply_impl(SPLPEItem const* lpeitem) -{ - sp_lpe_item = const_cast(lpeitem); - doOnApply(lpeitem); -} - -void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask) -{ - sp_lpe_item = const_cast(lpeitem); - is_clip_or_mask = clip_or_mask; - doBeforeEffect(lpeitem); - update_helperpath(); -} - -/** - * Effects can have a parameter path set before they are applied by accepting a nonzero number of - * mouse clicks. This method activates the pen context, which waits for the specified number of - * clicks. Override Effect::acceptsNumClicks() to return the number of expected mouse clicks. - */ -void -Effect::doAcceptPathPreparations(SPLPEItem *lpeitem) -{ - // switch to pen context - SPDesktop *desktop = SP_ACTIVE_DESKTOP; // TODO: Is there a better method to find the item's desktop? - if (!tools_isactive(desktop, TOOLS_FREEHAND_PEN)) { - tools_switch(desktop, TOOLS_FREEHAND_PEN); - } - - Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; - Inkscape::UI::Tools::PenTool *pc = SP_PEN_CONTEXT(ec); - pc->expecting_clicks_for_LPE = this->acceptsNumClicks(); - pc->waiting_LPE = this; - pc->waiting_item = lpeitem; - pc->polylines_only = true; - - ec->desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, - g_strdup_printf(_("Please specify a parameter path for the LPE '%s' with %d mouse clicks"), - getName().c_str(), acceptsNumClicks())); -} - -void -Effect::writeParamsToSVG() { - std::vector::iterator p; - for (p = param_vector.begin(); p != param_vector.end(); ++p) { - (*p)->write_to_SVG(); - } -} - -/** - * If the effect expects a path parameter (specified by a number of mouse clicks) before it is - * applied, this is the method that processes the resulting path. Override it to customize it for - * your LPE. But don't forget to call the parent method so that is_ready is set to true! - */ -void -Effect::acceptParamPath (SPPath const*/*param_path*/) { - setReady(); -} - -/* - * Here be the doEffect function chain: - */ -void -Effect::doEffect (SPCurve * curve) -{ - Geom::PathVector orig_pathv = curve->get_pathvector(); - - Geom::PathVector result_pathv = doEffect_path(orig_pathv); - - curve->set_pathvector(result_pathv); -} - -Geom::PathVector -Effect::doEffect_path (Geom::PathVector const & path_in) -{ - Geom::PathVector path_out; - - if ( !concatenate_before_pwd2 ) { - // default behavior - for (unsigned int i=0; i < path_in.size(); i++) { - Geom::Piecewise > pwd2_in = path_in[i].toPwSb(); - Geom::Piecewise > pwd2_out = doEffect_pwd2(pwd2_in); - Geom::PathVector path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE); - // add the output path vector to the already accumulated vector: - for (unsigned int j=0; j < path.size(); j++) { - path_out.push_back(path[j]); - } - } - } else { - // concatenate the path into possibly discontinuous pwd2 - Geom::Piecewise > pwd2_in; - for (unsigned int i=0; i < path_in.size(); i++) { - pwd2_in.concat( path_in[i].toPwSb() ); - } - Geom::Piecewise > pwd2_out = doEffect_pwd2(pwd2_in); - path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE); - } - - return path_out; -} - -Geom::Piecewise > -Effect::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) -{ - g_warning("Effect has no doEffect implementation"); - return pwd2_in; -} - -void -Effect::readallParameters(Inkscape::XML::Node const* repr) -{ - std::vector::iterator it = param_vector.begin(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - while (it != param_vector.end()) { - Parameter * param = *it; - const gchar * key = param->param_key.c_str(); - const gchar * value = repr->attribute(key); - if (value) { - bool accepted = param->param_readSVGValue(value); - if (!accepted) { - g_warning("Effect::readallParameters - '%s' not accepted for %s", value, key); - } - } else { - Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + - (Glib::ustring)LPETypeConverter.get_key(effectType()).c_str() + - (Glib::ustring)"/" + - (Glib::ustring)key; - bool valid = prefs->getEntry(pref_path).isValid(); - if(valid){ - param->param_update_default(prefs->getString(pref_path).c_str()); - } else { - param->param_set_default(); - } - } - ++it; - } -} - -/* This function does not and SHOULD NOT write to XML */ -void -Effect::setParameter(const gchar * key, const gchar * new_value) -{ - Parameter * param = getParameter(key); - if (param) { - if (new_value) { - bool accepted = param->param_readSVGValue(new_value); - if (!accepted) { - g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key); - } - } else { - // set default value - param->param_set_default(); - } - } -} - -void -Effect::registerParameter(Parameter * param) -{ - param_vector.push_back(param); -} - - -/** - * Add all registered LPE knotholder handles to the knotholder - */ -void -Effect::addHandles(KnotHolder *knotholder, SPItem *item) { - using namespace Inkscape::LivePathEffect; - - // add handles provided by the effect itself - addKnotHolderEntities(knotholder, item); - - // add handles provided by the effect's parameters (if any) - for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { - (*p)->addKnotHolderEntities(knotholder, item); - } -} - -/** - * Return a vector of PathVectors which contain all canvas indicators for this effect. - * This is the function called by external code to get all canvas indicators (effect and its parameters) - * lpeitem = the item onto which this effect is applied - * @todo change return type to one pathvector, add all paths to one pathvector instead of maintaining a vector of pathvectors - */ -std::vector -Effect::getCanvasIndicators(SPLPEItem const* lpeitem) -{ - std::vector hp_vec; - - // add indicators provided by the effect itself - addCanvasIndicators(lpeitem, hp_vec); - - // add indicators provided by the effect's parameters - for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { - (*p)->addCanvasIndicators(lpeitem, hp_vec); - } - - return hp_vec; -} - -/** - * Add possible canvas indicators (i.e., helperpaths other than the original path) to \a hp_vec - * This function should be overwritten by derived effects if they want to provide their own helperpaths. - */ -void -Effect::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &/*hp_vec*/) -{ -} - -/** - * Call to a method on nodetool to update the helper path from the effect - */ -void -Effect::update_helperpath() { - Inkscape::UI::Tools::sp_update_helperpath(); -} - -/** - * This *creates* a new widget, management of deletion should be done by the caller - */ -Gtk::Widget * -Effect::newWidget() -{ - // use manage here, because after deletion of Effect object, others might still be pointing to this widget. - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); - - vbox->set_border_width(5); - - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter * param = *it; - Gtk::Widget * widg = param->param_newWidget(); - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - -/** - * This *creates* a new widget, with default values setter - */ -Gtk::Widget * -Effect::defaultParamSet() -{ - // use manage here, because after deletion of Effect object, others might still be pointing to this widget. - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); - Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() ); - Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType()); - Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType()); - std::vector::iterator it = param_vector.begin(); - Inkscape::UI::Widget::Registry * wr; - bool has_params = false; - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - has_params = true; - Parameter * param = *it; - Glib::ustring * tip = param->param_getTooltip(); - const gchar * key = param->param_key.c_str(); - const gchar * value = param->param_label.c_str(); - - Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + - effectkey + - (Glib::ustring)"/" + - (Glib::ustring)key; - bool valid = prefs->getEntry(pref_path).isValid(); - const gchar * set_or_upd; - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); - if (valid) { - set_or_upd = _("Update"); - def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); - } else { - set_or_upd = _("Set"); - ove = Glib::ustring(_("Default value overridden: None\n")); - } - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(param->param_getSVGValue()); - Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) ); - Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START)); - parameter_label->set_use_markup(true); - parameter_label->set_use_underline(true); - Glib::ustring tooltip = Glib::ustring("") + parameter_label->get_text () + Glib::ustring("\n") + param->param_tooltip + Glib::ustring("\n\n"); - parameter_label->set_ellipsize(Pango::ELLIPSIZE_END); - parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); - vbox_param->pack_start(*parameter_label, true, true, 2); - Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); - Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); - unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); - - set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); - if (!valid) { - unset->set_sensitive(false); - } - vbox_param->pack_start(*set, true, true, 2); - vbox_param->pack_start(*unset, true, true, 2); - - vbox_expander->pack_start(*vbox_param, true, true, 2); - } - ++it; - } - Glib::ustring tip = "" + effectname + (Glib::ustring)_(": Set default parameters"); - Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip)); - expander->set_use_markup(true); - expander->add(*vbox_expander); - expander->set_expanded(false); - vbox->pack_start(*dynamic_cast (expander), true, true, 2); - if (has_params) { - Gtk::Widget *vboxwidg = dynamic_cast(vbox); - vboxwidg->set_margin_bottom(10); - vboxwidg->set_margin_top(5); - return vboxwidg; - } else { - return NULL; - } -} - -void -Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(pref_path, (Glib::ustring)value); - gchar * label = _("Update"); - set->set_label((Glib::ustring)label); - unset->set_sensitive(true); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(value) + Glib::ustring("\n"); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); - parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); -} - -void -Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->remove(pref_path); - gchar * label = _("Set"); - set->set_label((Glib::ustring)label); - unset->set_sensitive(false); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: None\n")); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); - parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); -} - -Inkscape::XML::Node *Effect::getRepr() -{ - return lpeobj->getRepr(); -} - -SPDocument *Effect::getSPDoc() -{ - if (lpeobj->document == NULL) { - g_message("Effect::getSPDoc() returns NULL"); - } - return lpeobj->document; -} - -Parameter * -Effect::getParameter(const char * key) -{ - Glib::ustring stringkey(key); - - if (param_vector.empty()) return NULL; - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - Parameter * param = *it; - if ( param->param_key == key) { - return param; - } - - ++it; - } - - return NULL; -} - -Parameter * -Effect::getNextOncanvasEditableParam() -{ - if (param_vector.size() == 0) // no parameters - return NULL; - - oncanvasedit_it++; - if (oncanvasedit_it >= static_cast(param_vector.size())) { - oncanvasedit_it = 0; - } - int old_it = oncanvasedit_it; - - do { - Parameter * param = param_vector[oncanvasedit_it]; - if(param && param->oncanvas_editable) { - return param; - } else { - oncanvasedit_it++; - if (oncanvasedit_it == static_cast(param_vector.size())) { // loop round the map - oncanvasedit_it = 0; - } - } - } while (oncanvasedit_it != old_it); // iterate until complete loop through map has been made - - return NULL; -} - -void -Effect::editNextParamOncanvas(SPItem * item, SPDesktop * desktop) -{ - if (!desktop) return; - - Parameter * param = getNextOncanvasEditableParam(); - if (param) { - param->param_editOncanvas(item, desktop); - gchar *message = g_strdup_printf(_("Editing parameter %s."), param->param_label.c_str()); - desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message); - g_free(message); - } else { - desktop->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("None of the applied path effect's parameters can be edited on-canvas.") ); - } -} - -/* This function should reset the defaults and is used for example to initialize an effect right after it has been applied to a path -* The nice thing about this is that this function can use knowledge of the original path and set things accordingly for example to the size or origin of the original path! -*/ -void -Effect::resetDefaults(SPItem const* /*item*/) -{ - std::vector::iterator p; - for (p = param_vector.begin(); p != param_vector.end(); ++p) { - (*p)->param_set_default(); - (*p)->write_to_SVG(); - } -} - -//Activate handle your transform filling your effect on SPPath.cpp -void -Effect::transform_multiply(Geom::Affine const& postmul, bool set) -{ - // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { - Parameter * param = *it; - param->param_transform_multiply(postmul, set); - } -} - -bool -Effect::providesKnotholder() const -{ - // does the effect actively provide any knotholder entities of its own? - if (_provides_knotholder_entities) { - return true; - } - - // otherwise: are there any parameters that have knotholderentities? - for (std::vector::const_iterator p = param_vector.begin(); p != param_vector.end(); ++p) { - if ((*p)->providesKnotHolderEntities()) { - return true; - } - } - - return false; -} - -} /* namespace LivePathEffect */ - -} /* namespace Inkscape */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-fillet-chamfer.cpp.orig b/src/live_effects/lpe-fillet-chamfer.cpp.orig deleted file mode 100644 index f4269d36c3..0000000000 --- a/src/live_effects/lpe-fillet-chamfer.cpp.orig +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Author(s): - * Jabiertxo Arraiza Cenoz - * - * Copyright (C) 2014 Author(s) - * - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "live_effects/lpe-fillet-chamfer.h" -#include "helper/geom.h" -#include "display/curve.h" -#include "helper/geom-curves.h" -#include "helper/geom-satellite.h" -#include <2geom/elliptical-arc.h> -#include "knotholder.h" -#include - -// TODO due to internal breakage in glibmm headers, this must be last: -#include - -namespace Inkscape { -namespace LivePathEffect { - -static const Util::EnumData FilletmethodData[] = { - { FM_AUTO, N_("Auto"), "auto" }, - { FM_ARC, N_("Force arc"), "arc" }, - { FM_BEZIER, N_("Force bezier"), "bezier" } -}; -static const Util::EnumDataConverter FMConverter(FilletmethodData, FM_END); - -LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) - : Effect(lpeobject), - unit(_("Unit"), _("Unit"), "unit", &wr, this, "px"), - satellites_param("Satellites_param", "Satellites_param", - "satellites_param", &wr, this), - method(_("Method:"), _("Methods to calculate the fillet or chamfer"), - "method", FMConverter, &wr, this, FM_AUTO), - mode(_("Mode:"), _("Mode, fillet or chamfer"), - "mode", &wr, this, "F", true), - radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, - this, 0.0), - chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", - &wr, this, 1), - flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), - "flexible", &wr, this, false), - mirror_knots(_("Mirror Knots"), _("Mirror Knots"), "mirror_knots", &wr, - this, true), - only_selected(_("Change only selected nodes"), - _("Change only selected nodes"), "only_selected", &wr, this, - false), - use_knot_distance(_("Use knots distance instead radius"), - _("Use knots distance instead radius"), - "use_knot_distance", &wr, this, false), - hide_knots(_("Hide knots"), _("Hide knots"), "hide_knots", &wr, this, - false), - apply_no_radius(_("Apply changes if radius = 0"), _("Apply changes if radius = 0"), "apply_no_radius", &wr, this, true), - apply_with_radius(_("Apply changes if radius > 0"), _("Apply changes if radius > 0"), "apply_with_radius", &wr, this, true), - helper_size(_("Helper path size with direction to node:"), - _("Helper path size with direction to node"), "helper_size", &wr, this, 0), - _pathvector_satellites(NULL), - _degenerate_hide(false) -{ - registerParameter(&satellites_param); - registerParameter(&unit); - registerParameter(&method); - registerParameter(&mode); - registerParameter(&radius); - registerParameter(&chamfer_steps); - registerParameter(&helper_size); - registerParameter(&flexible); - registerParameter(&use_knot_distance); - registerParameter(&mirror_knots); - registerParameter(&apply_no_radius); - registerParameter(&apply_with_radius); - registerParameter(&only_selected); - registerParameter(&hide_knots); - - radius.param_set_range(0.0, Geom::infinity()); - radius.param_set_increments(1, 1); - radius.param_set_digits(4); - radius.param_set_undo(false); - chamfer_steps.param_set_range(1, 999); - chamfer_steps.param_set_increments(1, 1); - chamfer_steps.param_set_digits(0); - helper_size.param_set_range(0, 999); - helper_size.param_set_increments(5, 5); - helper_size.param_set_digits(0); - _provides_knotholder_entities = true; -} - -void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) -{ - SPLPEItem *splpeitem = const_cast(lpeItem); - SPShape *shape = dynamic_cast(splpeitem); - if (shape) { - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); - Satellites satellites; - double power = radius; - if (!flexible) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - SPNamedView *nv = sp_document_namedview(document, NULL); - Glib::ustring display_unit = nv->display_units->abbr; - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); - } - SatelliteType satellite_type = FILLET; - std::map gchar_map_to_satellite_type = - boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); - if (it != gchar_map_to_satellite_type.end()) { - satellite_type = it->second; - } - for (Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - std::vector subpath_satellites; - for (Geom::Path::const_iterator curve_it = path_it->begin(); curve_it != path_it->end(); ++curve_it) { - //Maybe we want this satellites... - //if (curve_it->isDegenerate()) { - // continue - //} - Satellite satellite(satellite_type); - satellite.setSteps(chamfer_steps); - satellite.setAmount(power); - satellite.setIsTime(flexible); - satellite.setHasMirror(mirror_knots); - satellite.setHidden(hide_knots); - subpath_satellites.push_back(satellite); - } - //we add the last satellite on open path because _pathvector_satellites is related to nodes, not curves - //so maybe in the future we can need this last satellite in other effects - //don't remove for this effect because _pathvector_satellites class has methods when the path is modiffied - //and we want one method for all uses - if (!path_it->closed()) { - Satellite satellite(satellite_type); - satellite.setSteps(chamfer_steps); - satellite.setAmount(power); - satellite.setIsTime(flexible); - satellite.setHasMirror(mirror_knots); - satellite.setHidden(hide_knots); - subpath_satellites.push_back(satellite); - } - satellites.push_back(subpath_satellites); - } - _pathvector_satellites = new PathVectorSatellites(); - _pathvector_satellites->setPathVector(pathv); - _pathvector_satellites->setSatellites(satellites); - satellites_param.setPathVectorSatellites(_pathvector_satellites); - } else { - g_warning("LPE Fillet/Chamfer can only be applied to shapes (not groups)."); - SPLPEItem *item = const_cast(lpeItem); - item->removeCurrentPathEffect(false); - } -} - -Gtk::Widget *LPEFilletChamfer::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = param->param_newWidget(); - if (param->param_key == "radius") { - Inkscape::UI::Widget::Scalar *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg_registered->signal_value_changed().connect( - sigc::mem_fun(*this, &LPEFilletChamfer::updateAmount)); - widg = widg_registered; - if (widg) { - Gtk::HBox *scalar_parameter = dynamic_cast(widg); - std::vector childList = scalar_parameter->get_children(); - Gtk::Entry *entry_widget = dynamic_cast(childList[1]); - entry_widget->set_width_chars(6); - } -// } else if (param->param_key == "unit") { -// Inkscape::UI::Widget::RegisteredUnitMenu* widg_registered = -// Gtk::manage(dynamic_cast< Inkscape::UI::Widget::RegisteredUnitMenu *>(widg)); -// widg_registered->setUnit(unit.get_abbreviation()); -// widg_registered->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change unit parameter")); -// widg_registered->getUnitMenu()->signal_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::convertUnit)); -// widg = widg_registered; - } else if (param->param_key == "chamfer_steps") { - Inkscape::UI::Widget::Scalar *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg_registered->signal_value_changed().connect( - sigc::mem_fun(*this, &LPEFilletChamfer::updateChamferSteps)); - widg = widg_registered; - if (widg) { - Gtk::HBox *scalar_parameter = dynamic_cast(widg); - std::vector childList = scalar_parameter->get_children(); - Gtk::Entry *entry_widget = dynamic_cast(childList[1]); - entry_widget->set_width_chars(3); - } - } else if (param->param_key == "helper_size") { - Inkscape::UI::Widget::Scalar *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg_registered->signal_value_changed().connect( - sigc::mem_fun(*this, &LPEFilletChamfer::refreshKnots)); - } else if (param->param_key == "only_selected") { - Gtk::manage(widg); - } - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - ++it; - } - - Gtk::HBox *fillet_container = Gtk::manage(new Gtk::HBox(true, 0)); - Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); - fillet->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),FILLET)); - - fillet_container->pack_start(*fillet, true, true, 2); - Gtk::Button *inverse_fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); - inverse_fillet->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),INVERSE_FILLET)); - fillet_container->pack_start(*inverse_fillet, true, true, 2); - - Gtk::HBox *chamfer_container = Gtk::manage(new Gtk::HBox(true, 0)); - Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); - chamfer->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),CHAMFER)); - - chamfer_container->pack_start(*chamfer, true, true, 2); - Gtk::Button *inverse_chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer")))); - inverse_chamfer->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEFilletChamfer::updateSatelliteType),INVERSE_CHAMFER)); - chamfer_container->pack_start(*inverse_chamfer, true, true, 2); - - vbox->pack_start(*fillet_container, true, true, 2); - vbox->pack_start(*chamfer_container, true, true, 2); - - return vbox; -} - -void LPEFilletChamfer::refreshKnots() -{ - if (satellites_param._knoth) { - satellites_param._knoth->update_knots(); - } -} - -void LPEFilletChamfer::updateAmount() -{ - setSelected(_pathvector_satellites); - double power = radius; - if (!flexible) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - SPNamedView *nv = sp_document_namedview(document, NULL); - Glib::ustring display_unit = nv->display_units->abbr; - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); - } - _pathvector_satellites->updateAmount(power, apply_no_radius, apply_with_radius, only_selected, - use_knot_distance, flexible); - satellites_param.setPathVectorSatellites(_pathvector_satellites); -} - -//void LPEFilletChamfer::convertUnit() -//{ -// SPDocument * document = SP_ACTIVE_DOCUMENT; -// SPNamedView *nv = sp_document_namedview(document, NULL); -// Glib::ustring display_unit = nv->display_units->abbr; -// _pathvector_satellites->convertUnit(unit.get_abbreviation(), display_unit, apply_no_radius, apply_with_radius); -// satellites_param.setPathVectorSatellites(_pathvector_satellites); -//} - -void LPEFilletChamfer::updateChamferSteps() -{ - setSelected(_pathvector_satellites); - _pathvector_satellites->updateSteps(chamfer_steps, apply_no_radius, apply_with_radius, only_selected); - satellites_param.setPathVectorSatellites(_pathvector_satellites); -} - -void LPEFilletChamfer::updateSatelliteType(SatelliteType satellitetype) -{ - std::map satellite_type_to_gchar_map = - boost::assign::map_list_of(FILLET, "F")(INVERSE_FILLET, "IF")(CHAMFER, "C")(INVERSE_CHAMFER, "IC")(INVALID_SATELLITE, "KO"); - mode.param_setValue((Glib::ustring)satellite_type_to_gchar_map.at(satellitetype)); - setSelected(_pathvector_satellites); - _pathvector_satellites->updateSatelliteType(satellitetype, apply_no_radius, apply_with_radius, only_selected); - satellites_param.setPathVectorSatellites(_pathvector_satellites); -} - -void LPEFilletChamfer::setSelected(PathVectorSatellites *_pathvector_satellites){ - Geom::PathVector const pathv = _pathvector_satellites->getPathVector(); - Satellites satellites = _pathvector_satellites->getSatellites(); - for (size_t i = 0; i < satellites.size(); ++i) { - for (size_t j = 0; j < satellites[i].size(); ++j) { - Geom::Curve const &curve_in = pathv[i][j]; - if (only_selected && isNodePointSelected(curve_in.initialPoint()) ){ - satellites[i][j].setSelected(true); - } else { - satellites[i][j].setSelected(false); - } - } - } - _pathvector_satellites->setSatellites(satellites); -} - -void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) -{ - if (!pathvector_before_effect.empty()) { - //fillet chamfer specific calls - satellites_param.setUseDistance(use_knot_distance); - satellites_param.setCurrentZoom(current_zoom); - //mandatory call - satellites_param.setEffectType(effectType()); - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); - //if are diferent sizes call to recalculate - //TODO: Update the satellite data in paths modified, - Satellites satellites = satellites_param.data(); - if (satellites.empty()) { - doOnApply(lpeItem); - satellites = satellites_param.data(); - } - if (_pathvector_satellites) { - size_t number_nodes = pathv.nodes().size(); - size_t previous_number_nodes = _pathvector_satellites->getTotalSatellites(); - if (number_nodes != previous_number_nodes) { - Satellites satellites; - double power = radius; - if (!flexible) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - SPNamedView *nv = sp_document_namedview(document, NULL); - Glib::ustring display_unit = nv->display_units->abbr; - power = Inkscape::Util::Quantity::convert(power, unit.get_abbreviation(), display_unit.c_str()); - } - SatelliteType satellite_type = FILLET; - std::map gchar_map_to_satellite_type = - boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); - if (it != gchar_map_to_satellite_type.end()) { - satellite_type = it->second; - } - Satellite satellite(satellite_type); - satellite.setSteps(chamfer_steps); - satellite.setAmount(power); - satellite.setIsTime(flexible); - satellite.setHasMirror(mirror_knots); - satellite.setHidden(hide_knots); - _pathvector_satellites->recalculateForNewPathVector(pathv, satellite); - satellites = _pathvector_satellites->getSatellites(); - } - } - if (_degenerate_hide) { - satellites_param.setGlobalKnotHide(true); - } else { - satellites_param.setGlobalKnotHide(false); - } - if (hide_knots) { - satellites_param.setHelperSize(0); - } else { - satellites_param.setHelperSize(helper_size); - } - for (size_t i = 0; i < satellites.size(); ++i) { - for (size_t j = 0; j < satellites[i].size(); ++j) { - if (j >= pathv[i].size()) { - continue; - } - Geom::Curve const &curve_in = pathv[i][j]; - if (satellites[i][j].is_time != flexible) { - satellites[i][j].is_time = flexible; - double amount = satellites[i][j].amount; - if (satellites[i][j].is_time) { - double time = timeAtArcLength(amount, curve_in); - satellites[i][j].amount = time; - } else { - double size = arcLengthAt(amount, curve_in); - satellites[i][j].amount = size; - } - } - if (satellites[i][j].has_mirror != mirror_knots) { - satellites[i][j].has_mirror = mirror_knots; - } - satellites[i][j].hidden = hide_knots; - if (only_selected && isNodePointSelected(curve_in.initialPoint()) ){ - satellites[i][j].setSelected(true); - } - } - } - if (!_pathvector_satellites) { - _pathvector_satellites = new PathVectorSatellites(); - } - _pathvector_satellites->setPathVector(pathv); - _pathvector_satellites->setSatellites(satellites); - satellites_param.setPathVectorSatellites(_pathvector_satellites, false); - refreshKnots(); - } else { - g_warning("LPE Fillet can only be applied to shapes (not groups)."); - } -} - -void -LPEFilletChamfer::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) -{ - hp_vec.push_back(_hp); -} - -void -LPEFilletChamfer::addChamferSteps(Geom::Path &tmp_path, Geom::Path path_chamfer, Geom::Point end_arc_point, size_t steps) -{ - setSelected(_pathvector_satellites); - double path_subdivision = 1.0 / steps; - for (size_t i = 1; i < steps; i++) { - Geom::Point chamfer_step = path_chamfer.pointAt(path_subdivision * i); - tmp_path.appendNew(chamfer_step); - } - tmp_path.appendNew(end_arc_point); -} - -Geom::PathVector -LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) -{ - const double GAP_HELPER = 0.00001; - Geom::PathVector path_out; - size_t path = 0; - const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); - _degenerate_hide = false; - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(path_in); - Satellites satellites = _pathvector_satellites->getSatellites(); - for (Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - Geom::Path tmp_path; - if (path_it->size() == 1) { - path++; - tmp_path.start(path_it[0].pointAt(0)); - tmp_path.append(path_it[0]); - path_out.push_back(tmp_path); - continue; - } - double time0 = 0; - size_t curve = 0; - for (Geom::Path::const_iterator curve_it1 = path_it->begin(); curve_it1 != path_it->end(); ++curve_it1) { - size_t next_index = curve + 1; - if (curve == pathv[path].size() - 1 && pathv[path].closed()) { - next_index = 0; - } - //append last extreme of paths on open paths - if (curve == pathv[path].size() -1 && !pathv[path].closed()) { //the path is open and we are at end of path - if (time0 != 1) { //Previous satellite not at 100% amount - Geom::Curve *last_curve = curve_it1->portion(time0, 1); - last_curve->setInitial(tmp_path.finalPoint()); - tmp_path.append(*last_curve); - } - continue; - } - Geom::Curve const &curve_it2 = pathv[path][next_index]; - Satellite satellite = satellites[path][next_index]; - if (Geom::are_near((*curve_it1).initialPoint(), (*curve_it1).finalPoint())) { - _degenerate_hide = true; - g_warning("Knots hidden if consecutive nodes has the same position."); - return path_in; - } - if (!curve) { //curve == 0 - if (!path_it->closed()) { - time0 = 0; - } else { - time0 = satellites[path][0].time(*curve_it1); - } - } - double s = satellite.arcDistance(curve_it2); - double time1 = satellite.time(s, true, (*curve_it1)); - double time2 = satellite.time(curve_it2); - if (time1 <= time0) { - time1 = time0; - } - if (time2 > 1) { - time2 = 1; - } - Geom::Curve *knot_curve_1 = curve_it1->portion(time0, time1); - Geom::Curve *knot_curve_2 = curve_it2.portion(time2, 1); - if (curve > 0) { - knot_curve_1->setInitial(tmp_path.finalPoint()); - } else { - tmp_path.start((*curve_it1).pointAt(time0)); - } - - Geom::Point start_arc_point = knot_curve_1->finalPoint(); - Geom::Point end_arc_point = curve_it2.pointAt(time2); - //add a gap helper - if (time2 == 1) { - end_arc_point = curve_it2.pointAt(time2 - GAP_HELPER); - } - if (time1 == time0) { - start_arc_point = curve_it1->pointAt(time1 + GAP_HELPER); - } - - double k1 = distance(start_arc_point, curve_it1->finalPoint()) * K; - double k2 = distance(curve_it2.initialPoint(), end_arc_point) * K; - Geom::CubicBezier const *cubic_1 = dynamic_cast(&*knot_curve_1); - Geom::CubicBezier const *cubic_2 = dynamic_cast(&*knot_curve_2); - Geom::Ray ray_1(start_arc_point, curve_it1->finalPoint()); - Geom::Ray ray_2(curve_it2.initialPoint(), end_arc_point); - if (cubic_1) { - ray_1.setPoints((*cubic_1)[2], start_arc_point); - } - if (cubic_2) { - ray_2.setPoints(end_arc_point, (*cubic_2)[1]); - } - bool ccw_toggle = cross(curve_it1->finalPoint() - start_arc_point, end_arc_point - start_arc_point) < 0; - double angle = angle_between(ray_1, ray_2, ccw_toggle); - double handle_angle_1 = ray_1.angle() - angle; - double handle_angle_2 = ray_2.angle() + angle; - if (ccw_toggle) { - handle_angle_1 = ray_1.angle() + angle; - handle_angle_2 = ray_2.angle() - angle; - } - Geom::Point handle_1 = Geom::Point::polar(ray_1.angle(), k1) + start_arc_point; - Geom::Point handle_2 = end_arc_point - Geom::Point::polar(ray_2.angle(), k2); - Geom::Point inverse_handle_1 = Geom::Point::polar(handle_angle_1, k1) + start_arc_point; - Geom::Point inverse_handle_2 = end_arc_point - Geom::Point::polar(handle_angle_2, k2); - if (time0 == 1) { - handle_1 = start_arc_point; - inverse_handle_1 = start_arc_point; - } - //remove gap helper - if (time2 == 1) { - end_arc_point = curve_it2.pointAt(time2); - } - if (time1 == time0) { - start_arc_point = curve_it1->pointAt(time0); - } - if (time1 != 1) { - if (time1 != time0 || (time1 == 1 && time0 == 1)) { - if (!knot_curve_1->isDegenerate()) { - tmp_path.append(*knot_curve_1); - } - } - SatelliteType type = satellite.satellite_type; - size_t steps = satellite.steps; - if (!steps) steps = 1; - Geom::Line const x_line(Geom::Point(0, 0), Geom::Point(1, 0)); - Geom::Line const angled_line(start_arc_point, end_arc_point); - double arc_angle = Geom::angle_between(x_line, angled_line); - double radius = Geom::distance(start_arc_point, middle_point(start_arc_point, end_arc_point)) / - sin(angle / 2.0); - Geom::Coord rx = radius; - Geom::Coord ry = rx; - bool eliptical = (is_straight_curve(*curve_it1) && - is_straight_curve(curve_it2) && method != FM_BEZIER) || - method == FM_ARC; - switch (type) { - case CHAMFER: - { - Geom::Path path_chamfer; - path_chamfer.start(tmp_path.finalPoint()); - if (eliptical) { - ccw_toggle = ccw_toggle ? 0 : 1; - path_chamfer.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); - } else { - path_chamfer.appendNew(handle_1, handle_2, end_arc_point); - } - addChamferSteps(tmp_path, path_chamfer, end_arc_point, steps); - } - break; - case INVERSE_CHAMFER: - { - Geom::Path path_chamfer; - path_chamfer.start(tmp_path.finalPoint()); - if (eliptical) { - path_chamfer.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); - } else { - path_chamfer.appendNew(inverse_handle_1, inverse_handle_2, end_arc_point); - } - addChamferSteps(tmp_path, path_chamfer, end_arc_point, steps); - } - break; - case INVERSE_FILLET: - { - if (eliptical) { - tmp_path.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); - } else { - tmp_path.appendNew(inverse_handle_1, inverse_handle_2, end_arc_point); - } - } - break; - default: //fillet - { - if (eliptical) { - ccw_toggle = ccw_toggle ? 0 : 1; - tmp_path.appendNew(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); - } else { - tmp_path.appendNew(handle_1, handle_2, end_arc_point); - } - } - break; - } - } else { - if (!knot_curve_1->isDegenerate()) { - tmp_path.append(*knot_curve_1); - } - } - curve++; - time0 = time2; - } - if (path_it->closed()) { - tmp_path.close(); - } - path++; - path_out.push_back(tmp_path); - } - return path_out; -} - -}; //namespace LivePathEffect -}; /* namespace Inkscape */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offset:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- GitLab From 6c4ce394967cc1b8fed613134aa63a976b4b0847 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 10 Nov 2017 02:00:16 +0100 Subject: [PATCH 11/57] Fix compiling problems --- src/live_effects/effect.cpp | 1 + src/live_effects/effect.h | 2 + src/live_effects/effect.h.orig | 209 ++++++++++++++++++++++ src/live_effects/lpe-measure-segments.cpp | 2 +- src/ui/dialog/livepatheffect-editor.cpp | 2 +- 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 src/live_effects/effect.h.orig diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index b198ea7fbf..967f004676 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -861,6 +861,7 @@ Effect::defaultParamSet() expander->set_use_markup(true); expander->add(*vbox_expander); expander->set_expanded(defaultsopen); + expander->set_size_request(-1, 90); expander->property_expanded().signal_changed().connect(sigc::bind<0>(sigc::mem_fun(*this, &Effect::onDefaultsExpanderChanged), expander )); if (has_params) { Gtk::Widget *vboxwidg = dynamic_cast(expander); diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index f59b2a7320..0a69c69ceb 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -182,11 +182,13 @@ protected: std::vector selectedNodesPoints; private: + void onDefaultsExpanderChanged(Gtk::Expander * expander); void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); bool provides_own_flash_paths; // if true, the standard flash path is suppressed bool is_ready; + bool defaultsopen; Effect(const Effect&); Effect& operator=(const Effect&); diff --git a/src/live_effects/effect.h.orig b/src/live_effects/effect.h.orig new file mode 100644 index 0000000000..f59b2a7320 --- /dev/null +++ b/src/live_effects/effect.h.orig @@ -0,0 +1,209 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_H +#define INKSCAPE_LIVEPATHEFFECT_H + +/* + * Copyright (C) Johan Engelen 2007-2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include <2geom/forward.h> +#include "ui/widget/registry.h" +#include +#include "parameter/bool.h" +#include "effect-enum.h" + + +#define LPE_CONVERSION_TOLERANCE 0.01 // FIXME: find good solution for this. + +class SPDocument; +class SPDesktop; +class SPItem; +class LivePathEffectObject; +class SPLPEItem; +class KnotHolder; +class KnotHolderEntity; +class SPPath; +class SPCurve; + +namespace Gtk { + class Widget; +} + +namespace Inkscape { + +namespace XML { + class Node; +} + +namespace LivePathEffect { + +enum LPEPathFlashType { + SUPPRESS_FLASH, +// PERMANENT_FLASH, + DEFAULT +}; + +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + +class Effect { +public: + static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj); + static void createAndApply(const char* name, SPDocument *doc, SPItem *item); + static void createAndApply(EffectType type, SPDocument *doc, SPItem *item); + + virtual ~Effect(); + + EffectType effectType() const; + + //basically, to get this method called before the derived classes, a bit + //of indirection is needed. We first call these methods, then the below. + void doOnApply_impl(SPLPEItem const* lpeitem); + void doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask); + void setCurrentZoom(double cZ); + void setSelectedNodePoints(std::vector sNP); + bool isNodePointSelected(Geom::Point const &nodePoint) const; + virtual void doOnApply (SPLPEItem const* lpeitem); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void doAfterEffect (SPLPEItem const* lpeitem); + virtual void doOnRemove (SPLPEItem const* lpeitem); + virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); + void writeParamsToSVG(); + + virtual void acceptParamPath (SPPath const* param_path); + static int acceptsNumClicks(EffectType type); + int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } + void doAcceptPathPreparations(SPLPEItem *lpeitem); + SPShape * getCurrentShape() const { return current_shape; }; + void setCurrentShape(SPShape * shape) { current_shape = shape; } + void processObjects(LpeAction lpe_action); + + /* + * isReady() indicates whether all preparations which are necessary to apply the LPE are done, + * e.g., waiting for a parameter path either before the effect is created or when it needs a + * path as argument. This is set in SPLPEItem::addPathEffect(). + */ + inline bool isReady() const { return is_ready; } + inline void setReady(bool ready = true) { is_ready = ready; } + + virtual void doEffect (SPCurve * curve); + + virtual Gtk::Widget * newWidget(); + virtual Gtk::Widget * defaultParamSet(); + /** + * Sets all parameters to their default values and writes them to SVG. + */ + virtual void resetDefaults(SPItem const* item); + + /// /todo: is this method really necessary? it causes UI inconsistensies... (johan) + virtual void transform_multiply(Geom::Affine const& postmul, bool set); + + // /TODO: providesKnotholder() is currently used as an indicator of whether a nodepath is + // created for an item or not. When we allow both at the same time, this needs rethinking! + bool providesKnotholder() const; + // /TODO: in view of providesOwnFlashPaths() below, this is somewhat redundant + // (but spiro lpe still needs it!) + virtual LPEPathFlashType pathFlashType() const { return DEFAULT; } + void addHandles(KnotHolder *knotholder, SPItem *item); + std::vector getCanvasIndicators(SPLPEItem const* lpeitem); + void update_helperpath(); + + inline bool providesOwnFlashPaths() const { + return provides_own_flash_paths || show_orig_path; + } + inline bool showOrigPath() const { return show_orig_path; } + + Glib::ustring getName() const; + Inkscape::XML::Node * getRepr(); + SPDocument * getSPDoc(); + LivePathEffectObject * getLPEObj() {return lpeobj;}; + LivePathEffectObject const * getLPEObj() const {return lpeobj;}; + Parameter * getParameter(const char * key); + + void readallParameters(Inkscape::XML::Node const* repr); + void setParameter(const gchar * key, const gchar * new_value); + + inline bool isVisible() const { return is_visible; } + + void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); + bool apply_to_clippath_and_mask; + bool is_clip_or_mask;//Not a group and the effect is applied to clip or mask + bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE + bool is_load; + bool upd_params; + BoolParam is_visible; + Geom::PathVector pathvector_before_effect; + Geom::PathVector pathvector_after_effect; +protected: + Effect(LivePathEffectObject *lpeobject); + + // provide a set of doEffect functions so the developer has a choice + // of what kind of input/output parameters he desires. + // the order in which they appear is the order in which they are + // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling + // doEffect(Geom::PathVector ) + virtual Geom::PathVector + doEffect_path (Geom::PathVector const & path_in); + virtual Geom::Piecewise > + doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + + void registerParameter(Parameter * param); + Parameter * getNextOncanvasEditableParam(); + + virtual void addKnotHolderEntities(KnotHolder * /*knotholder*/, SPItem * /*item*/) {}; + + virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); + + std::vector param_vector; + bool _provides_knotholder_entities; + + int oncanvasedit_it; + + bool show_orig_path; // set this to true in derived effects to automatically have the original + // path displayed as helperpath + + Inkscape::UI::Widget::Registry wr; + + LivePathEffectObject *lpeobj; + + // this boolean defaults to false, it concatenates the input path to one pwd2, + // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. + bool concatenate_before_pwd2; + SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + SPShape * current_shape; // these get stored in performPathEffects. + std::vector items; + double current_zoom; + std::vector selectedNodesPoints; + +private: + void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + bool provides_own_flash_paths; // if true, the standard flash path is suppressed + + bool is_ready; + + Effect(const Effect&); + Effect& operator=(const Effect&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 5c75ed363c..31eff7e669 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -138,7 +138,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_increments(1, 1); helpline_overlap.param_set_digits(2); star_ellipse_fix = Geom::identity(); - message.param_set_min_height(95); + //message.param_set_min_height(95); } LPEMeasureSegments::~LPEMeasureSegments() {} diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 4c642404eb..5929733f73 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -204,7 +204,7 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect) delete effectwidget; effectwidget = NULL; } - effectwidget = effect.newWidget_impl(); + effectwidget = effect.newWidget(); effectcontrol_frame.set_label(effect.getName()); effectcontrol_vbox.pack_start(*effectwidget, true, true); -- GitLab From 4d6c271bc41f5bde914cda58fe36f6c2039e532e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 30 Dec 2017 23:29:32 +0100 Subject: [PATCH 12/57] Fix compiling --- src/live_effects/lpe-show_handles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 2da5705372..79409fe11c 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -93,7 +93,7 @@ Geom::PathVector LPEShowHandles::doEffect_path (Geom::PathVector const & path_in outline_path.clear(); } if (original_d) { - SPCurve * shape_curve = sp_shape->getCurveBeforeLPE(); + SPCurve * shape_curve = current_shape->getCurveBeforeLPE(); if (shape_curve) { Geom::PathVector original_curve = shape_curve->get_pathvector(); if(original_path) { -- GitLab From feac708e5d839102c9929e6571b905124b5f1fdb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 14 Jan 2018 01:38:33 +0100 Subject: [PATCH 13/57] Fix bend compiling bug --- src/live_effects/lpe-bendpath.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 01a81d653b..cbf8d96004 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -90,14 +90,14 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) if (!is_clip_or_mask) { original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); - if (knot_entity && knot_entity->knot) { + if (_knot_entity) { if (hide_knot) { helper_path.clear(); - knot_entity->knot->hide(); + _knot_entity->knot->hide(); } else { - knot_entity->knot->show(); + _knot_entity->knot->show(); } - knot_entity->update_knot(); + _knot_entity->update_knot(); } } } -- GitLab From 562571d9740bc30927595ca0e0bb1b6f29edb77e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 14 Jan 2018 22:18:39 +0100 Subject: [PATCH 14/57] Remove unwanted file and fix some imbue --- src/live_effects/effect.h.orig | 209 ---------------------- src/live_effects/lpe-bendpath.cpp.rej | 21 +++ src/live_effects/lpe-measure-segments.cpp | 14 +- src/live_effects/lpe-measure-segments.h | 1 + src/sp-lpe-item.cpp | 2 + 5 files changed, 31 insertions(+), 216 deletions(-) delete mode 100644 src/live_effects/effect.h.orig create mode 100644 src/live_effects/lpe-bendpath.cpp.rej diff --git a/src/live_effects/effect.h.orig b/src/live_effects/effect.h.orig deleted file mode 100644 index f59b2a7320..0000000000 --- a/src/live_effects/effect.h.orig +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef INKSCAPE_LIVEPATHEFFECT_H -#define INKSCAPE_LIVEPATHEFFECT_H - -/* - * Copyright (C) Johan Engelen 2007-2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include -#include <2geom/forward.h> -#include "ui/widget/registry.h" -#include -#include "parameter/bool.h" -#include "effect-enum.h" - - -#define LPE_CONVERSION_TOLERANCE 0.01 // FIXME: find good solution for this. - -class SPDocument; -class SPDesktop; -class SPItem; -class LivePathEffectObject; -class SPLPEItem; -class KnotHolder; -class KnotHolderEntity; -class SPPath; -class SPCurve; - -namespace Gtk { - class Widget; -} - -namespace Inkscape { - -namespace XML { - class Node; -} - -namespace LivePathEffect { - -enum LPEPathFlashType { - SUPPRESS_FLASH, -// PERMANENT_FLASH, - DEFAULT -}; - -enum LpeAction { - LPE_ERASE = 0, - LPE_TO_OBJECTS, - LPE_VISIBILITY -}; - -class Effect { -public: - static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj); - static void createAndApply(const char* name, SPDocument *doc, SPItem *item); - static void createAndApply(EffectType type, SPDocument *doc, SPItem *item); - - virtual ~Effect(); - - EffectType effectType() const; - - //basically, to get this method called before the derived classes, a bit - //of indirection is needed. We first call these methods, then the below. - void doOnApply_impl(SPLPEItem const* lpeitem); - void doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask); - void setCurrentZoom(double cZ); - void setSelectedNodePoints(std::vector sNP); - bool isNodePointSelected(Geom::Point const &nodePoint) const; - virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - - virtual void doAfterEffect (SPLPEItem const* lpeitem); - virtual void doOnRemove (SPLPEItem const* lpeitem); - virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); - void writeParamsToSVG(); - - virtual void acceptParamPath (SPPath const* param_path); - static int acceptsNumClicks(EffectType type); - int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } - void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape() const { return current_shape; }; - void setCurrentShape(SPShape * shape) { current_shape = shape; } - void processObjects(LpeAction lpe_action); - - /* - * isReady() indicates whether all preparations which are necessary to apply the LPE are done, - * e.g., waiting for a parameter path either before the effect is created or when it needs a - * path as argument. This is set in SPLPEItem::addPathEffect(). - */ - inline bool isReady() const { return is_ready; } - inline void setReady(bool ready = true) { is_ready = ready; } - - virtual void doEffect (SPCurve * curve); - - virtual Gtk::Widget * newWidget(); - virtual Gtk::Widget * defaultParamSet(); - /** - * Sets all parameters to their default values and writes them to SVG. - */ - virtual void resetDefaults(SPItem const* item); - - /// /todo: is this method really necessary? it causes UI inconsistensies... (johan) - virtual void transform_multiply(Geom::Affine const& postmul, bool set); - - // /TODO: providesKnotholder() is currently used as an indicator of whether a nodepath is - // created for an item or not. When we allow both at the same time, this needs rethinking! - bool providesKnotholder() const; - // /TODO: in view of providesOwnFlashPaths() below, this is somewhat redundant - // (but spiro lpe still needs it!) - virtual LPEPathFlashType pathFlashType() const { return DEFAULT; } - void addHandles(KnotHolder *knotholder, SPItem *item); - std::vector getCanvasIndicators(SPLPEItem const* lpeitem); - void update_helperpath(); - - inline bool providesOwnFlashPaths() const { - return provides_own_flash_paths || show_orig_path; - } - inline bool showOrigPath() const { return show_orig_path; } - - Glib::ustring getName() const; - Inkscape::XML::Node * getRepr(); - SPDocument * getSPDoc(); - LivePathEffectObject * getLPEObj() {return lpeobj;}; - LivePathEffectObject const * getLPEObj() const {return lpeobj;}; - Parameter * getParameter(const char * key); - - void readallParameters(Inkscape::XML::Node const* repr); - void setParameter(const gchar * key, const gchar * new_value); - - inline bool isVisible() const { return is_visible; } - - void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); - bool apply_to_clippath_and_mask; - bool is_clip_or_mask;//Not a group and the effect is applied to clip or mask - bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE - bool is_load; - bool upd_params; - BoolParam is_visible; - Geom::PathVector pathvector_before_effect; - Geom::PathVector pathvector_after_effect; -protected: - Effect(LivePathEffectObject *lpeobject); - - // provide a set of doEffect functions so the developer has a choice - // of what kind of input/output parameters he desires. - // the order in which they appear is the order in which they are - // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling - // doEffect(Geom::PathVector ) - virtual Geom::PathVector - doEffect_path (Geom::PathVector const & path_in); - virtual Geom::Piecewise > - doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); - - void registerParameter(Parameter * param); - Parameter * getNextOncanvasEditableParam(); - - virtual void addKnotHolderEntities(KnotHolder * /*knotholder*/, SPItem * /*item*/) {}; - - virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); - - std::vector param_vector; - bool _provides_knotholder_entities; - - int oncanvasedit_it; - - bool show_orig_path; // set this to true in derived effects to automatically have the original - // path displayed as helperpath - - Inkscape::UI::Widget::Registry wr; - - LivePathEffectObject *lpeobj; - - // this boolean defaults to false, it concatenates the input path to one pwd2, - // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. - bool concatenate_before_pwd2; - SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - SPShape * current_shape; // these get stored in performPathEffects. - std::vector items; - double current_zoom; - std::vector selectedNodesPoints; - -private: - void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); - void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); - bool provides_own_flash_paths; // if true, the standard flash path is suppressed - - bool is_ready; - - Effect(const Effect&); - Effect& operator=(const Effect&); -}; - -} //namespace LivePathEffect -} //namespace Inkscape - -#endif - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-bendpath.cpp.rej b/src/live_effects/lpe-bendpath.cpp.rej new file mode 100644 index 0000000000..1be2227ef4 --- /dev/null +++ b/src/live_effects/lpe-bendpath.cpp.rej @@ -0,0 +1,21 @@ +--- src/live_effects/lpe-bendpath.cpp ++++ src/live_effects/lpe-bendpath.cpp +@@ -90,14 +90,14 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) + if (!is_clip_or_mask) { + original_bbox(lpeitem); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); +- if (knot_entity && knot_entity->knot) { ++ if (_knot_entity) { + if (hide_knot) { + helper_path.clear(); +- knot_entity->knot->hide(); ++ _knot_entity->knot->hide(); + } else { +- knot_entity->knot->show(); ++ _knot_entity->knot->show(); + } +- knot_entity->update_knot(); ++ _knot_entity->update_knot(); + } + } + } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 9e2f88a903..18fe4cdf8f 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -138,6 +138,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_increments(1, 1); helpline_overlap.param_set_digits(2); star_ellipse_fix = Geom::identity(); + locale_base = strdup(setlocale(LC_NUMERIC, NULL)); //message.param_set_min_height(95); } @@ -279,9 +280,9 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng fontlister->fill_css(css, Glib::ustring(fontbutton_str)); g_free(fontbutton_str); std::stringstream font_size; - font_size.imbue(std::locale::classic()); + setlocale (LC_NUMERIC, "C"); font_size << fontsize << "pt"; - + setlocale (LC_NUMERIC, locale_base); gchar c[32]; unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); @@ -304,7 +305,6 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::GC::release(rtspan); } length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation()); - gchar const* oldlocale = strdup(setlocale(LC_NUMERIC, NULL)); if (local_locale) { setlocale (LC_NUMERIC, ""); } else { @@ -312,7 +312,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng } gchar length_str[64]; g_snprintf(length_str, 64, "%.*f", (int)precision, length); - setlocale (LC_NUMERIC, oldlocale); + setlocale (LC_NUMERIC, locale_base); gchar * format_str = format.param_getSVGValue(); Glib::ustring label_value(format_str); g_free(format_str); @@ -448,9 +448,10 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i line->setAttribute("inkscape:label", "dinhelpline"); } std::stringstream stroke_w; - stroke_w.imbue(std::locale::classic()); + setlocale (LC_NUMERIC, "C"); double stroke_width = Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); stroke_w << stroke_width; + setlocale (LC_NUMERIC, locale_base); style = style + Glib::ustring("stroke-width:" + stroke_w.str()); gchar c[32]; unsigned const rgb24 = coloropacity.get_value() >> 8; @@ -782,10 +783,9 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); - gchar const* oldlocale = setlocale(LC_NUMERIC, NULL); setlocale (LC_NUMERIC, "C"); double width_line = atof(sp_repr_css_property(css,"stroke-width","-1")); - setlocale (LC_NUMERIC, oldlocale); + setlocale (LC_NUMERIC, locale_base); if (width_line > -0.0001) { arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str()); } diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index 903a5cbd27..19a8d4700d 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -79,6 +79,7 @@ private: double anotation_width; double previous_size; double arrow_gap; + gchar const* locale_base; Geom::Affine star_ellipse_fix; LPEMeasureSegments(const LPEMeasureSegments &); LPEMeasureSegments &operator=(const LPEMeasureSegments &); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9ca2c0bd3c..0f4be41664 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -244,6 +244,8 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip lpe->pathvector_before_effect = curve->get_pathvector(); // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { + //to calculate BBox on shapes and nested LPE + current->setCurve(curve, TRUE); lpe->doBeforeEffect_impl(this, is_clip_or_mask); } -- GitLab From be6ae4413e016a7147adf37f1931486622869345 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 14 Jan 2018 22:19:19 +0100 Subject: [PATCH 15/57] Remove unwanted file and fix some imbue --- src/live_effects/lpe-bendpath.cpp.rej | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/live_effects/lpe-bendpath.cpp.rej diff --git a/src/live_effects/lpe-bendpath.cpp.rej b/src/live_effects/lpe-bendpath.cpp.rej deleted file mode 100644 index 1be2227ef4..0000000000 --- a/src/live_effects/lpe-bendpath.cpp.rej +++ /dev/null @@ -1,21 +0,0 @@ ---- src/live_effects/lpe-bendpath.cpp -+++ src/live_effects/lpe-bendpath.cpp -@@ -90,14 +90,14 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) - if (!is_clip_or_mask) { - original_bbox(lpeitem); - original_height = boundingbox_Y.max() - boundingbox_Y.min(); -- if (knot_entity && knot_entity->knot) { -+ if (_knot_entity) { - if (hide_knot) { - helper_path.clear(); -- knot_entity->knot->hide(); -+ _knot_entity->knot->hide(); - } else { -- knot_entity->knot->show(); -+ _knot_entity->knot->show(); - } -- knot_entity->update_knot(); -+ _knot_entity->update_knot(); - } - } - } -- GitLab From 01d2508620b1a0ca9b5db72bbb349747cf49f499 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 14 Jan 2018 22:34:43 +0100 Subject: [PATCH 16/57] Fix meassure gap --- src/live_effects/lpe-measure-segments.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 18fe4cdf8f..daf42a74ea 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -380,9 +380,9 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i { double k = 0; if (flip_side) { - k = (Geom::distance(start,end)/2.0) + arrow_gap - (anotation_width/2.0); + k = (Geom::distance(start,end)/2.0) + (anotation_width/10.0) - (anotation_width/2.0); } else { - k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0); + k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); } if (Geom::distance(start,end) < anotation_width){ if ((elemref = document->getObjectById(id))) { -- GitLab From 49ffdbe9da8a5aeb02b8240c0616861f00b88fb5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 16 Jan 2018 00:43:32 +0100 Subject: [PATCH 17/57] Adding do before effect per LPE on groups --- src/sp-item-group.cpp | 38 ++++--------- src/sp-lpe-item.cpp | 120 ++++++++++++++++++++++++------------------ src/sp-lpe-item.h | 8 +-- src/sp-path.cpp | 8 +-- 4 files changed, 87 insertions(+), 87 deletions(-) diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 5d4dfc44b4..4b74b78dbe 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -56,7 +56,7 @@ using Inkscape::DocumentUndo; -static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write); +static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write); SPGroup::SPGroup() : SPLPEItem(), _expanded(false), @@ -917,16 +917,7 @@ void SPGroup::update_patheffect(bool write) { if (lpeobj && lpeobj->get_lpe()) { lpeobj->get_lpe()->doBeforeEffect_impl(this, false); - } - } - - sp_group_perform_patheffect(this, this, write); - - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - - if (lpeobj && lpeobj->get_lpe()) { + sp_group_perform_patheffect(this, this,lpeobj->get_lpe(), write); lpeobj->get_lpe()->doAfterEffect(this); } } @@ -934,26 +925,26 @@ void SPGroup::update_patheffect(bool write) { } static void -sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) +sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write) { SPItem* clipmaskto = dynamic_cast(group); if (clipmaskto) { - top_group->applyToClipPath(clipmaskto); - top_group->applyToMask(clipmaskto); + top_group->applyToClipPath(clipmaskto, lpe); + top_group->applyToMask(clipmaskto, lpe); } std::vector const item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { - sp_group_perform_patheffect(sub_group, top_group, write); + sp_group_perform_patheffect(sub_group, top_group, lpe, write); } else { SPShape* sub_shape = dynamic_cast(sub_item); SPPath* sub_path = dynamic_cast(sub_item); clipmaskto = dynamic_cast(sub_item); if (clipmaskto) { - top_group->applyToClipPath(clipmaskto); - top_group->applyToMask(clipmaskto); + top_group->applyToClipPath(clipmaskto, lpe); + top_group->applyToMask(clipmaskto, lpe); } if (sub_shape) { SPCurve * c = NULL; @@ -976,11 +967,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } - if (sub_shape->isFirstLPE(top_group)) { - c = sub_shape->getCurveBeforeLPE(); - } else { - c = sub_shape->getCurve(); - } + c = sub_shape->getCurve(); bool success = false; // only run LPEs when the shape has a curve defined if (c) { @@ -989,11 +976,6 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - if (!sub_path) { - sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); - sub_shape->setCurve(c, TRUE); - sub_shape->setCurveInsync( c, TRUE); - } if (write) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); @@ -1001,6 +983,8 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); + } else { + sub_shape->setCurveInsync( c, TRUE); } c->unref(); } else { diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 0f4be41664..d7ba271c0f 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -217,56 +217,68 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip if (!lpeobj) { /** \todo Investigate the cause of this. * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. - */ + */ g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); return false; } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!lpe) { - /** \todo Investigate the cause of this. - * Not sure, but I think this can happen when an unknown effect type is specified... - */ - g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); - return false; - } - if (lpe->isVisible()) { + performOnePathEffect(curve, current, lpe, is_clip_or_mask); + } + } + return true; +} - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - // if the effect expects mouse input before being applied and the input is not finished - // yet, we don't alter the path - return false; - } - if (is_clip_or_mask && !lpe->apply_to_clippath_and_mask) { - continue; - } +/** + * returns true when LPE was successful. + */ +bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { - lpe->setCurrentShape(current); - lpe->pathvector_before_effect = curve->get_pathvector(); - // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this)) { - //to calculate BBox on shapes and nested LPE - current->setCurve(curve, TRUE); - lpe->doBeforeEffect_impl(this, is_clip_or_mask); - } + if (!curve) { + return false; + } + if (!lpe) { + /** \todo Investigate the cause of this. + * Not sure, but I think this can happen when an unknown effect type is specified... + */ + g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); + return false; + } + if (lpe->isVisible()) { - try { - lpe->doEffect(curve); - } + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { + // if the effect expects mouse input before being applied and the input is not finished + // yet, we don't alter the path + return false; + } + if (is_clip_or_mask && !lpe->apply_to_clippath_and_mask) { + continue; + } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); - } - return false; - } + lpe->setCurrentShape(current); + lpe->pathvector_before_effect = curve->get_pathvector(); + // Groups have their doBeforeEffect called elsewhere + if (!SP_IS_GROUP(this)) { + //to calculate BBox on shapes and nested LPE + current->setCurveInsync(curve, TRUE); + lpe->doBeforeEffect_impl(this, is_clip_or_mask); + } - lpe->pathvector_after_effect = curve->get_pathvector(); - if (!SP_IS_GROUP(this)) { - lpe->doAfterEffect(this); - } - } + try { + lpe->doEffect(curve); + } + + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + return false; + } + + lpe->pathvector_after_effect = curve->get_pathvector(); + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); } } return true; @@ -687,33 +699,33 @@ bool SPLPEItem::isFirstLPE(SPLPEItem const* compare) const } void -SPLPEItem::applyToClipPath(SPItem* to) +SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { SPClipPath *clip_path = to->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data), to); + applyToClipPathOrMask(SP_ITEM(clip_data), to, lpe); } } } void -SPLPEItem::applyToMask(SPItem* to) +SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { SPMask *mask = to->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data), to); + applyToClipPathOrMask(SP_ITEM(mask_data), to, lpe); } } } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { SPGroup* group = dynamic_cast(clip_mask); SPShape* shape = dynamic_cast(clip_mask); @@ -722,22 +734,26 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to) std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; - applyToClipPathOrMask(subitem, to); + applyToClipPathOrMask(subitem, to, lpe); } } else if (shape) { SPCurve* c = NULL; SPPath* path = dynamic_cast(clip_mask); - if (tolpe->isFirstLPE(this)) { - c = shape->getCurveBeforeLPE(true); - } else { +// if (tolpe->isFirstLPE(this)) { +// c = shape->getCurveBeforeLPE(true); +// } else { c = shape->getCurve(); - } + // } if (c) { bool success = false; try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + if (lpe) { + success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + } c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); } else { success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 54394f62e5..81daac8f45 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -71,7 +71,7 @@ public: virtual void update_patheffect(bool write); bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); - + bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask); bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; @@ -93,9 +93,9 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void applyToMask(SPItem* to); - void applyToClipPath(SPItem* to); - void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to); + void applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); + void applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); + void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index c2d5fb8181..d775198cd5 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -334,7 +334,7 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif - if (_curve_before_lpe && hasPathEffect()) { + if (_curve_before_lpe && hasPathEffectRecursive()) { SPCurve *curve = _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)*/ @@ -342,13 +342,13 @@ g_message("sp_path_update_patheffect"); bool success = this->performPathEffect(curve, SP_SHAPE(this)); - if (success && write) { + if (success && write && hasPathEffect()) { // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); #endif - if (_curve) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + if (curve) { + gchar *str = sp_svg_write_path(curve->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { -- GitLab From aac606d939690c5a8395bb87bf91cfe65ca345e6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 17 Jan 2018 01:19:23 +0100 Subject: [PATCH 18/57] Fix compiling broken --- src/sp-item-group.cpp | 17 +++++++------ src/sp-lpe-item.cpp | 57 ++++++++++++++++++++----------------------- src/sp-lpe-item.h | 2 +- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 4b74b78dbe..0c6118c624 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -914,11 +914,13 @@ void SPGroup::update_patheffect(bool write) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - - if (lpeobj && lpeobj->get_lpe()) { - lpeobj->get_lpe()->doBeforeEffect_impl(this, false); - sp_group_perform_patheffect(this, this,lpeobj->get_lpe(), write); - lpeobj->get_lpe()->doAfterEffect(this); + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + lpeobj->get_lpe()->doBeforeEffect_impl(this, false); + sp_group_perform_patheffect(this, this, lpe, write); + lpeobj->get_lpe()->doAfterEffect(this); + } } } } @@ -972,10 +974,11 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa // only run LPEs when the shape has a curve defined if (c) { c->transform(i2anc_affine(sub_item, top_group)); - success = top_group->performPathEffect(c, sub_shape); + success = top_group->performOnePathEffect(c, sub_shape, lpe); c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { + sub_shape->setCurveInsync( c, TRUE); if (write) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); @@ -983,8 +986,6 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); - } else { - sub_shape->setCurveInsync( c, TRUE); } c->unref(); } else { diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index d7ba271c0f..0ff6085765 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -222,7 +222,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip return false; } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - performOnePathEffect(curve, current, lpe, is_clip_or_mask); + if(!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { + return false; + } } } return true; @@ -232,10 +234,6 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip * returns true when LPE was successful. */ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { - - if (!curve) { - return false; - } if (!lpe) { /** \todo Investigate the cause of this. * Not sure, but I think this can happen when an unknown effect type is specified... @@ -244,41 +242,38 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: return false; } if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished // yet, we don't alter the path return false; } - if (is_clip_or_mask && !lpe->apply_to_clippath_and_mask) { - continue; - } - - lpe->setCurrentShape(current); - lpe->pathvector_before_effect = curve->get_pathvector(); - // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this)) { - //to calculate BBox on shapes and nested LPE - current->setCurveInsync(curve, TRUE); - lpe->doBeforeEffect_impl(this, is_clip_or_mask); - } + if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { + lpe->setCurrentShape(current); + lpe->pathvector_before_effect = curve->get_pathvector(); + // Groups have their doBeforeEffect called elsewhere + if (!SP_IS_GROUP(this)) { + //to calculate BBox on shapes and nested LPE + current->setCurveInsync(curve, TRUE); + lpe->doBeforeEffect_impl(this, is_clip_or_mask); + } - try { - lpe->doEffect(curve); - } + try { + lpe->doEffect(curve); + } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + return false; } - return false; - } - lpe->pathvector_after_effect = curve->get_pathvector(); - if (!SP_IS_GROUP(this)) { - lpe->doAfterEffect(this); + lpe->pathvector_after_effect = curve->get_pathvector(); + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); + } } } return true; diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 81daac8f45..e3554b48ef 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -71,7 +71,7 @@ public: virtual void update_patheffect(bool write); bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); - bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask); + bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; -- GitLab From bbd7ce65653c1dceae4f707e99be4316e0cb0a51 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 17 Jan 2018 03:08:57 +0100 Subject: [PATCH 19/57] Working on clippaths --- src/live_effects/effect.cpp | 4 +-- src/live_effects/effect.h | 3 +- src/live_effects/lpe-bendpath.cpp | 22 ++++++------ src/live_effects/lpe-copy_rotate.cpp | 6 ++-- src/live_effects/lpe-envelope.cpp | 4 +-- src/live_effects/lpe-lattice.cpp | 4 +-- src/live_effects/lpe-lattice2.cpp | 4 +-- src/live_effects/lpe-mirror_symmetry.cpp | 4 +-- src/live_effects/lpe-perspective-envelope.cpp | 4 +-- src/live_effects/lpe-transform_2pts.cpp | 4 +-- src/live_effects/lpe-vonkoch.cpp | 4 +-- src/live_effects/lpegroupbbox.cpp | 10 +++--- src/sp-item-group.cpp | 10 +++--- src/sp-lpe-item.cpp | 35 ++++++------------- src/sp-lpe-item.h | 1 - 15 files changed, 49 insertions(+), 70 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3e1ec9c120..6cddc39122 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -372,7 +372,6 @@ Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) Effect::Effect(LivePathEffectObject *lpeobject) : apply_to_clippath_and_mask(false), - is_clip_or_mask(false), _provides_knotholder_entities(false), oncanvasedit_it(0), is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), @@ -545,10 +544,9 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) doOnApply(lpeitem); } -void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask) +void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - is_clip_or_mask = clip_or_mask; doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 0a69c69ceb..19c8c6421d 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -64,7 +64,7 @@ public: //basically, to get this method called before the derived classes, a bit //of indirection is needed. We first call these methods, then the below. void doOnApply_impl(SPLPEItem const* lpeitem); - void doBeforeEffect_impl(SPLPEItem const* lpeitem, bool clip_or_mask); + void doBeforeEffect_impl(SPLPEItem const* lpeitem); void setCurrentZoom(double cZ); void setSelectedNodePoints(std::vector sNP); bool isNodePointSelected(Geom::Point const &nodePoint) const; @@ -133,7 +133,6 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_mask; - bool is_clip_or_mask;//Not a group and the effect is applied to clip or mask bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool is_load; bool upd_params; diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index cbf8d96004..63d854c802 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -87,18 +87,16 @@ void LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - if (!is_clip_or_mask) { - original_bbox(lpeitem); - original_height = boundingbox_Y.max() - boundingbox_Y.min(); - if (_knot_entity) { - if (hide_knot) { - helper_path.clear(); - _knot_entity->knot->hide(); - } else { - _knot_entity->knot->show(); - } - _knot_entity->update_knot(); + original_bbox(lpeitem, false, true); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); + if (_knot_entity) { + if (hide_knot) { + helper_path.clear(); + _knot_entity->knot->hide(); + } else { + _knot_entity->knot->show(); } + _knot_entity->update_knot(); } } @@ -155,7 +153,7 @@ LPEBendPath::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 007e189530..7ab0123dcb 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -348,7 +348,7 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); @@ -375,7 +375,7 @@ void LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); if (copies_to_360 && num_copies > 2) { rotation_angle.param_set_value(360.0/(double)num_copies); } @@ -711,7 +711,7 @@ void LPECopyRotate::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); } void diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index b50efde345..0dcae51e41 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -42,7 +42,7 @@ void LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); } Geom::Piecewise > @@ -218,7 +218,7 @@ LPEEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Geom::Point Up_Left(boundingbox_X.min(), boundingbox_Y.min()); Geom::Point Up_Right(boundingbox_X.max(), boundingbox_Y.min()); diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index 124a7a9c6a..df4da45905 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -164,7 +164,7 @@ LPELattice::doEffect_pwd2 (Geom::Piecewise > const & pwd2 void LPELattice::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); } void @@ -172,7 +172,7 @@ LPELattice::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false); + original_bbox(SP_LPE_ITEM(item), false, true); // place the 16 control points grid_point0[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 50a4ea9e49..8c2c3ec317 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -330,7 +330,7 @@ LPELattice2::horizontal(PointParam ¶m_one, PointParam ¶m_two, Geom::Line void LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); setDefaults(); Geom::Line vert(grid_point_8x9.param_get_default(),grid_point_10x11.param_get_default()); Geom::Line horiz(grid_point_24x26.param_get_default(),grid_point_25x27.param_get_default()); @@ -554,7 +554,7 @@ void LPELattice2::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 7207eb2fa7..884bf1c3db 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -116,7 +116,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); @@ -343,7 +343,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index f6930f81f6..e95cdfd4bb 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -465,7 +465,7 @@ LPEPerspectiveEnvelope::horizontal(PointParam ¶m_one, PointParam ¶m_two, void LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Geom::Line vert(Geom::Point(boundingbox_X.middle(),boundingbox_Y.max()), Geom::Point(boundingbox_X.middle(), boundingbox_Y.min())); Geom::Line horiz(Geom::Point(boundingbox_X.min(),boundingbox_Y.middle()), Geom::Point(boundingbox_X.max(), boundingbox_Y.middle())); if(vertical_mirror) { @@ -506,7 +506,7 @@ void LPEPerspectiveEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 693c9332c2..34abfd3d2d 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -87,7 +87,7 @@ void LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); @@ -118,7 +118,7 @@ void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index f04c243f63..33460aa2d7 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -239,7 +239,7 @@ void LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Geom::PathVector paths = ref_path.get_pathvector(); Geom::Point A,B; @@ -269,7 +269,7 @@ LPEVonKoch::resetDefaults(SPItem const* item) Effect::resetDefaults(item); using namespace Geom; - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Point A,B; A[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index e0451d5dd3..0528c84a89 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -64,12 +64,12 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo } Geom::OptRect bbox; -// if (clipmask) { -// SPLPEItem * item = const_cast(lpeitem); -// bbox = getItemClipMaskBounds(item, transform); -// } else { + if (clipmask) { + SPLPEItem * item = const_cast(lpeitem); + bbox = getItemClipMaskBounds(item, transform); + } else { bbox = lpeitem->geometricBounds(transform); -// } + } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 0c6118c624..398f699bfe 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -929,11 +929,6 @@ void SPGroup::update_patheffect(bool write) { static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write) { - SPItem* clipmaskto = dynamic_cast(group); - if (clipmaskto) { - top_group->applyToClipPath(clipmaskto, lpe); - top_group->applyToMask(clipmaskto, lpe); - } std::vector const item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; @@ -1003,6 +998,11 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } } } + SPItem* clipmaskto = dynamic_cast(group); + if (clipmaskto) { + top_group->applyToClipPath(clipmaskto, lpe); + top_group->applyToMask(clipmaskto, lpe); + } } /* diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 0ff6085765..4140ed7c90 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -247,13 +247,14 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: // yet, we don't alter the path return false; } - if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { + //if is not clip or mask or LPE apply to clip and mask + if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { lpe->setCurrentShape(current); lpe->pathvector_before_effect = curve->get_pathvector(); // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { //to calculate BBox on shapes and nested LPE - current->setCurveInsync(curve, TRUE); + current->setCurveInsync(curve); lpe->doBeforeEffect_impl(this, is_clip_or_mask); } @@ -681,18 +682,6 @@ bool SPLPEItem::hasPathEffectRecursive() const } } -bool SPLPEItem::isFirstLPE(SPLPEItem const* compare) const -{ - if (hasPathEffectRecursive()) { - SPLPEItem const* nearest = this; - while (!nearest->hasPathEffect()) { - nearest = SP_LPE_ITEM(nearest->parent); - } - return nearest == compare; - } - return false; -} - void SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { @@ -734,11 +723,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa } else if (shape) { SPCurve* c = NULL; SPPath* path = dynamic_cast(clip_mask); -// if (tolpe->isFirstLPE(this)) { -// c = shape->getCurveBeforeLPE(true); -// } else { - c = shape->getCurve(); - // } + c = shape->getCurve(); if (c) { bool success = false; try { @@ -751,7 +736,11 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa } c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + if (lpe) { + success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + } } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -763,11 +752,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa } Inkscape::XML::Node *repr = clip_mask->getRepr(); if (success && c) { - if (!path) { - shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); - shape->setCurve(c, TRUE); - shape->setCurveInsync( c, TRUE); - } + shape->setCurveInsync( c, TRUE); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index e3554b48ef..c0bf4da908 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -76,7 +76,6 @@ public: bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; - bool isFirstLPE(SPLPEItem const* compare) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; -- GitLab From e98618a078e2060d5515bbc68b9efc0c6b3a373d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 17 Jan 2018 09:05:45 +0100 Subject: [PATCH 20/57] Fic compiling bugs --- src/sp-item-group.cpp | 4 ++-- src/sp-lpe-item.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 398f699bfe..81cb211fea 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -917,7 +917,7 @@ void SPGroup::update_patheffect(bool write) { if (lpeobj) { Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); if (lpe) { - lpeobj->get_lpe()->doBeforeEffect_impl(this, false); + lpeobj->get_lpe()->doBeforeEffect_impl(this); sp_group_perform_patheffect(this, this, lpe, write); lpeobj->get_lpe()->doAfterEffect(this); } @@ -938,7 +938,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } else { SPShape* sub_shape = dynamic_cast(sub_item); SPPath* sub_path = dynamic_cast(sub_item); - clipmaskto = dynamic_cast(sub_item); + SPItem* clipmaskto = dynamic_cast(sub_item); if (clipmaskto) { top_group->applyToClipPath(clipmaskto, lpe); top_group->applyToMask(clipmaskto, lpe); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 4140ed7c90..9c158c0bb7 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -254,8 +254,8 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { //to calculate BBox on shapes and nested LPE - current->setCurveInsync(curve); - lpe->doBeforeEffect_impl(this, is_clip_or_mask); + current->setCurveInsync(curve, true); + lpe->doBeforeEffect_impl(this); } try { -- GitLab From 898728f3e5a823686102d69e922858aff3453748 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 17 Jan 2018 09:38:44 +0100 Subject: [PATCH 21/57] Fic compiling bugs --- src/sp-ellipse.cpp | 1 - src/sp-lpe-item.cpp | 23 +++++++++++++++++++++-- src/sp-path.cpp | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index a43920a6f1..46bbe0d180 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -485,7 +485,6 @@ void SPGenericEllipse::set_shape(bool force) } this->setCurveInsync(curve, TRUE); this->setCurveBeforeLPE(curve); - if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9c158c0bb7..1b5a68c4eb 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -41,6 +41,7 @@ #include "svg/svg.h" #include "sp-clippath.h" #include "sp-mask.h" +#include "sp-rect.h" #include "ui/tools-switch.h" #include "ui/tools/node-tool.h" @@ -721,8 +722,26 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa applyToClipPathOrMask(subitem, to, lpe); } } else if (shape) { - SPCurve* c = NULL; - SPPath* path = dynamic_cast(clip_mask); + SPCurve * c = NULL; + // If item is a SPRect, convert it to path first: + if ( dynamic_cast(shape) ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty() ) { + sel->clear(); + sel->add(SP_ITEM(shape)); + sel->toCurves(); + SPItem* item = sel->singleItem(); + shape = dynamic_cast(item); + if (!shape) { + return; + } + sel->clear(); + sel->add(this); + } + } + } c = shape->getCurve(); if (c) { bool success = false; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index d775198cd5..cceb823e4d 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -334,7 +334,7 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif - if (_curve_before_lpe && hasPathEffectRecursive()) { + if (_curve_before_lpe) { SPCurve *curve = _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)*/ -- GitLab From e9951b88629d7f746330a8d4063ab330c11560e8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 17 Jan 2018 23:41:38 +0100 Subject: [PATCH 22/57] Alowing clipaths --- src/sp-ellipse.cpp | 1 + src/sp-lpe-item.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/sp-lpe-item.h | 1 + src/sp-path.cpp | 26 +++++++++++++------------- src/sp-path.h | 2 +- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 46bbe0d180..431bb188e2 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -484,6 +484,7 @@ void SPGenericEllipse::set_shape(bool force) } } this->setCurveInsync(curve, TRUE); + this->resetClipPathAndMaskLPE(); this->setCurveBeforeLPE(curve); if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = curve->copy(); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 1b5a68c4eb..100c648085 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -683,6 +683,49 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +void +SPLPEItem::resetClipPathAndMaskLPE() +{ + SPClipPath *clip_path = this->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); + } + } + } + SPMask *mask = this->mask_ref->getObject(); + if(mask) { + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); + } + } + } +} + void SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index c0bf4da908..89491dc967 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -92,6 +92,7 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); + void resetClipPathAndMaskLPE(); void applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); void applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cceb823e4d..58d2663626 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -334,15 +334,16 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif - if (_curve_before_lpe) { - SPCurve *curve = _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)*/ - this->setCurveInsync(curve, TRUE); - + SPCurve *curve = get_curve_for_edit(true); + /* 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)*/ + this->setCurveInsync(curve, TRUE); + this->resetClipPathAndMaskLPE(); + if (hasPathEffect()) { bool success = this->performPathEffect(curve, SP_SHAPE(this)); + this->setCurveInsync(curve, TRUE); - if (success && write && hasPathEffect()) { + if (success && write) { // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); @@ -368,10 +369,9 @@ g_message("sp_path_update_patheffect writes 'd' attribute"); } } } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - curve->unref(); - } + } + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + curve->unref(); // } else if(_curve_before_lpe) { // SPCurve *curve = _curve_before_lpe->copy(); // this->setCurveInsync(curve, TRUE); @@ -437,9 +437,9 @@ SPCurve * SPPath::get_original_curve () const * 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 +SPCurve* SPPath::get_curve_for_edit(bool force) const { - if (_curve_before_lpe && hasPathEffectRecursive()) { + if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { return get_original_curve(); } else { return getCurve(); diff --git a/src/sp-path.h b/src/sp-path.h index 572fd648d1..798ee04514 100644 --- a/src/sp-path.h +++ b/src/sp-path.h @@ -37,7 +37,7 @@ public: // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. void set_original_curve (SPCurve *curve, unsigned int owner, bool write); SPCurve* get_original_curve () const; - SPCurve* get_curve_for_edit () const; + SPCurve* get_curve_for_edit (bool force = false) const; const SPCurve* get_curve_reference() const; public: // should be made protected -- GitLab From 4ca24ec8a1ce38d7727c9daf87dbc3a7366be2cd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Thu, 18 Jan 2018 00:14:50 +0100 Subject: [PATCH 23/57] Alowing clipaths --- src/live_effects/effect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 6cddc39122..c30a6d3b9c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -859,11 +859,11 @@ Effect::defaultParamSet() expander->set_use_markup(true); expander->add(*vbox_expander); expander->set_expanded(defaultsopen); - expander->set_size_request(-1, 90); + //expander->set_size_request(-1, 90); expander->property_expanded().signal_changed().connect(sigc::bind<0>(sigc::mem_fun(*this, &Effect::onDefaultsExpanderChanged), expander )); if (has_params) { Gtk::Widget *vboxwidg = dynamic_cast(expander); - vboxwidg->set_margin_bottom(10); + vboxwidg->set_margin_bottom(5); vboxwidg->set_margin_top(5); return vboxwidg; } else { -- GitLab From abff211d2a8fbab64deb7125d19784680ca09789 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 23 Jan 2018 23:40:10 +0100 Subject: [PATCH 24/57] Working on clips and mask --- src/live_effects/lpe-bendpath.cpp | 2 +- src/live_effects/lpegroupbbox.cpp | 6 +-- src/sp-ellipse.cpp | 75 ++++++++++++++++--------------- src/sp-ellipse.h | 2 +- src/sp-item-group.cpp | 1 + src/sp-lpe-item.cpp | 21 ++++++--- src/sp-path.cpp | 72 +++++++++++++---------------- src/sp-shape.cpp | 33 +++++++------- src/sp-shape.h | 3 +- src/style-internal.h | 2 +- src/ui/tool/path-manipulator.cpp | 24 +++++++++- 11 files changed, 135 insertions(+), 106 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 63d854c802..57955eaf06 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -171,7 +171,7 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - if (sp_lpe_item) { + if (sp_lpe_item) { //Check is object sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } } diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 0528c84a89..a3f27436c2 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -44,10 +44,10 @@ GroupBBoxEffect::getItemClipMaskBounds(SPLPEItem* item, Geom::Affine transform) std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPLPEItem *subitem = dynamic_cast(*iter); - bbox.unionWith(getItemClipMaskBounds(subitem, transform)); + bbox.unionWith(getItemClipMaskBounds(subitem, group->transform * transform)); } } else if (shape) { - bbox.unionWith(item->geometricBounds(transform)); + bbox.unionWith(item->geometricBounds(shape->transform * transform)); } return bbox; } @@ -64,7 +64,7 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo } Geom::OptRect bbox; - if (clipmask) { + if (clipmask && 1>2) { SPLPEItem * item = const_cast(lpeitem); bbox = getItemClipMaskBounds(item, transform); } else { diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 431bb188e2..2f1e0d9c86 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -410,7 +410,7 @@ const char *SPGenericEllipse::displayName() const } // Create path for rendering shape on screen -void SPGenericEllipse::set_shape(bool force) +void SPGenericEllipse::set_shape() { // std::cout << "SPGenericEllipse::set_shape: Entrance" << std::endl; if (hasBrokenPathEffect()) { @@ -474,33 +474,20 @@ void SPGenericEllipse::set_shape(bool force) // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); curve->transform(aff); - - /* Reset the shape's curve to the "original_curve" - * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { + + //If original shape dont change on a LPE item return here to allow LPE + if (this->getCurveBeforeLPE()) { + if(this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { curve->unref(); return; } } - this->setCurveInsync(curve, TRUE); - this->resetClipPathAndMaskLPE(); + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ this->setCurveBeforeLPE(curve); - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = curve->copy(); - bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - - if (success) { - this->setCurveInsync(c_lpe, TRUE); - this->applyToClipPath(this); - this->applyToMask(this); - } - - c_lpe->unref(); - } - + this->setCurveInsync(curve, TRUE); curve->unref(); - // std::cout << "SPGenericEllipse::set_shape: Exit" << std::endl; + return; } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) @@ -637,21 +624,39 @@ void SPGenericEllipse::modified(guint flags) void SPGenericEllipse::update_patheffect(bool write) { - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); + Inkscape::XML::Node *repr = this->getRepr(); + if (SPCurve *c_lpe = this->getCurveForEdit(true)) { + /* 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)*/ + this->setCurveInsync(c_lpe, TRUE); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); + } else { + // LPE was unsuccessful. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + this->setCurve(this->getCurveBeforeLPE(), TRUE); + } + } + } - if (this->_curve != NULL && type == SP_GENERIC_ELLIPSE_ARC) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); + if (write && success) { + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } } + c_lpe->unref(); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void SPGenericEllipse::normalize() @@ -700,7 +705,7 @@ void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry this->rx = rx; this->ry = ry; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Inkscape::Preferences * prefs = Inkscape::Preferences::get(); // those pref values are in degrees, while we want radians if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) { diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index a31b571d85..c179e3ff0f 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -64,7 +64,7 @@ public: virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char *displayName() const; - virtual void set_shape(bool force = false); + virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const &xform); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 81cb211fea..ee6593b1c3 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -910,6 +910,7 @@ void SPGroup::update_patheffect(bool write) { } } + this->resetClipPathAndMaskLPE(); if (hasPathEffect() && pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 100c648085..b7f73bad77 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -180,10 +180,12 @@ void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { } void SPLPEItem::modified(unsigned int flags) { - if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + //TODO: finale remove tghe commented code if no regressions + /* The SP_OBJECT_USER_MODIFIED_FLAG_B is used to mark the fact that it's only a + transformation. It's apparently safe comment this. */ + if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) /*&& (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)*/) { sp_lpe_item_update_patheffect(this, true, true); } - // SPItem::onModified(flags); } @@ -252,10 +254,10 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { lpe->setCurrentShape(current); lpe->pathvector_before_effect = curve->get_pathvector(); + // To Calculate BBox on shapes and nested LPE + current->setCurveInsync(curve, true); // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { - //to calculate BBox on shapes and nested LPE - current->setCurveInsync(curve, true); lpe->doBeforeEffect_impl(this); } @@ -296,6 +298,7 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); #endif g_return_if_fail (lpeitem != NULL); + g_return_if_fail (SP_IS_OBJECT (lpeitem)); g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); if (!lpeitem->pathEffectsEnabled()) @@ -701,7 +704,7 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); } } } @@ -720,7 +723,7 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveBeforeLPE(true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); } } } @@ -729,6 +732,9 @@ SPLPEItem::resetClipPathAndMaskLPE() void SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } SPClipPath *clip_path = to->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); @@ -742,6 +748,9 @@ SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) void SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } SPMask *mask = to->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 58d2663626..0f80f50de6 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -328,50 +328,43 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { void SPPath::update_patheffect(bool write) { - Inkscape::XML::Node *repr = this->getRepr(); - #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect"); #endif + Inkscape::XML::Node *repr = this->getRepr(); + if (SPCurve *c_lpe = this->getCurveForEdit(true)) { + /* 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)*/ + this->setCurveInsync(c_lpe, TRUE); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); + } else { + // LPE was unsuccessful. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + this->setCurve(this->getCurveBeforeLPE(), TRUE); + } + } + } - SPCurve *curve = get_curve_for_edit(true); - /* 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)*/ - this->setCurveInsync(curve, TRUE); - this->resetClipPathAndMaskLPE(); - if (hasPathEffect()) { - bool success = this->performPathEffect(curve, SP_SHAPE(this)); - this->setCurveInsync(curve, TRUE); - - if (success && write) { - // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. -#ifdef PATH_VERBOSE -g_message("sp_path_update_patheffect writes 'd' attribute"); -#endif - if (curve) { - gchar *str = sp_svg_write_path(curve->get_pathvector()); + if (write && success) { + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { repr->setAttribute("d", NULL); } - this->applyToClipPath(this); - this->applyToMask(this); - } else if (!success) { - // LPE was unsuccessful. 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) { - this->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } } + c_lpe->unref(); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - curve->unref(); // } else if(_curve_before_lpe) { // SPCurve *curve = _curve_before_lpe->copy(); // this->setCurveInsync(curve, TRUE); @@ -426,7 +419,7 @@ void SPPath::set_original_curve (SPCurve *new_curve, unsigned int owner, bool wr */ SPCurve * SPPath::get_original_curve () const { - if (_curve_before_lpe) { + if (hasPathEffectRecursive() && _curve_before_lpe) { return _curve_before_lpe->copy(); } @@ -440,10 +433,9 @@ SPCurve * SPPath::get_original_curve () const SPCurve* SPPath::get_curve_for_edit(bool force) const { if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { - return get_original_curve(); - } else { - return getCurve(); + return _curve_before_lpe->copy(); } + return _curve; } /** @@ -454,9 +446,8 @@ const SPCurve* SPPath::get_curve_reference () const { if (_curve_before_lpe && hasPathEffectRecursive()) { return _curve_before_lpe; - } else { - return _curve; } + return _curve; } /** @@ -467,9 +458,8 @@ SPCurve* SPPath::get_curve () { if (_curve_before_lpe && hasPathEffectRecursive()) { return _curve_before_lpe; - } else { - return _curve; } + return _curve; } /* diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 14083dbc3a..25ccb782ab 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -416,7 +416,7 @@ void SPShape::modified(unsigned int flags) { Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const { Geom::OptRect bbox; - if (!this->_curve) { + if (!this->_curve || this->_curve->get_pathvector().empty()) { return bbox; } @@ -1025,25 +1025,26 @@ SPCurve * SPShape::getCurve() const /** * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurveBeforeLPE(bool force) const +SPCurve * SPShape::getCurveBeforeLPE() const { - if (hasPathEffectRecursive()) { - if (_curve_before_lpe) { - return this->_curve_before_lpe->copy(); - } - } else { - //We can force for mask and clippath that dont have real path effect - if (force && _curve_before_lpe) { - return this->_curve_before_lpe->copy(); - } - if (_curve) { - return _curve->copy(); - } - } - + if (hasPathEffectRecursive() && _curve_before_lpe) { + return _curve_before_lpe->copy(); + } return NULL; } +/** + * Return curve for edit + */ +SPCurve * SPShape::getCurveForEdit(bool force) const +{ + if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + return _curve_before_lpe->copy(); + } + return getCurve(); +} + + /** * Same as sp_shape_set_curve but without updating the display */ diff --git a/src/sp-shape.h b/src/sp-shape.h index c35233d173..ffa1e09ff1 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -40,7 +40,8 @@ public: virtual ~SPShape(); SPCurve * getCurve () const; - SPCurve * getCurveBeforeLPE (bool force = false) const; + SPCurve * getCurveBeforeLPE () const; + SPCurve * getCurveForEdit (bool force = false) const; void setCurve (SPCurve *curve, unsigned int owner); void setCurveInsync (SPCurve *curve, unsigned int owner); void setCurveBeforeLPE (SPCurve *curve); diff --git a/src/style-internal.h b/src/style-internal.h index 33e71d5b4c..027cf736e1 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -868,7 +868,7 @@ public: } bool isNone() const { - return (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL) && !colorSet && !isPaintserver(); + return !colorSet && !isPaintserver() && (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL); } // TODO refine bool isColor() const { diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e7c5958937..2abbc4fceb 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1146,6 +1146,9 @@ void PathManipulator::_createControlPointsFromGeometry() ++i; } } + if (pathv.empty()) { + return; + } _spcurve->set_pathvector(pathv); pathv *= (_edit_transform * _i2d_transform); @@ -1352,6 +1355,19 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } builder.flush(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); + for (Geom::PathVector::iterator i = pathv.begin(); i != pathv.end(); ) { + // NOTE: this utilizes the fact that Geom::PathVector is an std::vector. + // When we erase an element, the next one slides into position, + // so we do not increment the iterator even though it is theoretically invalidated. + if (i->empty()) { + i = pathv.erase(i); + } else { + ++i; + } + } + if (pathv.empty()) { + return; + } _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? @@ -1651,8 +1667,14 @@ Geom::Coord PathManipulator::_updateDragPoint(Geom::Point const &evp) Geom::Coord dist = HUGE_VAL; Geom::Affine to_desktop = _edit_transform * _i2d_transform; +// //To avoid crash releasing clips and mask on LPE with node tool and path parameter +// Geom::PathVector pv; +// try { +// pv = _spcurve->get_pathvector(); +// } catch ( const std::bad_alloc& e ) { +// return dist; +// } Geom::PathVector pv = _spcurve->get_pathvector(); - boost::optional pvp = pv.nearestTime(_desktop->w2d(evp) * to_desktop.inverse()); if (!pvp) return dist; -- GitLab From 2b049c1b0aa404d1de0b026cf50aa4d16fe37974 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 27 Jan 2018 11:18:49 +0100 Subject: [PATCH 25/57] Fixing compiling bug --- share/icons/hicolor/icon-theme.cache | Bin 0 -> 17600 bytes src/selection-chemistry.cpp | 19 ++++++++++++++++--- src/ui/tool/path-manipulator.cpp | 7 ------- testfiles/src/object-set-test.cpp | 21 +-------------------- 4 files changed, 17 insertions(+), 30 deletions(-) create mode 100644 share/icons/hicolor/icon-theme.cache diff --git a/share/icons/hicolor/icon-theme.cache b/share/icons/hicolor/icon-theme.cache new file mode 100644 index 0000000000000000000000000000000000000000..20ed4414a7df5ff4f985c063acfe3a67cd3026e1 GIT binary patch literal 17600 zcmZQzWB>sk1_qZU3=9m585o%6FfcHk`Tzg_e+C9-9R>#GI}kRD2?GPm8U_Yd4h9C+ z9SjU?A`A>{KNuL;8yFZk0vH%Lu0Ygr>M$^HLiKa$FfeelFfed$fynWsFfj1!U|`^7 zU|`_YU|`^_VPN1>VPN1ZU|`^z!oa|HhJk@!hk=3r00V=72LppZ0Rw};5e5b!1_lOU z4h9C{1O^7-BOtRtn1Mm~4FiLS2!t&%hk-#cagMmRDte$~E z!hnH6;tvCZqz?mwWC;U{TT)Z`#%f}4lxW2 z4i6X@91|EA9Ct7RTMs%}|oQAuWUVvcT7VsUCtW?m{p8?yP#Aq))677Pr`9_5*N zDf#8P1x2Z4nfax~Af<5g85o#b7#Nrn7#Nr<(o$VA)6z1fr0r?Nq)X=ZfSCcZf0IK!U+hq5VKfB7#LVIj8l^GE8ZSGa~T*|Iv5yOau^s` zYKk-R%XL#S6La#@!3HuQ#U0fCDGUrO3!q_}ms$=s4Jn*h?l3U0>|kJExloW=R9ujn zT#{Lqs#}m)l$eu~ngdpiY32(C29`f*sqTrT#l@M4c}_W{MeqdGKV3VaE#w2G%1C z46Jv+8j|z#KnYm4Bwx2EHN7+^u?VCA-JUND3~U@A_3`ETMJe&c1&PV^VU|_Q;&PyynNrJk``9*oDMbHRD)>FX1z!t*5z?OpWb81d1#KXwyW-u_Y)i5xy z^?=lY+@cGMX{5MgU|>7Kz`(YIfq`vDdQoPIE+{w>^WYxCOgn5B7#P^zB<5tM=jmqT z7iCuE=apb&W+Zp8>o72|voJ8QDNyQ*&}M3yM>9i&N8cQ}ZAx1<4PPxMj~^U|=tSr|Al?GGuq`U|?YH zVPIfilb@88np~n=nwMUbUs|ABkYAu%oSFkk24I&Una#k!{)T~p{RjgC`vY(oBA1QD znJKB|iItdf#394L!2W}QfkOb4vZ1Dfiq-VYyhI%NheLybfx`uR+AK1HYC`f4M-2l5 zM+^f4M*%qPfD(VPZgOf~Nh&x+qWFPh0|Ns`2Ll7g60GHLeo0AwF4*UA^C4l%v4??y z;{>?u$xDTVD5|+2KR#e!;CPdhSeaUcNMLB@aI!Eka4M7(CFT`_Jg8foom!5Rc)(U8 z$3JHP0|Tc80|TcE!f#+jaB~?LI7=89IAa(XI5WU$B)K#xKQjfS2wBY>1_sUs1_sUv z@Ceo|O3W+<7Y=ZB5WjM+U|`@pfE-_mIXSvue?cM`uAYH`^9KV1=M4r1&Nr}H15}b1 zfvO&m3y{JHVm22G0|S==*e@^*x=HyJDA9%Nf36S)1}+N*1}+b9*k>f>r0EuCR)L+3 zqOOC1fh&Q5fvW~7Y?Bjn5S1*%IVgH|FfedUVPN1|1F5^yixN{n)x9pLDu$G1NbYA~ z;JU-Wz;%Ryf$IXK94?N}&p{1ms2^W2FmU|<#|5+u$-!_hH>jN|z`($*0QOgYQ6^G` zKnh>(2nGgj3kC*mpMu1a4BcE%!JbrH0CFM3L&$1-7#O%y7#O%4u#_*!`8oN}?0^UZ zhwE31YJs4{ zKhGTo2A(4f3_KUW_Gacmtwn?r)VvoA3_M@JMkN)cCPD%T?ly=TULFPpUKvDQ%*ii@ zlvZ$c3=F&x3=F&`3=F(Jpf+7`K~7?FDyY==O)Nn82Cg1zZVCefZvi;6b<;9)AcZAd z4Fd!33I+z=4h9C^IpBDNI6yZOT$6(%5?SpP1_s_O3=F&{(o&uCa|`l|GfPqtHlu_M zAE(HK2Z92PB{8`vY>bF+1_pi>1_r(x3=Difz*z!OrzhvSEuFVmxFZV>!uYY=0d%JP!Dy_0tN>DE#R~bE@ukzb1LBl z4YHfwFfj0g`ppke@^?XLaRw+Bk;0yVK|qFqf&T{sgMa{{Tn2|LsObpm`+#)7&4#!` zK!brnzy_RuN-7Idb>J^Gl#cqq|ukgn>aI1?*->DU)854{pT6&17H@n8CmxP{Y6= z&;u@$LEcJ-rb;BYLhW9{z#y;#8YiHR6Qsih=@=lJ`GJ8!-~t1Kz!T(r1W#E=<}xq{ zsxUAJ{9#}alt5~8AT=0sQq#c27s78041zuk41xv>41x|R`N^fAT(6s%TaaG_R*2*d z!4d`r!3YKh!3=0zlw}rYCSle$f*TkZ1REF_1ebur0N&pN#jkEbYEeOIUP@*%tPzh~ zMlvu6-eF)6+{3^icmbUJ5-alaz`e!HWKiTGtA&K2;0p!@!7t!+SDFV(c_3v-ZWc0N zU=ZSAU=UJ)`z^m9H4oI_#?q!`U=WI6U=XrlU=Z?w`Vrb*1sRJRWXk3_=wk zyW@*eK?yBBJGCeeGk*x}VPFuNz`!810n&blB}d(o`~py(Ps~fsz^pGB7=#`$FbJJs zU=X?j4#(nx%pyoL7VbYt7zn*#U=aF~mg=9DR-9UbRA|E0F)#@0Ffa&#z!t&vKEj*BiCeYPiU|w0Q4ieDl>V7aVh(P*)pkM~a2&(-I3?d#33?d2)3?eqz z%TaKR2GRsKn}I>3fPq0Ign>aM1+CqHq7LFWks1aDkqOA^;JFSZuZkRCU=Ufsz#y`v zBtJh#7hI-*j6=i;1B1v51_qHc3=AT7AoWRpQA%o&Zf+Xb^Kkb;?ft^QAj$$RpOSMj z3$XU@MQs=uL}eHlL=C{|@*znkr7|xu7m~%$%oO!tU=U3~D^C&S3D~*F?iB@%Q`Rsr zh)w{fSy&$ul)%BwR}{5Z7#KuXFffRoz@B!HyH&{g#8?;@L?19Pi2i_t3A`1DpPPhr{7Wo`fkDiIfk7+)T;C;v$6w-$Gjj`aGSeWvWu*9n zgt=G-1A|xvIR3!-1J)!!v3~~xgV+QH2C+3r{!A}QEXdG>41}aYf(Av;2L=YQBMb~; zPtfxSxZ8+YY@o%N*dGQ4ac~~cEzJWJNuXFlQzNdxz#wh|4iA+27d+flk%?B$FffQ0 zFffRRFffRxq^0_%7Nz5An~Be0U=XiiU=Z&C6&a9mro=MzJ|ZOS#FsEIi0=TGpT(u1 zAun*V3*=bja-M-f{0#$x_yqpz#|}Hv%$zngSo}L3Nu%3j>2h z4g-Tk1vo5A^Dx?=3=9%07#JibFfd5W0p|&jhtb@{z#wskfk9#m1B1i?P>HFVm7fV2 zMn$9vsM~KaFi3oW)=g=kTn;Mc;He%deKIgesxUA}axgGRN`Ol=U06N=TaFeck_HS6 zk`5rJ#TVs62BE>q(CwFuU|^8UfaE(!S(KKGS{5-dNG@PtkZfRJkemYcZ*pQzP9`|H zLrNG_H=bZ%kX*ySAh`$Jw!txu$iN`^g@Hlx3Il`W3&{9wT7GE}^6)LfoeT_8It&a_ z3=9lX3b@+WNvS!ImK%y&q#_s?q%0U1qffb^Kg>(S}gLDHp52RKk=ad#>$p_Lq7#O5yFfd53LAEv4)oL&>$O?~s#9y)r3=FbJ<6ntsX`sPGMk>U4y6>@>0uD8a0GXDW>hNl(f=YppFpdC~s_sh#L zFvxvjV30@Z`$FRcWttEXClEX2H5eG=J+QZfQ7QstyJ{F14v33RpS<}xrSFfcI4 zKVV>x|AHK+plJ?J@P2Y; z9;E3BG8Q?E6kaeeDBNIRP`HzymIjhUvQtrjfkEL51A`(9O5I!xo?w8hgM^2o3YZcb`3xMhH9<`D)4#W@TNiaQW}iem8CIa;Rz-OU#m7!)6X^9;D3qzfAXf~#X- zP*PxEQ2fEbpdg~1A{UT1B22B1_osYNIS0}GZ{WKiR@Qp3kC*d2?hpb9cX-l zjZOuZ+~Amk+YfP{vI_%)atu;>2X~90!+@X=f~#j>P@cfRpj^VhpxgqPuh31(Oizb( zhLF|mVPH_6!@!`t0osNI7c!~3@aTc7g}UJc1B3Dtq;_0lcB*btW=U>hfiA2VNB9w{ z=MMveiUib;knU4rUWzWF5=L=5M30IA1A~eWLWwT4#LX{DEy_tO00$4cJt`>-3@VWE zAJEVia!U~q}d1d2ErdubsHEMR8K(T ztSG;{SQiv!NCQ1^H$c@tU|>-F02<8K1&#k>DYF?E)HE0v)HoOz)MP;AL41B`Nor9% zjaV0O|&)lM9OS3qUJpFv~jz2DJtT2DJRH5eGwc^DYfWgzuJXU|>*RgDC40!KDqP!;zYTy4(U09#FkU z7#P%VKoSk4pOTbX1}gyJ;laS50rKAm1_liVNV+Xb&BHnGpdrD)prHYcW3X~a)<)RP zz@U-Az@Xv4z@QO>R6v3UMsib2!1L|UNqJ;9OkiNpC}CjGXaT1MP`)VEO)f14k3b-+ zJHo)AF^7RcV+U9rtg#86mxeVbz%D}8^Mipw;{pSN#v5>X0B`y>Xu~YfM=~R(vgk;1A~qV zEW3f`{2^m1;8;d8Q^$sZLB|JNzd=$NG%AqOf=&wqgH8$qgH8o#=3BR@G$&OzwJbGH zHy^!TWnj?R!oZ+2fq_A11vtFme#^})D#BH7>KtHT(76FEr$E&gxIRqFht9wt`Hz7? z7v#4O3=Fy~;QF96FC||$BeS>!vroprplidxpew_`plbjhD@x8uP0TBWLwyVbgPsWkgI)ky zUl_Dr4%|kC4rrmJ6}=1w2E79CEIGK?Mx+r)`qb-SV9t@`UPUIJ_7@Tz6eq|QIubro{s)hPheos*I{7L4?#_v$(cpTIjOqf0SE9}SzT~X7tN0h4Ej9`4Ei|?4Em6`1DmXn{4Z@rH}2LpovWZWNAJ{1(D78jRdDccP$FfbTwVPG&g0*TrQ2upcv%)-E6bc2Dx=m%0e4Jl5Mr_T}gLELC8z`$Uv11>HQ>xMvOTX9AvbVUe; zzl>cN7>pCJjBi$fb1qs~FfbU;U|=w=U|=xrK^m7s%!px{zl4FocuPTMMQToBQHd_1 zXM_~5#%~xHjL$GI7(W2Fm%%k5c7HN3m`E@%82?~kFyR5W5W$h0Us?icCS$nO#D#&u zM1_ID!~#)&=jG>Br52&*B?bnQ90mrH00st=1W1JHW@M(MK#NlJa5kx6U@++cyA_lW zi%}L7A^FQ>2Lpr25(Wm7HK2S1aUO|kIp z&0%0LtwHiLNE^sY$m)(TFqlqZU@+YQ&L{9T5OO_Jl$eqU*=&N`K44%l{ldUtdVzt# z^aV8hAud9lNrBr1N$+M13=C#G;0_*^wZ{w$W;P5AW-1H}W(KInAmV_5!7PJ;!OVk! z!7K(cu9lmamzWNohyZyG)s1FT7#Pe-7#PeTYv4fRr1^P>k_st&85qnCFff=cU|=xY z0uBpU`#G@)V~rC7gV`4b2D38^3}!E|G@@b}wX&n{IwG ztlNt0MvDvv1`8Jk28$SYa}=_E9+nY7!GPutixLI~ixyDh4t1&>VJ_4ia~K#b_JHFa zo(~f9(sMuqo1oEE%sv4FgT)sH28$~U3>GgCW1+~wi?D-%!BT>O!IFW2!4jJOG1vP- z++nH0z+hZt~2*9e~_A)S7A7NmyUcta%y#t;nQ!B8nJGBPw!Mwo0U=8*! z>VB=%lyu0@EZkg3_}DNoFxUu`Wu}(vrj_R86eky@LTYSubs7u|Hi&hv5c_eI2{sK3 z3^oxA3^pZbWie!!Iv(DXg4@BsV6%dO!KR0S!DbGqo(Cms-SW&7=n7-FI;fksFfiC0 z0ISO{1$X>V!_?*n1B1;C1_m3{{x7(93Lc_>o5#RltHHov%fi55D+4XRLFpbmh5%_t zqsN7<4+Dd(2?K+z12n(p=V0vXu`OX>u#I3~u!ZG;(mX_O3T`*VFSZQ~47M}iQy04V zMI{;e>G@dpVKFe+USVLc-N3+Ldje6`LdS^_j)j}gz+n4_fx-3x1B2}ca2`QUtw?zm z;to3w1_nD3@O)%$K9+u$od*Mhoel$ooejj_;Fhg!aV~0~l!3vngn_{>gn_{>BQ4c8 zzo;N1KPNxE5?j9pYHtGrgIy1(DA7&E7MFHM7#Qq8`-gXc%U@{G3*HR`jvD0h#O?zF zgWUxN2D>NFxCAeWNXaaLRTM~JV=uwLVE2cC!JY>?fdy{5K#W9~32~#n3Il_^4W!OS zlu1b2qma$5U|_HhVPLRF&in8>06M#ktbPFlgMAAFgZ&h67@#hqgsX$PV+{j?{QoB|%)L{$rMhl2?Ng9G~b z4=iuPnp()__b@OxWH2x|G+?*~R>~r|pMk+)2Lpq{3!+a8!Y``>?kiAoe=i zFfcfVK>P%cVx;O7#r_@!2FDx*2FC_y{R+vkh$RJZH$csv!NB0S2F+|}@Xf6lSeR~)foTe}^IBh^` zyC8WAo`B(gf`oz72?hqIJK($l-ruF0Sda+Wn1Nb1IEyeaIDKJYaOQx<1EhU|m>qzd z%fR65z`)?Fz`)>af+(Le)AQiPBeEZzGZ+}0eHa*=V?bT+_>BCbDy(bjohL9bIF~Rm zIJbb^T9jIrS_IkfiR?~@pPc6~FgQczzd!+8tP9Qrpkoh^5*ggRP(2qI7@QwK(k{xx zIb0nBgNqCUgYypt1{VR4v5children) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); - if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) - { + if (copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { + copy->setAttribute("d", copy->attribute("inkscape:original-d")); + } else if (copy->attribute("inkscape:original-d")) { copy->setAttribute("d", copy->attribute("inkscape:original-d")); + copy->setAttribute("inkscape:original-d", NULL); + } else if (!copy->attribute("inkscape:path-effect") && !SP_IS_PATH(&child)) { + copy->setAttribute("d", NULL); + copy->setAttribute("inkscape:original-d", NULL); } items_to_move.push_back(copy); } @@ -4194,7 +4199,15 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { // rebuild selection addList(items_to_select); - + NodeTool *nt = NULL; + std::cout << "aaaaaaaaaaaaaaaaaaa" << std::endl; +// SPDesktop * desktop = desktop(); +// if (desktop && tools_isactive(desktop, TOOLS_NODES)) { +// nt = static_cast(desktop->event_context); +// if (nt) { +// nt->selection_changed(this); +// } +// } if (!skip_undo) { if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 2abbc4fceb..9413a911dd 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1667,13 +1667,6 @@ Geom::Coord PathManipulator::_updateDragPoint(Geom::Point const &evp) Geom::Coord dist = HUGE_VAL; Geom::Affine to_desktop = _edit_transform * _i2d_transform; -// //To avoid crash releasing clips and mask on LPE with node tool and path parameter -// Geom::PathVector pv; -// try { -// pv = _spcurve->get_pathvector(); -// } catch ( const std::bad_alloc& e ) { -// return dist; -// } Geom::PathVector pv = _spcurve->get_pathvector(); boost::optional pvp = pv.nearestTime(_desktop->w2d(evp) * to_desktop.inverse()); diff --git a/testfiles/src/object-set-test.cpp b/testfiles/src/object-set-test.cpp index 1879777e56..295e398a29 100644 --- a/testfiles/src/object-set-test.cpp +++ b/testfiles/src/object-set-test.cpp @@ -594,26 +594,7 @@ TEST_F(ObjectSetTest, ZOrder) { EXPECT_TRUE(sp_object_compare_position_bool(r1.get(),r2.get())); } -TEST_F(ObjectSetTest, Combine) { - set->add(r1.get()); - set->add(r2.get()); - set->combine(); - r1.release(); - r2.release(); - EXPECT_EQ(1, set->size()); - EXPECT_EQ(5, _doc->getRoot()->children.size()); - set->breakApart(); - EXPECT_EQ(2, set->size()); - EXPECT_EQ(6, _doc->getRoot()->children.size()); - set->deleteItems(); - set->set(r3.get()); - set->toCurves(); - r3.release(); - auto x = set->singleItem(); - EXPECT_NE(nullptr,dynamic_cast(x)); - EXPECT_EQ(nullptr,dynamic_cast(x)); - set->deleteItems(); -} + TEST_F(ObjectSetTest, Moves) { set->add(r1.get()); -- GitLab From 3dda5d54ad2a3030a23ee6722915ab11af4bff54 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 27 Jan 2018 11:20:54 +0100 Subject: [PATCH 26/57] Fixing compiling bug --- share/icons/hicolor/icon-theme.cache | Bin 17600 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 share/icons/hicolor/icon-theme.cache diff --git a/share/icons/hicolor/icon-theme.cache b/share/icons/hicolor/icon-theme.cache deleted file mode 100644 index 20ed4414a7df5ff4f985c063acfe3a67cd3026e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17600 zcmZQzWB>sk1_qZU3=9m585o%6FfcHk`Tzg_e+C9-9R>#GI}kRD2?GPm8U_Yd4h9C+ z9SjU?A`A>{KNuL;8yFZk0vH%Lu0Ygr>M$^HLiKa$FfeelFfed$fynWsFfj1!U|`^7 zU|`_YU|`^_VPN1>VPN1ZU|`^z!oa|HhJk@!hk=3r00V=72LppZ0Rw};5e5b!1_lOU z4h9C{1O^7-BOtRtn1Mm~4FiLS2!t&%hk-#cagMmRDte$~E z!hnH6;tvCZqz?mwWC;U{TT)Z`#%f}4lxW2 z4i6X@91|EA9Ct7RTMs%}|oQAuWUVvcT7VsUCtW?m{p8?yP#Aq))677Pr`9_5*N zDf#8P1x2Z4nfax~Af<5g85o#b7#Nrn7#Nr<(o$VA)6z1fr0r?Nq)X=ZfSCcZf0IK!U+hq5VKfB7#LVIj8l^GE8ZSGa~T*|Iv5yOau^s` zYKk-R%XL#S6La#@!3HuQ#U0fCDGUrO3!q_}ms$=s4Jn*h?l3U0>|kJExloW=R9ujn zT#{Lqs#}m)l$eu~ngdpiY32(C29`f*sqTrT#l@M4c}_W{MeqdGKV3VaE#w2G%1C z46Jv+8j|z#KnYm4Bwx2EHN7+^u?VCA-JUND3~U@A_3`ETMJe&c1&PV^VU|_Q;&PyynNrJk``9*oDMbHRD)>FX1z!t*5z?OpWb81d1#KXwyW-u_Y)i5xy z^?=lY+@cGMX{5MgU|>7Kz`(YIfq`vDdQoPIE+{w>^WYxCOgn5B7#P^zB<5tM=jmqT z7iCuE=apb&W+Zp8>o72|voJ8QDNyQ*&}M3yM>9i&N8cQ}ZAx1<4PPxMj~^U|=tSr|Al?GGuq`U|?YH zVPIfilb@88np~n=nwMUbUs|ABkYAu%oSFkk24I&Una#k!{)T~p{RjgC`vY(oBA1QD znJKB|iItdf#394L!2W}QfkOb4vZ1Dfiq-VYyhI%NheLybfx`uR+AK1HYC`f4M-2l5 zM+^f4M*%qPfD(VPZgOf~Nh&x+qWFPh0|Ns`2Ll7g60GHLeo0AwF4*UA^C4l%v4??y z;{>?u$xDTVD5|+2KR#e!;CPdhSeaUcNMLB@aI!Eka4M7(CFT`_Jg8foom!5Rc)(U8 z$3JHP0|Tc80|TcE!f#+jaB~?LI7=89IAa(XI5WU$B)K#xKQjfS2wBY>1_sUs1_sUv z@Ceo|O3W+<7Y=ZB5WjM+U|`@pfE-_mIXSvue?cM`uAYH`^9KV1=M4r1&Nr}H15}b1 zfvO&m3y{JHVm22G0|S==*e@^*x=HyJDA9%Nf36S)1}+N*1}+b9*k>f>r0EuCR)L+3 zqOOC1fh&Q5fvW~7Y?Bjn5S1*%IVgH|FfedUVPN1|1F5^yixN{n)x9pLDu$G1NbYA~ z;JU-Wz;%Ryf$IXK94?N}&p{1ms2^W2FmU|<#|5+u$-!_hH>jN|z`($*0QOgYQ6^G` zKnh>(2nGgj3kC*mpMu1a4BcE%!JbrH0CFM3L&$1-7#O%y7#O%4u#_*!`8oN}?0^UZ zhwE31YJs4{ zKhGTo2A(4f3_KUW_Gacmtwn?r)VvoA3_M@JMkN)cCPD%T?ly=TULFPpUKvDQ%*ii@ zlvZ$c3=F&x3=F&`3=F(Jpf+7`K~7?FDyY==O)Nn82Cg1zZVCefZvi;6b<;9)AcZAd z4Fd!33I+z=4h9C^IpBDNI6yZOT$6(%5?SpP1_s_O3=F&{(o&uCa|`l|GfPqtHlu_M zAE(HK2Z92PB{8`vY>bF+1_pi>1_r(x3=Difz*z!OrzhvSEuFVmxFZV>!uYY=0d%JP!Dy_0tN>DE#R~bE@ukzb1LBl z4YHfwFfj0g`ppke@^?XLaRw+Bk;0yVK|qFqf&T{sgMa{{Tn2|LsObpm`+#)7&4#!` zK!brnzy_RuN-7Idb>J^Gl#cqq|ukgn>aI1?*->DU)854{pT6&17H@n8CmxP{Y6= z&;u@$LEcJ-rb;BYLhW9{z#y;#8YiHR6Qsih=@=lJ`GJ8!-~t1Kz!T(r1W#E=<}xq{ zsxUAJ{9#}alt5~8AT=0sQq#c27s78041zuk41xv>41x|R`N^fAT(6s%TaaG_R*2*d z!4d`r!3YKh!3=0zlw}rYCSle$f*TkZ1REF_1ebur0N&pN#jkEbYEeOIUP@*%tPzh~ zMlvu6-eF)6+{3^icmbUJ5-alaz`e!HWKiTGtA&K2;0p!@!7t!+SDFV(c_3v-ZWc0N zU=ZSAU=UJ)`z^m9H4oI_#?q!`U=WI6U=XrlU=Z?w`Vrb*1sRJRWXk3_=wk zyW@*eK?yBBJGCeeGk*x}VPFuNz`!810n&blB}d(o`~py(Ps~fsz^pGB7=#`$FbJJs zU=X?j4#(nx%pyoL7VbYt7zn*#U=aF~mg=9DR-9UbRA|E0F)#@0Ffa&#z!t&vKEj*BiCeYPiU|w0Q4ieDl>V7aVh(P*)pkM~a2&(-I3?d#33?d2)3?eqz z%TaKR2GRsKn}I>3fPq0Ign>aM1+CqHq7LFWks1aDkqOA^;JFSZuZkRCU=Ufsz#y`v zBtJh#7hI-*j6=i;1B1v51_qHc3=AT7AoWRpQA%o&Zf+Xb^Kkb;?ft^QAj$$RpOSMj z3$XU@MQs=uL}eHlL=C{|@*znkr7|xu7m~%$%oO!tU=U3~D^C&S3D~*F?iB@%Q`Rsr zh)w{fSy&$ul)%BwR}{5Z7#KuXFffRoz@B!HyH&{g#8?;@L?19Pi2i_t3A`1DpPPhr{7Wo`fkDiIfk7+)T;C;v$6w-$Gjj`aGSeWvWu*9n zgt=G-1A|xvIR3!-1J)!!v3~~xgV+QH2C+3r{!A}QEXdG>41}aYf(Av;2L=YQBMb~; zPtfxSxZ8+YY@o%N*dGQ4ac~~cEzJWJNuXFlQzNdxz#wh|4iA+27d+flk%?B$FffQ0 zFffRRFffRxq^0_%7Nz5An~Be0U=XiiU=Z&C6&a9mro=MzJ|ZOS#FsEIi0=TGpT(u1 zAun*V3*=bja-M-f{0#$x_yqpz#|}Hv%$zngSo}L3Nu%3j>2h z4g-Tk1vo5A^Dx?=3=9%07#JibFfd5W0p|&jhtb@{z#wskfk9#m1B1i?P>HFVm7fV2 zMn$9vsM~KaFi3oW)=g=kTn;Mc;He%deKIgesxUA}axgGRN`Ol=U06N=TaFeck_HS6 zk`5rJ#TVs62BE>q(CwFuU|^8UfaE(!S(KKGS{5-dNG@PtkZfRJkemYcZ*pQzP9`|H zLrNG_H=bZ%kX*ySAh`$Jw!txu$iN`^g@Hlx3Il`W3&{9wT7GE}^6)LfoeT_8It&a_ z3=9lX3b@+WNvS!ImK%y&q#_s?q%0U1qffb^Kg>(S}gLDHp52RKk=ad#>$p_Lq7#O5yFfd53LAEv4)oL&>$O?~s#9y)r3=FbJ<6ntsX`sPGMk>U4y6>@>0uD8a0GXDW>hNl(f=YppFpdC~s_sh#L zFvxvjV30@Z`$FRcWttEXClEX2H5eG=J+QZfQ7QstyJ{F14v33RpS<}xrSFfcI4 zKVV>x|AHK+plJ?J@P2Y; z9;E3BG8Q?E6kaeeDBNIRP`HzymIjhUvQtrjfkEL51A`(9O5I!xo?w8hgM^2o3YZcb`3xMhH9<`D)4#W@TNiaQW}iem8CIa;Rz-OU#m7!)6X^9;D3qzfAXf~#X- zP*PxEQ2fEbpdg~1A{UT1B22B1_osYNIS0}GZ{WKiR@Qp3kC*d2?hpb9cX-l zjZOuZ+~Amk+YfP{vI_%)atu;>2X~90!+@X=f~#j>P@cfRpj^VhpxgqPuh31(Oizb( zhLF|mVPH_6!@!`t0osNI7c!~3@aTc7g}UJc1B3Dtq;_0lcB*btW=U>hfiA2VNB9w{ z=MMveiUib;knU4rUWzWF5=L=5M30IA1A~eWLWwT4#LX{DEy_tO00$4cJt`>-3@VWE zAJEVia!U~q}d1d2ErdubsHEMR8K(T ztSG;{SQiv!NCQ1^H$c@tU|>-F02<8K1&#k>DYF?E)HE0v)HoOz)MP;AL41B`Nor9% zjaV0O|&)lM9OS3qUJpFv~jz2DJtT2DJRH5eGwc^DYfWgzuJXU|>*RgDC40!KDqP!;zYTy4(U09#FkU z7#P%VKoSk4pOTbX1}gyJ;laS50rKAm1_liVNV+Xb&BHnGpdrD)prHYcW3X~a)<)RP zz@U-Az@Xv4z@QO>R6v3UMsib2!1L|UNqJ;9OkiNpC}CjGXaT1MP`)VEO)f14k3b-+ zJHo)AF^7RcV+U9rtg#86mxeVbz%D}8^Mipw;{pSN#v5>X0B`y>Xu~YfM=~R(vgk;1A~qV zEW3f`{2^m1;8;d8Q^$sZLB|JNzd=$NG%AqOf=&wqgH8$qgH8o#=3BR@G$&OzwJbGH zHy^!TWnj?R!oZ+2fq_A11vtFme#^})D#BH7>KtHT(76FEr$E&gxIRqFht9wt`Hz7? z7v#4O3=Fy~;QF96FC||$BeS>!vroprplidxpew_`plbjhD@x8uP0TBWLwyVbgPsWkgI)ky zUl_Dr4%|kC4rrmJ6}=1w2E79CEIGK?Mx+r)`qb-SV9t@`UPUIJ_7@Tz6eq|QIubro{s)hPheos*I{7L4?#_v$(cpTIjOqf0SE9}SzT~X7tN0h4Ej9`4Ei|?4Em6`1DmXn{4Z@rH}2LpovWZWNAJ{1(D78jRdDccP$FfbTwVPG&g0*TrQ2upcv%)-E6bc2Dx=m%0e4Jl5Mr_T}gLELC8z`$Uv11>HQ>xMvOTX9AvbVUe; zzl>cN7>pCJjBi$fb1qs~FfbU;U|=w=U|=xrK^m7s%!px{zl4FocuPTMMQToBQHd_1 zXM_~5#%~xHjL$GI7(W2Fm%%k5c7HN3m`E@%82?~kFyR5W5W$h0Us?icCS$nO#D#&u zM1_ID!~#)&=jG>Br52&*B?bnQ90mrH00st=1W1JHW@M(MK#NlJa5kx6U@++cyA_lW zi%}L7A^FQ>2Lpr25(Wm7HK2S1aUO|kIp z&0%0LtwHiLNE^sY$m)(TFqlqZU@+YQ&L{9T5OO_Jl$eqU*=&N`K44%l{ldUtdVzt# z^aV8hAud9lNrBr1N$+M13=C#G;0_*^wZ{w$W;P5AW-1H}W(KInAmV_5!7PJ;!OVk! z!7K(cu9lmamzWNohyZyG)s1FT7#Pe-7#PeTYv4fRr1^P>k_st&85qnCFff=cU|=xY z0uBpU`#G@)V~rC7gV`4b2D38^3}!E|G@@b}wX&n{IwG ztlNt0MvDvv1`8Jk28$SYa}=_E9+nY7!GPutixLI~ixyDh4t1&>VJ_4ia~K#b_JHFa zo(~f9(sMuqo1oEE%sv4FgT)sH28$~U3>GgCW1+~wi?D-%!BT>O!IFW2!4jJOG1vP- z++nH0z+hZt~2*9e~_A)S7A7NmyUcta%y#t;nQ!B8nJGBPw!Mwo0U=8*! z>VB=%lyu0@EZkg3_}DNoFxUu`Wu}(vrj_R86eky@LTYSubs7u|Hi&hv5c_eI2{sK3 z3^oxA3^pZbWie!!Iv(DXg4@BsV6%dO!KR0S!DbGqo(Cms-SW&7=n7-FI;fksFfiC0 z0ISO{1$X>V!_?*n1B1;C1_m3{{x7(93Lc_>o5#RltHHov%fi55D+4XRLFpbmh5%_t zqsN7<4+Dd(2?K+z12n(p=V0vXu`OX>u#I3~u!ZG;(mX_O3T`*VFSZQ~47M}iQy04V zMI{;e>G@dpVKFe+USVLc-N3+Ldje6`LdS^_j)j}gz+n4_fx-3x1B2}ca2`QUtw?zm z;to3w1_nD3@O)%$K9+u$od*Mhoel$ooejj_;Fhg!aV~0~l!3vngn_{>gn_{>BQ4c8 zzo;N1KPNxE5?j9pYHtGrgIy1(DA7&E7MFHM7#Qq8`-gXc%U@{G3*HR`jvD0h#O?zF zgWUxN2D>NFxCAeWNXaaLRTM~JV=uwLVE2cC!JY>?fdy{5K#W9~32~#n3Il_^4W!OS zlu1b2qma$5U|_HhVPLRF&in8>06M#ktbPFlgMAAFgZ&h67@#hqgsX$PV+{j?{QoB|%)L{$rMhl2?Ng9G~b z4=iuPnp()__b@OxWH2x|G+?*~R>~r|pMk+)2Lpq{3!+a8!Y``>?kiAoe=i zFfcfVK>P%cVx;O7#r_@!2FDx*2FC_y{R+vkh$RJZH$csv!NB0S2F+|}@Xf6lSeR~)foTe}^IBh^` zyC8WAo`B(gf`oz72?hqIJK($l-ruF0Sda+Wn1Nb1IEyeaIDKJYaOQx<1EhU|m>qzd z%fR65z`)?Fz`)>af+(Le)AQiPBeEZzGZ+}0eHa*=V?bT+_>BCbDy(bjohL9bIF~Rm zIJbb^T9jIrS_IkfiR?~@pPc6~FgQczzd!+8tP9Qrpkoh^5*ggRP(2qI7@QwK(k{xx zIb0nBgNqCUgYypt1{VR4v5 Date: Sat, 27 Jan 2018 23:58:12 +0100 Subject: [PATCH 27/57] Fixing compiling bug --- src/live_effects/lpe-clone-original.cpp | 6 +- src/live_effects/lpe-measure-segments.cpp | 2 +- src/live_effects/lpe-patternalongpath.cpp | 4 +- src/live_effects/lpe-show_handles.cpp | 2 +- src/live_effects/lpe-transform_2pts.cpp | 6 +- src/live_effects/parameter/originalpath.cpp | 2 +- .../parameter/originalpatharray.cpp | 4 +- src/live_effects/parameter/path.cpp | 2 +- src/sp-ellipse.cpp | 6 +- src/sp-lpe-item.cpp.orig | 1087 +++++++++++++++++ src/sp-path.cpp | 2 +- src/sp-spiral.cpp | 4 +- src/sp-star.cpp | 4 +- src/splivarot.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 2 +- src/ui/tools/node-tool.cpp | 2 +- src/widgets/pencil-toolbar.cpp | 4 +- testfiles/src/object-set-test.cpp | 21 +- 18 files changed, 1134 insertions(+), 28 deletions(-) create mode 100644 src/sp-lpe-item.cpp.orig diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index d06069ea9e..42558abdea 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -120,7 +120,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * if ( shape_dest && shape_origin && (std::strcmp(attribute, "d") == 0)) { SPCurve *c = NULL; if (method == CLM_BSPLINESPIRO) { - c = shape_origin->getCurveBeforeLPE(); + c = shape_origin->getCurveForEdit(); SPLPEItem * lpe_item = SP_LPE_ITEM(origin); if (lpe_item) { PathEffectList lpelist = lpe_item->getEffectList(); @@ -138,7 +138,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * } } } else if(method == CLM_ORIGINALD) { - c = shape_origin->getCurveBeforeLPE(); + c = shape_origin->getCurveForEdit(); } else { c = shape_origin->getCurve(); } @@ -336,7 +336,7 @@ LPECloneOriginal::doEffect (SPCurve * curve) // if (linkeditem.linksToItem()) { // SPShape * shape = getCurrentShape(); // if(shape){ -// curve->set_pathvector(shape->getCurveBeforeLPE()->get_pathvector()); +// curve->set_pathvector(shape->getCurveForEdit()->get_pathvector()); // } // } } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index daf42a74ea..677ca223c6 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -594,7 +594,7 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) SPPath *path = dynamic_cast(shape); if (path) { - c = path->get_original_curve(); + c = path->get_curve_for_edit(); } else { c = shape->getCurve(); } diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index efd1aec2d8..6e5763b935 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -313,7 +313,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Poin Geom::Point const s = snap_knot_position(p, state); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); + SPCurve *curve_before = sp_shape->getCurveForEdit(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); @@ -346,7 +346,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const LPEPatternAlongPath *lpe = dynamic_cast (_effect); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); + SPCurve *curve_before = sp_shape->getCurveForEdit(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 79409fe11c..f3615118aa 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -93,7 +93,7 @@ Geom::PathVector LPEShowHandles::doEffect_path (Geom::PathVector const & path_in outline_path.clear(); } if (original_d) { - SPCurve * shape_curve = current_shape->getCurveBeforeLPE(); + SPCurve * shape_curve = current_shape->getCurveForEdit(); if (shape_curve) { Geom::PathVector original_curve = shape_curve->get_pathvector(); if(original_path) { diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 34abfd3d2d..d84c9a2f3c 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -93,7 +93,7 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->get_curve_for_edit()->get_pathvector(); } if(!pathvector.empty()) { point_a = pathvector.initialPoint(); @@ -125,7 +125,7 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->get_curve_for_edit()->get_pathvector(); } if(from_original_width_toggler != from_original_width) { from_original_width_toggler = from_original_width; @@ -181,7 +181,7 @@ LPETransform2Pts::updateIndex() SPLPEItem * splpeitem = const_cast(sp_lpe_item); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->get_curve_for_edit()->get_pathvector(); } if(pathvector.empty()) { return; diff --git a/src/live_effects/parameter/originalpath.cpp b/src/live_effects/parameter/originalpath.cpp index 3f833d2ac1..2236b93d89 100644 --- a/src/live_effects/parameter/originalpath.cpp +++ b/src/live_effects/parameter/originalpath.cpp @@ -92,7 +92,7 @@ OriginalPathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags* SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 22630d9332..2df3451a7c 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -426,9 +426,9 @@ void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/ if (SP_IS_SHAPE(linked_obj)) { SPLPEItem * lpe_item = SP_LPE_ITEM(linked_obj); if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else if (_allow_only_bspline_spiro && lpe_item && lpe_item->hasPathEffect()){ - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); PathEffectList lpelist = lpe_item->getEffectList(); PathEffectList::iterator i; for (i = lpelist.begin(); i != lpelist.end(); ++i) { diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 88ba85b48a..c14d3d1838 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -458,7 +458,7 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 2f1e0d9c86..f06f1659df 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -476,8 +476,8 @@ void SPGenericEllipse::set_shape() curve->transform(aff); //If original shape dont change on a LPE item return here to allow LPE - if (this->getCurveBeforeLPE()) { - if(this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { + if (this->getCurveForEdit()) { + if(this->getCurveForEdit()->get_pathvector() == curve->get_pathvector()) { curve->unref(); return; } @@ -640,7 +640,7 @@ void SPGenericEllipse::update_patheffect(bool write) } else { // LPE was unsuccessful. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { - this->setCurve(this->getCurveBeforeLPE(), TRUE); + this->setCurve(this->getCurveForEdit(), TRUE); } } } diff --git a/src/sp-lpe-item.cpp.orig b/src/sp-lpe-item.cpp.orig new file mode 100644 index 0000000000..061969a69b --- /dev/null +++ b/src/sp-lpe-item.cpp.orig @@ -0,0 +1,1087 @@ +/** \file + * Base class for live path effect items + */ +/* + * Authors: + * Johan Engelen + * Bastien Bouclet + * Abhishek Sharma + * + * Copyright (C) 2008 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#endif + +#include + +#include "bad-uri-exception.h" +#include "ui/tool/multi-path-manipulator.h" + +#include "live_effects/effect.h" +#include "live_effects/lpe-path_length.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/lpe-mirror_symmetry.h" +#include "live_effects/lpe-copy_rotate.h" + +#include "sp-path.h" +#include "sp-item-group.h" +#include "attributes.h" +#include "uri.h" +#include "message-stack.h" +#include "inkscape.h" +#include "desktop.h" +#include "ui/shape-editor.h" +#include "path-chemistry.h" +#include "sp-ellipse.h" +#include "display/curve.h" +#include "svg/svg.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-rect.h" +#include "ui/tools-switch.h" +#include "ui/tools/node-tool.h" + +/* LPEItem base class */ +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); + +static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); + +static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); +static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); + +typedef std::list HRefList; +static std::string patheffectlist_svg_string(PathEffectList const & list); +static std::string hreflist_svg_string(HRefList const & list); + +SPLPEItem::SPLPEItem() + : SPItem() + , path_effects_enabled(1) + , path_effect_list(new PathEffectList()) + , lpe_modified_connection_list(new std::list()) + , current_path_effect(NULL) + , lpe_helperpaths() +{ +} + +SPLPEItem::~SPLPEItem() { +} + +void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { + this->readAttr( "inkscape:path-effect" ); + + SPItem::build(document, repr); +} + +void SPLPEItem::release() { + // disconnect all modified listeners: + + for (std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); + mod_it != this->lpe_modified_connection_list->end(); ++mod_it) + { + mod_it->disconnect(); + } + + delete this->lpe_modified_connection_list; + this->lpe_modified_connection_list = NULL; + + PathEffectList::iterator it = this->path_effect_list->begin(); + + while ( it != this->path_effect_list->end() ) { + // unlink and delete all references in the list + (*it)->unlink(); + delete *it; + it = this->path_effect_list->erase(it); + } + + // delete the list itself + delete this->path_effect_list; + this->path_effect_list = NULL; + + SPItem::release(); +} + +void SPLPEItem::set(unsigned int key, gchar const* value) { + switch (key) { + case SP_ATTR_INKSCAPE_PATH_EFFECT: + { + this->current_path_effect = NULL; + + // Disable the path effects while populating the LPE list + sp_lpe_item_enable_path_effects(this, false); + + // disconnect all modified listeners: + for ( std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); + mod_it != this->lpe_modified_connection_list->end(); + ++mod_it) + { + mod_it->disconnect(); + } + + this->lpe_modified_connection_list->clear(); + // Clear the path effect list + PathEffectList::iterator it = this->path_effect_list->begin(); + while ( it != this->path_effect_list->end()) { + (*it)->unlink(); + delete *it; + it = this->path_effect_list->erase(it); + } + + // Parse the contents of "value" to rebuild the path effect reference list + if ( value ) { + std::istringstream iss(value); + std::string href; + + while (std::getline(iss, href, ';')) + { + Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(this); + + try { + path_effect_ref->link(href.c_str()); + } catch (Inkscape::BadURIException &e) { + g_warning("BadURIException when trying to find LPE: %s", e.what()); + path_effect_ref->unlink(); + delete path_effect_ref; + path_effect_ref = NULL; + } + + this->path_effect_list->push_back(path_effect_ref); + + if ( path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe() ) { + // connect modified-listener + this->lpe_modified_connection_list->push_back( + path_effect_ref->lpeobject->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), this)) ); + } else { + // something has gone wrong in finding the right patheffect. + g_warning("Unknown LPE type specified, LPE stack effectively disabled"); + // keep the effect in the lpestack, so the whole stack is effectively disabled but maintained + } + } + } + + sp_lpe_item_enable_path_effects(this, true); + } + break; + + default: + SPItem::set(key, value); + break; + } +} + +void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { + SPItem::update(ctx, flags); + + // update the helperpaths of all LPEs applied to the item + // TODO: re-add for the new node tool +} + +void SPLPEItem::modified(unsigned int flags) { + if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + sp_lpe_item_update_patheffect(this, true, true); + } + +// SPItem::onModified(flags); +} + +Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + if (flags & SP_OBJECT_WRITE_EXT) { + if ( hasPathEffect() ) { + repr->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); + } else { + repr->setAttribute("inkscape:path-effect", NULL); + } + } + + SPItem::write(xml_doc, repr, flags); + + return repr; +} + + +/** + * returns true when LPE was successful. + */ +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { + + if (!curve) { + return false; + } + + if (this->hasPathEffect() && this->pathEffectsEnabled()) { + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj) { + /** \todo Investigate the cause of this. + * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. + */ + g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); + return false; + } + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if(!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { + return false; + } + } + } + return true; +} + +/** + * returns true when LPE was successful. + */ +bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { + if (!lpe) { + /** \todo Investigate the cause of this. + * Not sure, but I think this can happen when an unknown effect type is specified... + */ + g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); + return false; + } + if (lpe->isVisible()) { + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { + // if the effect expects mouse input before being applied and the input is not finished + // yet, we don't alter the path + return false; + } + //if is not clip or mask or LPE apply to clip and mask + if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { + lpe->setCurrentShape(current); + lpe->pathvector_before_effect = curve->get_pathvector(); + // To Calculate BBox on shapes and nested LPE + current->setCurveInsync(curve, true); + // Groups have their doBeforeEffect called elsewhere + if (!SP_IS_GROUP(this)) { + lpe->doBeforeEffect_impl(this); + } + + try { + lpe->doEffect(curve); + } + + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + return false; + } + + lpe->pathvector_after_effect = curve->get_pathvector(); + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); + } + } + } + return true; +} + +// CPPIFY: make pure virtual +void SPLPEItem::update_patheffect(bool /*write*/) { + //throw; +} + +/** + * Calls any registered handlers for the update_patheffect action + */ +void +sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) +{ +#ifdef SHAPE_VERBOSE + g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); +#endif + g_return_if_fail (lpeitem != NULL); + g_return_if_fail (SP_IS_OBJECT (lpeitem)); + g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); + + if (!lpeitem->pathEffectsEnabled()) + return; + + SPLPEItem *top = NULL; + + if (wholetree) { + SPLPEItem *prev_parent = lpeitem; + SPLPEItem *parent = dynamic_cast(prev_parent->parent); + while (parent && parent->hasPathEffectRecursive()) { + prev_parent = parent; + parent = dynamic_cast(prev_parent->parent); + } + top = prev_parent; + } + else { + top = lpeitem; + } + + top->update_patheffect(write); +} + +/** + * Gets called when any of the lpestack's lpeobject repr contents change: i.e. parameter change in any of the stacked LPEs + */ +static void +lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) +{ +#ifdef SHAPE_VERBOSE + g_message("lpeobject_ref_modified"); +#endif + sp_lpe_item_update_patheffect (lpeitem, true, true); +} + +static void +sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) +{ + g_return_if_fail(lpeitem != NULL); + + SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPLPEItem * clip_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(clip_data); + } + } + + SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPLPEItem * mask_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(mask_data); + } + } + if (SP_IS_GROUP(lpeitem)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *subitem = *iter; + if (SP_IS_LPE_ITEM(subitem)) { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); + } + } + } + else if (SP_IS_PATH(lpeitem)) { + Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); + if ( !pathrepr->attribute("inkscape:original-d") ) { + pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); + } + } +} + +static void +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) +{ + g_return_if_fail(lpeitem != NULL); + SPItem *item = dynamic_cast(lpeitem); + if (!item) { + return; + } + SPGroup *group = dynamic_cast(lpeitem); + SPShape *shape = dynamic_cast(lpeitem); + SPPath *path = dynamic_cast(lpeitem); + SPClipPath *clip_path = item->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPLPEItem* clip_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, shape && !shape->hasPathEffectRecursive()); + } + } + + SPMask *mask_path = item->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPLPEItem* mask_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, shape && !shape->hasPathEffectRecursive()); + } + } + + if (group) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPLPEItem* subitem = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths, false); + } + } else if (path) { + Inkscape::XML::Node *repr = lpeitem->getRepr(); + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) + { + if (!keep_paths) { + repr->setAttribute("d", repr->attribute("inkscape:original-d")); + } + repr->setAttribute("inkscape:original-d", NULL); + } else { + if (!keep_paths) { + sp_lpe_item_update_patheffect(lpeitem, true, true); + } + } + } else if (shape) { + Inkscape::XML::Node *repr = lpeitem->getRepr(); + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) + { + if (!keep_paths) { + repr->setAttribute("d", NULL); + } else { + SPDesktop * desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + std::vector items; + items.push_back(SP_ITEM(lpeitem)); + std::vector selected = items; + std::vector to_select; + sp_item_list_to_curves(items, selected, to_select, true); + } + } + } else { + if (!keep_paths) { + sp_lpe_item_update_patheffect(lpeitem, true, true); + } + } + + } +} + +void SPLPEItem::addPathEffect(std::string value, bool reset) +{ + if (!value.empty()) { + // Apply the path effects here because in the casse of a group, lpe->resetDefaults + // needs that all the subitems have their effects applied + sp_lpe_item_update_patheffect(this, false, true); + + // Disable the path effects while preparing the new lpe + sp_lpe_item_enable_path_effects(this, false); + + // Add the new reference to the list of LPE references + HRefList hreflist; + for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + hreflist.push_back( std::string((*it)->lpeobject_href) ); + } + hreflist.push_back(value); // C++11: should be emplace_back std::move'd (also the reason why passed by value to addPathEffect) + + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); + + // Make sure that ellipse is stored as + if( SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); + } + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(this); + + LivePathEffectObject *lpeobj = this->path_effect_list->back()->lpeobject; + if (lpeobj && lpeobj->get_lpe()) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + // Ask the path effect to reset itself if it doesn't have parameters yet + if (reset) { + // has to be called when all the subitems have their lpes applied + lpe->resetDefaults(this); + } + + // perform this once when the effect is applied + lpe->doOnApply(this); + + // indicate that all necessary preparations are done and the effect can be performed + lpe->setReady(); + } + + //Enable the path effects now that everything is ready to apply the new path effect + sp_lpe_item_enable_path_effects(this, true); + + // Apply the path effect + sp_lpe_item_update_patheffect(this, true, true); + //fix bug 1219324 + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_SELECT); //mhh + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_NODES); + } + } + } +} + +void SPLPEItem::addPathEffect(LivePathEffectObject * new_lpeobj) +{ + const gchar * repr_id = new_lpeobj->getRepr()->attribute("id"); + gchar *hrefstr = g_strdup_printf("#%s", repr_id); + this->addPathEffect(hrefstr, false); + g_free(hrefstr); +} + +/** + * If keep_path is true, the item should not be updated, effectively 'flattening' the LPE. + */ +void SPLPEItem::removeCurrentPathEffect(bool keep_paths) +{ + Inkscape::LivePathEffect::LPEObjectReference* lperef = this->getCurrentLPEReference(); + if (!lperef) + return; + + if (Inkscape::LivePathEffect::Effect* effect_ = this->getCurrentLPE()) { + effect_->keep_paths = keep_paths; + effect_->doOnRemove(this); + } + PathEffectList new_list = *this->path_effect_list; + new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); + if (!keep_paths) { + // Make sure that ellipse is stored as or if possible. + if( SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); + } + } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); +} + +/** + * If keep_path is true, the item should not be updated, effectively 'flattening' the LPE. + */ +void SPLPEItem::removeAllPathEffects(bool keep_paths) +{ + if (keep_paths) { + if (path_effect_list->empty()) { + return; + } + } + + PathEffectList::iterator it = this->path_effect_list->begin(); + + while ( it != this->path_effect_list->end() ) { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); + if (lpe) { + lpe->keep_paths = keep_paths; + lpe->doOnRemove(this); + } + } + // unlink and delete all references in the list + (*it)->unlink(); + ++it; + } + this->path_effect_list->clear(); + this->getRepr()->setAttribute("inkscape:path-effect", NULL); + + if (!keep_paths) { + // Make sure that ellipse is stored as or if possible. + if (SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write(this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT); + } + } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); +} + +void SPLPEItem::downCurrentPathEffect() +{ + Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); + if (!lperef) + return; + + PathEffectList new_list = *this->path_effect_list; + PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); + if (cur_it != new_list.end()) { + PathEffectList::iterator down_it = cur_it; + ++down_it; + if (down_it != new_list.end()) { // perhaps current effect is already last effect + std::iter_swap(cur_it, down_it); + } + } + + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); + + sp_lpe_item_cleanup_original_path_recursive(this, false); +} + +void SPLPEItem::upCurrentPathEffect() +{ + Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); + if (!lperef) + return; + + PathEffectList new_list = *this->path_effect_list; + PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); + if (cur_it != new_list.end() && cur_it != new_list.begin()) { + PathEffectList::iterator up_it = cur_it; + --up_it; + std::iter_swap(cur_it, up_it); + } + + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); + + sp_lpe_item_cleanup_original_path_recursive(this, false); +} + +/** used for shapes so they can see if they should also disable shape calculation and read from d= */ +bool SPLPEItem::hasBrokenPathEffect() const +{ + if (path_effect_list->empty()) { + return false; + } + + // go through the list; if some are unknown or invalid, return true + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj || !lpeobj->get_lpe()) { + return true; + } + } + + return false; +} + +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const +{ + if (path_effect_list->empty()) { + return false; + } + + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject const *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + if (is_ready || lpe->isReady()) { + return true; + } + } + } + } + + return false; +} + +bool SPLPEItem::hasPathEffect() const +{ + if (!path_effect_list || path_effect_list->empty()) { + return false; + } + + // go through the list; if some are unknown or invalid, we are not an LPE item! + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj || !lpeobj->get_lpe()) { + return false; + } + } + + return true; +} + +bool SPLPEItem::hasPathEffectRecursive() const +{ + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (parent_lpe_item) { + return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); + } + else { + return hasPathEffect(); + } +} + +void +SPLPEItem::resetClipPathAndMaskLPE() +{ + SPClipPath *clip_path = this->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); + } + } + } + SPMask *mask = this->mask_ref->getObject(); + if(mask) { + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); + } + } + } +} + +void +SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +{ + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } + SPClipPath *clip_path = to->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPObject * clip_data = *iter; + applyToClipPathOrMask(SP_ITEM(clip_data), to, lpe); + } + } +} + +void +SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +{ + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } + SPMask *mask = to->mask_ref->getObject(); + if(mask) { + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPObject * mask_data = *iter; + applyToClipPathOrMask(SP_ITEM(mask_data), to, lpe); + } + } +} + +void +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +{ + SPGroup* group = dynamic_cast(clip_mask); + SPShape* shape = dynamic_cast(clip_mask); + SPLPEItem* tolpe = dynamic_cast(to); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPItem *subitem = *iter; + applyToClipPathOrMask(subitem, to, lpe); + } + } else if (shape) { + SPCurve * c = NULL; + // If item is a SPRect, convert it to path first: + if ( dynamic_cast(shape) ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty() ) { + sel->clear(); + sel->add(SP_ITEM(shape)); + sel->toCurves(); + SPItem* item = sel->singleItem(); + shape = dynamic_cast(item); + if (!shape) { + return; + } + sel->clear(); + sel->add(this); + } + } + } + c = shape->getCurve(); + if (c) { + bool success = false; + try { + if(SP_IS_GROUP(this)){ + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); + if (lpe) { + success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + } + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); + } else { + if (lpe) { + success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + } + } + } catch (std::exception & e) { + g_warning("Exception during LPE execution. \n %s", e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + success = false; + } + Inkscape::XML::Node *repr = clip_mask->getRepr(); + if (success && c) { + shape->setCurveInsync( c, TRUE); + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccessful or doeffect stack return null.. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); + if (oldcurve) { + SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + if (c) { + c->unref(); + } + } + } +} + +Inkscape::LivePathEffect::Effect* +SPLPEItem::getPathEffectOfType(int type) +{ + std::list::iterator i; + for (i = path_effect_list->begin(); i != path_effect_list->end(); ++i) { + LivePathEffectObject *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect* lpe = lpeobj->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + return lpe; + } + } + } + return NULL; +} + +Inkscape::LivePathEffect::Effect const* +SPLPEItem::getPathEffectOfType(int type) const +{ + std::list::const_iterator i; + for (i = path_effect_list->begin(); i != path_effect_list->end(); ++i) { + LivePathEffectObject const *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect const *lpe = lpeobj->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + return lpe; + } + } + } + return NULL; +} + +void SPLPEItem::editNextParamOncanvas(SPDesktop *dt) +{ + Inkscape::LivePathEffect::LPEObjectReference *lperef = this->getCurrentLPEReference(); + if (lperef && lperef->lpeobject && lperef->lpeobject->get_lpe()) { + lperef->lpeobject->get_lpe()->editNextParamOncanvas(this, dt); + } +} + +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)); + } + } +} +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), false); + } + } + + SPItem::remove_child(child); +} + +static std::string patheffectlist_svg_string(PathEffectList const & list) +{ + HRefList hreflist; + + for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) + { + hreflist.push_back( std::string((*it)->lpeobject_href) ); // C++11: use emplace_back + } + + return hreflist_svg_string(hreflist); +} + +/** + * THE function that should be used to generate any patheffectlist string. + * one of the methods to change the effect list: + * - create temporary href list + * - populate the templist with the effects from the old list that you want to have and their order + * - call this function with temp list as param + */ +static std::string hreflist_svg_string(HRefList const & list) +{ + std::string r; + bool semicolon_first = false; + + for (HRefList::const_iterator it = list.begin(); it != list.end(); ++it) + { + if (semicolon_first) { + r += ';'; + } + + semicolon_first = true; + + r += (*it); + } + + return r; +} + +// Return a copy of the effect list +PathEffectList SPLPEItem::getEffectList() +{ + return *path_effect_list; +} + +// Return a copy of the effect list +PathEffectList const SPLPEItem::getEffectList() const +{ + return *path_effect_list; +} + +Inkscape::LivePathEffect::LPEObjectReference* SPLPEItem::getCurrentLPEReference() +{ + if (!this->current_path_effect && !this->path_effect_list->empty()) { + setCurrentPathEffect(this->path_effect_list->back()); + } + + return this->current_path_effect; +} + +Inkscape::LivePathEffect::Effect* SPLPEItem::getCurrentLPE() +{ + Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); + + if (lperef && lperef->lpeobject) + return lperef->lpeobject->get_lpe(); + else + return NULL; +} + +bool SPLPEItem::setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef) +{ + for (PathEffectList::iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) { + if ((*it)->lpeobject_repr == lperef->lpeobject_repr) { + this->current_path_effect = (*it); // current_path_effect should always be a pointer from the path_effect_list ! + return true; + } + } + + return false; +} + +/** + * Writes a new "inkscape:path-effect" string to xml, where the old_lpeobjects are substituted by the new ones. + * Note that this method messes up the item's \c PathEffectList. + */ +void SPLPEItem::replacePathEffects( std::vector const &old_lpeobjs, + std::vector const &new_lpeobjs ) +{ + HRefList hreflist; + for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject const * current_lpeobj = (*it)->lpeobject; + std::vector::const_iterator found_it(std::find(old_lpeobjs.begin(), old_lpeobjs.end(), current_lpeobj)); + + if ( found_it != old_lpeobjs.end() ) { + std::vector::difference_type found_index = std::distance (old_lpeobjs.begin(), found_it); + const gchar * repr_id = new_lpeobjs[found_index]->getRepr()->attribute("id"); + gchar *hrefstr = g_strdup_printf("#%s", repr_id); + hreflist.push_back( std::string(hrefstr) ); + g_free(hrefstr); + } + else { + hreflist.push_back( std::string((*it)->lpeobject_href) ); + } + } + + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); +} + +/** + * Check all effects in the stack if they are used by other items, and fork them if so. + * It is not recommended to fork the effects by yourself calling LivePathEffectObject::fork_private_if_necessary, + * use this method instead. + * Returns true if one or more effects were forked; returns false if nothing was done. + */ +bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users) +{ + bool forked = false; + + if ( this->hasPathEffect() ) { + // If one of the path effects is used by 2 or more items, fork it + // so that each object has its own independent copy of the effect. + // Note: replacing path effects messes up the path effect list + + // Clones of the LPEItem will increase the refcount of the lpeobjects. + // Therefore, nr_of_allowed_users should be increased with the number of clones (i.e. refs to the lpeitem) + nr_of_allowed_users += this->hrefcount; + + std::vector old_lpeobjs, new_lpeobjs; + PathEffectList effect_list = this->getEffectList(); + for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + LivePathEffectObject *forked_lpeobj = lpeobj->fork_private_if_necessary(nr_of_allowed_users); + if (forked_lpeobj != lpeobj) { + forked = true; + old_lpeobjs.push_back(lpeobj); + new_lpeobjs.push_back(forked_lpeobj); + } + } + } + + if (forked) { + this->replacePathEffects(old_lpeobjs, new_lpeobjs); + } + } + + return forked; +} + +// Enable or disable the path effects of the item. +// The counter allows nested calls +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) +{ + if (enable) { + lpeitem->path_effects_enabled++; + } + else { + lpeitem->path_effects_enabled--; + } +} + +// Are the path effects enabled on this item ? +bool SPLPEItem::pathEffectsEnabled() const +{ + return path_effects_enabled > 0; +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 0f80f50de6..9dd2c955d4 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -347,7 +347,7 @@ g_message("sp_path_update_patheffect"); } else { // LPE was unsuccessful. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { - this->setCurve(this->getCurveBeforeLPE(), TRUE); + this->setCurve(this->getCurveForEdit(), TRUE); } } } diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 1223cecfaf..e912713de3 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -365,8 +365,8 @@ void SPSpiral::set_shape(bool force) { /* 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)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { + if(this->getCurveForEdit()) { + if(!force && this->getCurveForEdit()->get_pathvector() == c->get_pathvector()) { c->unref(); return; } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 0af9e04721..16ca27cfff 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -447,8 +447,8 @@ void SPStar::set_shape(bool force) { /* 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)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { + if(this->getCurveForEdit()) { + if(!force && this->getCurveForEdit()->get_pathvector() == c->get_pathvector()) { c->unref(); return; } diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 145feda445..08a5ca68e9 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2560,7 +2560,7 @@ SPCurve* curve_for_item_before_LPE(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { - curve = SP_SHAPE(item)->getCurveBeforeLPE(); + curve = SP_SHAPE(item)->getCurveForEdit(); } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9413a911dd..26250be2f7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1500,7 +1500,7 @@ void PathManipulator::_setGeometry() } } else { if (empty()) return; - if (SPCurve * original = _path->get_original_curve()){ + if (SPCurve * original = _path->get_curve_for_edit()){ if(!_spcurve->is_equal(original)) { _path->set_original_curve(_spcurve, false, false); delete original; diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 2b3de5203a..be5b40a2b2 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -525,7 +525,7 @@ bool NodeTool::root_handler(GdkEvent* event) { } this->flashed_item = over_item; - SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE(); + SPCurve *c = SP_SHAPE(over_item)->getCurveForEdit(); if (!c) { break; // break out when curve doesn't exist diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 14fb72f97b..a3ce6f92c2 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -292,7 +292,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveBeforeLPE(); + SPCurve * c = shape->getCurveForEdit(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ @@ -333,7 +333,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) if (dynamic_cast(lpe)) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveBeforeLPE(); + SPCurve * c = shape->getCurveForEdit(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ diff --git a/testfiles/src/object-set-test.cpp b/testfiles/src/object-set-test.cpp index 295e398a29..1879777e56 100644 --- a/testfiles/src/object-set-test.cpp +++ b/testfiles/src/object-set-test.cpp @@ -594,7 +594,26 @@ TEST_F(ObjectSetTest, ZOrder) { EXPECT_TRUE(sp_object_compare_position_bool(r1.get(),r2.get())); } - +TEST_F(ObjectSetTest, Combine) { + set->add(r1.get()); + set->add(r2.get()); + set->combine(); + r1.release(); + r2.release(); + EXPECT_EQ(1, set->size()); + EXPECT_EQ(5, _doc->getRoot()->children.size()); + set->breakApart(); + EXPECT_EQ(2, set->size()); + EXPECT_EQ(6, _doc->getRoot()->children.size()); + set->deleteItems(); + set->set(r3.get()); + set->toCurves(); + r3.release(); + auto x = set->singleItem(); + EXPECT_NE(nullptr,dynamic_cast(x)); + EXPECT_EQ(nullptr,dynamic_cast(x)); + set->deleteItems(); +} TEST_F(ObjectSetTest, Moves) { set->add(r1.get()); -- GitLab From 8e3cbd6bbea655824b915bb9d1617aabd80e8484 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 27 Jan 2018 23:58:43 +0100 Subject: [PATCH 28/57] Removing unwanted file --- src/sp-lpe-item.cpp.orig | 1087 -------------------------------------- 1 file changed, 1087 deletions(-) delete mode 100644 src/sp-lpe-item.cpp.orig diff --git a/src/sp-lpe-item.cpp.orig b/src/sp-lpe-item.cpp.orig deleted file mode 100644 index 061969a69b..0000000000 --- a/src/sp-lpe-item.cpp.orig +++ /dev/null @@ -1,1087 +0,0 @@ -/** \file - * Base class for live path effect items - */ -/* - * Authors: - * Johan Engelen - * Bastien Bouclet - * Abhishek Sharma - * - * Copyright (C) 2008 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#endif - -#include - -#include "bad-uri-exception.h" -#include "ui/tool/multi-path-manipulator.h" - -#include "live_effects/effect.h" -#include "live_effects/lpe-path_length.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" -#include "live_effects/lpe-mirror_symmetry.h" -#include "live_effects/lpe-copy_rotate.h" - -#include "sp-path.h" -#include "sp-item-group.h" -#include "attributes.h" -#include "uri.h" -#include "message-stack.h" -#include "inkscape.h" -#include "desktop.h" -#include "ui/shape-editor.h" -#include "path-chemistry.h" -#include "sp-ellipse.h" -#include "display/curve.h" -#include "svg/svg.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "sp-rect.h" -#include "ui/tools-switch.h" -#include "ui/tools/node-tool.h" - -/* LPEItem base class */ -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); - -static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); - -static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); -static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); - -typedef std::list HRefList; -static std::string patheffectlist_svg_string(PathEffectList const & list); -static std::string hreflist_svg_string(HRefList const & list); - -SPLPEItem::SPLPEItem() - : SPItem() - , path_effects_enabled(1) - , path_effect_list(new PathEffectList()) - , lpe_modified_connection_list(new std::list()) - , current_path_effect(NULL) - , lpe_helperpaths() -{ -} - -SPLPEItem::~SPLPEItem() { -} - -void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { - this->readAttr( "inkscape:path-effect" ); - - SPItem::build(document, repr); -} - -void SPLPEItem::release() { - // disconnect all modified listeners: - - for (std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); - mod_it != this->lpe_modified_connection_list->end(); ++mod_it) - { - mod_it->disconnect(); - } - - delete this->lpe_modified_connection_list; - this->lpe_modified_connection_list = NULL; - - PathEffectList::iterator it = this->path_effect_list->begin(); - - while ( it != this->path_effect_list->end() ) { - // unlink and delete all references in the list - (*it)->unlink(); - delete *it; - it = this->path_effect_list->erase(it); - } - - // delete the list itself - delete this->path_effect_list; - this->path_effect_list = NULL; - - SPItem::release(); -} - -void SPLPEItem::set(unsigned int key, gchar const* value) { - switch (key) { - case SP_ATTR_INKSCAPE_PATH_EFFECT: - { - this->current_path_effect = NULL; - - // Disable the path effects while populating the LPE list - sp_lpe_item_enable_path_effects(this, false); - - // disconnect all modified listeners: - for ( std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); - mod_it != this->lpe_modified_connection_list->end(); - ++mod_it) - { - mod_it->disconnect(); - } - - this->lpe_modified_connection_list->clear(); - // Clear the path effect list - PathEffectList::iterator it = this->path_effect_list->begin(); - while ( it != this->path_effect_list->end()) { - (*it)->unlink(); - delete *it; - it = this->path_effect_list->erase(it); - } - - // Parse the contents of "value" to rebuild the path effect reference list - if ( value ) { - std::istringstream iss(value); - std::string href; - - while (std::getline(iss, href, ';')) - { - Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(this); - - try { - path_effect_ref->link(href.c_str()); - } catch (Inkscape::BadURIException &e) { - g_warning("BadURIException when trying to find LPE: %s", e.what()); - path_effect_ref->unlink(); - delete path_effect_ref; - path_effect_ref = NULL; - } - - this->path_effect_list->push_back(path_effect_ref); - - if ( path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe() ) { - // connect modified-listener - this->lpe_modified_connection_list->push_back( - path_effect_ref->lpeobject->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), this)) ); - } else { - // something has gone wrong in finding the right patheffect. - g_warning("Unknown LPE type specified, LPE stack effectively disabled"); - // keep the effect in the lpestack, so the whole stack is effectively disabled but maintained - } - } - } - - sp_lpe_item_enable_path_effects(this, true); - } - break; - - default: - SPItem::set(key, value); - break; - } -} - -void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { - SPItem::update(ctx, flags); - - // update the helperpaths of all LPEs applied to the item - // TODO: re-add for the new node tool -} - -void SPLPEItem::modified(unsigned int flags) { - if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { - sp_lpe_item_update_patheffect(this, true, true); - } - -// SPItem::onModified(flags); -} - -Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - if (flags & SP_OBJECT_WRITE_EXT) { - if ( hasPathEffect() ) { - repr->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); - } else { - repr->setAttribute("inkscape:path-effect", NULL); - } - } - - SPItem::write(xml_doc, repr, flags); - - return repr; -} - - -/** - * returns true when LPE was successful. - */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { - - if (!curve) { - return false; - } - - if (this->hasPathEffect() && this->pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj) { - /** \todo Investigate the cause of this. - * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. - */ - g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); - return false; - } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if(!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { - return false; - } - } - } - return true; -} - -/** - * returns true when LPE was successful. - */ -bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { - if (!lpe) { - /** \todo Investigate the cause of this. - * Not sure, but I think this can happen when an unknown effect type is specified... - */ - g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); - return false; - } - if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - // if the effect expects mouse input before being applied and the input is not finished - // yet, we don't alter the path - return false; - } - //if is not clip or mask or LPE apply to clip and mask - if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { - lpe->setCurrentShape(current); - lpe->pathvector_before_effect = curve->get_pathvector(); - // To Calculate BBox on shapes and nested LPE - current->setCurveInsync(curve, true); - // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect_impl(this); - } - - try { - lpe->doEffect(curve); - } - - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); - } - return false; - } - - lpe->pathvector_after_effect = curve->get_pathvector(); - if (!SP_IS_GROUP(this)) { - lpe->doAfterEffect(this); - } - } - } - return true; -} - -// CPPIFY: make pure virtual -void SPLPEItem::update_patheffect(bool /*write*/) { - //throw; -} - -/** - * Calls any registered handlers for the update_patheffect action - */ -void -sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) -{ -#ifdef SHAPE_VERBOSE - g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); -#endif - g_return_if_fail (lpeitem != NULL); - g_return_if_fail (SP_IS_OBJECT (lpeitem)); - g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); - - if (!lpeitem->pathEffectsEnabled()) - return; - - SPLPEItem *top = NULL; - - if (wholetree) { - SPLPEItem *prev_parent = lpeitem; - SPLPEItem *parent = dynamic_cast(prev_parent->parent); - while (parent && parent->hasPathEffectRecursive()) { - prev_parent = parent; - parent = dynamic_cast(prev_parent->parent); - } - top = prev_parent; - } - else { - top = lpeitem; - } - - top->update_patheffect(write); -} - -/** - * Gets called when any of the lpestack's lpeobject repr contents change: i.e. parameter change in any of the stacked LPEs - */ -static void -lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) -{ -#ifdef SHAPE_VERBOSE - g_message("lpeobject_ref_modified"); -#endif - sp_lpe_item_update_patheffect (lpeitem, true, true); -} - -static void -sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) -{ - g_return_if_fail(lpeitem != NULL); - - SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPLPEItem * clip_data = dynamic_cast(*iter); - sp_lpe_item_create_original_path_recursive(clip_data); - } - } - - SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); - if(mask_path) { - std::vector mask_path_list = mask_path->childList(true); - for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { - SPLPEItem * mask_data = dynamic_cast(*iter); - sp_lpe_item_create_original_path_recursive(mask_data); - } - } - if (SP_IS_GROUP(lpeitem)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - if (SP_IS_LPE_ITEM(subitem)) { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); - } - } - } - else if (SP_IS_PATH(lpeitem)) { - Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); - if ( !pathrepr->attribute("inkscape:original-d") ) { - pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); - } - } -} - -static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) -{ - g_return_if_fail(lpeitem != NULL); - SPItem *item = dynamic_cast(lpeitem); - if (!item) { - return; - } - SPGroup *group = dynamic_cast(lpeitem); - SPShape *shape = dynamic_cast(lpeitem); - SPPath *path = dynamic_cast(lpeitem); - SPClipPath *clip_path = item->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPLPEItem* clip_data = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, shape && !shape->hasPathEffectRecursive()); - } - } - - SPMask *mask_path = item->mask_ref->getObject(); - if(mask_path) { - std::vector mask_path_list = mask_path->childList(true); - for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { - SPLPEItem* mask_data = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, shape && !shape->hasPathEffectRecursive()); - } - } - - if (group) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPLPEItem* subitem = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths, false); - } - } else if (path) { - Inkscape::XML::Node *repr = lpeitem->getRepr(); - if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) - { - if (!keep_paths) { - repr->setAttribute("d", repr->attribute("inkscape:original-d")); - } - repr->setAttribute("inkscape:original-d", NULL); - } else { - if (!keep_paths) { - sp_lpe_item_update_patheffect(lpeitem, true, true); - } - } - } else if (shape) { - Inkscape::XML::Node *repr = lpeitem->getRepr(); - if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) - { - if (!keep_paths) { - repr->setAttribute("d", NULL); - } else { - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - std::vector items; - items.push_back(SP_ITEM(lpeitem)); - std::vector selected = items; - std::vector to_select; - sp_item_list_to_curves(items, selected, to_select, true); - } - } - } else { - if (!keep_paths) { - sp_lpe_item_update_patheffect(lpeitem, true, true); - } - } - - } -} - -void SPLPEItem::addPathEffect(std::string value, bool reset) -{ - if (!value.empty()) { - // Apply the path effects here because in the casse of a group, lpe->resetDefaults - // needs that all the subitems have their effects applied - sp_lpe_item_update_patheffect(this, false, true); - - // Disable the path effects while preparing the new lpe - sp_lpe_item_enable_path_effects(this, false); - - // Add the new reference to the list of LPE references - HRefList hreflist; - for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - hreflist.push_back( std::string((*it)->lpeobject_href) ); - } - hreflist.push_back(value); // C++11: should be emplace_back std::move'd (also the reason why passed by value to addPathEffect) - - this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); - - // Make sure that ellipse is stored as - if( SP_IS_GENERICELLIPSE(this)) { - SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); - } - // make sure there is an original-d for paths!!! - sp_lpe_item_create_original_path_recursive(this); - - LivePathEffectObject *lpeobj = this->path_effect_list->back()->lpeobject; - if (lpeobj && lpeobj->get_lpe()) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - // Ask the path effect to reset itself if it doesn't have parameters yet - if (reset) { - // has to be called when all the subitems have their lpes applied - lpe->resetDefaults(this); - } - - // perform this once when the effect is applied - lpe->doOnApply(this); - - // indicate that all necessary preparations are done and the effect can be performed - lpe->setReady(); - } - - //Enable the path effects now that everything is ready to apply the new path effect - sp_lpe_item_enable_path_effects(this, true); - - // Apply the path effect - sp_lpe_item_update_patheffect(this, true, true); - //fix bug 1219324 - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tools_switch(SP_ACTIVE_DESKTOP, TOOLS_SELECT); //mhh - tools_switch(SP_ACTIVE_DESKTOP, TOOLS_NODES); - } - } - } -} - -void SPLPEItem::addPathEffect(LivePathEffectObject * new_lpeobj) -{ - const gchar * repr_id = new_lpeobj->getRepr()->attribute("id"); - gchar *hrefstr = g_strdup_printf("#%s", repr_id); - this->addPathEffect(hrefstr, false); - g_free(hrefstr); -} - -/** - * If keep_path is true, the item should not be updated, effectively 'flattening' the LPE. - */ -void SPLPEItem::removeCurrentPathEffect(bool keep_paths) -{ - Inkscape::LivePathEffect::LPEObjectReference* lperef = this->getCurrentLPEReference(); - if (!lperef) - return; - - if (Inkscape::LivePathEffect::Effect* effect_ = this->getCurrentLPE()) { - effect_->keep_paths = keep_paths; - effect_->doOnRemove(this); - } - PathEffectList new_list = *this->path_effect_list; - new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list - this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - if (!keep_paths) { - // Make sure that ellipse is stored as or if possible. - if( SP_IS_GENERICELLIPSE(this)) { - SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); - } - } - sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); -} - -/** - * If keep_path is true, the item should not be updated, effectively 'flattening' the LPE. - */ -void SPLPEItem::removeAllPathEffects(bool keep_paths) -{ - if (keep_paths) { - if (path_effect_list->empty()) { - return; - } - } - - PathEffectList::iterator it = this->path_effect_list->begin(); - - while ( it != this->path_effect_list->end() ) { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (lpe) { - lpe->keep_paths = keep_paths; - lpe->doOnRemove(this); - } - } - // unlink and delete all references in the list - (*it)->unlink(); - ++it; - } - this->path_effect_list->clear(); - this->getRepr()->setAttribute("inkscape:path-effect", NULL); - - if (!keep_paths) { - // Make sure that ellipse is stored as or if possible. - if (SP_IS_GENERICELLIPSE(this)) { - SP_GENERICELLIPSE(this)->write(this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT); - } - } - sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); -} - -void SPLPEItem::downCurrentPathEffect() -{ - Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); - if (!lperef) - return; - - PathEffectList new_list = *this->path_effect_list; - PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); - if (cur_it != new_list.end()) { - PathEffectList::iterator down_it = cur_it; - ++down_it; - if (down_it != new_list.end()) { // perhaps current effect is already last effect - std::iter_swap(cur_it, down_it); - } - } - - this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - - sp_lpe_item_cleanup_original_path_recursive(this, false); -} - -void SPLPEItem::upCurrentPathEffect() -{ - Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); - if (!lperef) - return; - - PathEffectList new_list = *this->path_effect_list; - PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); - if (cur_it != new_list.end() && cur_it != new_list.begin()) { - PathEffectList::iterator up_it = cur_it; - --up_it; - std::iter_swap(cur_it, up_it); - } - - this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - - sp_lpe_item_cleanup_original_path_recursive(this, false); -} - -/** used for shapes so they can see if they should also disable shape calculation and read from d= */ -bool SPLPEItem::hasBrokenPathEffect() const -{ - if (path_effect_list->empty()) { - return false; - } - - // go through the list; if some are unknown or invalid, return true - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj || !lpeobj->get_lpe()) { - return true; - } - } - - return false; -} - -bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const -{ - if (path_effect_list->empty()) { - return false; - } - - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject const *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); - if (lpe && (lpe->effectType() == type)) { - if (is_ready || lpe->isReady()) { - return true; - } - } - } - } - - return false; -} - -bool SPLPEItem::hasPathEffect() const -{ - if (!path_effect_list || path_effect_list->empty()) { - return false; - } - - // go through the list; if some are unknown or invalid, we are not an LPE item! - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj || !lpeobj->get_lpe()) { - return false; - } - } - - return true; -} - -bool SPLPEItem::hasPathEffectRecursive() const -{ - SPLPEItem * parent_lpe_item = dynamic_cast(parent); - if (parent_lpe_item) { - return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); - } - else { - return hasPathEffect(); - } -} - -void -SPLPEItem::resetClipPathAndMaskLPE() -{ - SPClipPath *clip_path = this->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPGroup* group = dynamic_cast(*iter); - SPShape* shape = dynamic_cast(*iter); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { - SPLPEItem * subitem = dynamic_cast(*iter2); - if (subitem) { - subitem->resetClipPathAndMaskLPE(); - } - } - } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); - } - } - } - SPMask *mask = this->mask_ref->getObject(); - if(mask) { - std::vector mask_list = mask->childList(true); - for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { - SPGroup* group = dynamic_cast(*iter); - SPShape* shape = dynamic_cast(*iter); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { - SPLPEItem * subitem = dynamic_cast(*iter2); - if (subitem) { - subitem->resetClipPathAndMaskLPE(); - } - } - } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); - } - } - } -} - -void -SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) -{ - if (lpe && !lpe->apply_to_clippath_and_mask) { - return; - } - SPClipPath *clip_path = to->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data), to, lpe); - } - } -} - -void -SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) -{ - if (lpe && !lpe->apply_to_clippath_and_mask) { - return; - } - SPMask *mask = to->mask_ref->getObject(); - if(mask) { - std::vector mask_list = mask->childList(true); - for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { - SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data), to, lpe); - } - } -} - -void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe) -{ - SPGroup* group = dynamic_cast(clip_mask); - SPShape* shape = dynamic_cast(clip_mask); - SPLPEItem* tolpe = dynamic_cast(to); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPItem *subitem = *iter; - applyToClipPathOrMask(subitem, to, lpe); - } - } else if (shape) { - SPCurve * c = NULL; - // If item is a SPRect, convert it to path first: - if ( dynamic_cast(shape) ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty() ) { - sel->clear(); - sel->add(SP_ITEM(shape)); - sel->toCurves(); - SPItem* item = sel->singleItem(); - shape = dynamic_cast(item); - if (!shape) { - return; - } - sel->clear(); - sel->add(this); - } - } - } - c = shape->getCurve(); - if (c) { - bool success = false; - try { - if(SP_IS_GROUP(this)){ - c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); - if (lpe) { - success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); - } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - } - c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); - } else { - if (lpe) { - success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); - } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - } - } - } catch (std::exception & e) { - g_warning("Exception during LPE execution. \n %s", e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); - } - success = false; - } - Inkscape::XML::Node *repr = clip_mask->getRepr(); - if (success && c) { - shape->setCurveInsync( c, TRUE); - gchar *str = sp_svg_write_path(c->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - // LPE was unsuccessful or doeffect stack return null.. Read the old 'd'-attribute. - if (gchar const * value = repr->attribute("d")) { - Geom::PathVector pv = sp_svg_read_pathv(value); - SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); - if (oldcurve) { - SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } - } - if (c) { - c->unref(); - } - } - } -} - -Inkscape::LivePathEffect::Effect* -SPLPEItem::getPathEffectOfType(int type) -{ - std::list::iterator i; - for (i = path_effect_list->begin(); i != path_effect_list->end(); ++i) { - LivePathEffectObject *lpeobj = (*i)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect* lpe = lpeobj->get_lpe(); - if (lpe && (lpe->effectType() == type)) { - return lpe; - } - } - } - return NULL; -} - -Inkscape::LivePathEffect::Effect const* -SPLPEItem::getPathEffectOfType(int type) const -{ - std::list::const_iterator i; - for (i = path_effect_list->begin(); i != path_effect_list->end(); ++i) { - LivePathEffectObject const *lpeobj = (*i)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect const *lpe = lpeobj->get_lpe(); - if (lpe && (lpe->effectType() == type)) { - return lpe; - } - } - } - return NULL; -} - -void SPLPEItem::editNextParamOncanvas(SPDesktop *dt) -{ - Inkscape::LivePathEffect::LPEObjectReference *lperef = this->getCurrentLPEReference(); - if (lperef && lperef->lpeobject && lperef->lpeobject->get_lpe()) { - lperef->lpeobject->get_lpe()->editNextParamOncanvas(this, dt); - } -} - -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)); - } - } -} -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), false); - } - } - - SPItem::remove_child(child); -} - -static std::string patheffectlist_svg_string(PathEffectList const & list) -{ - HRefList hreflist; - - for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) - { - hreflist.push_back( std::string((*it)->lpeobject_href) ); // C++11: use emplace_back - } - - return hreflist_svg_string(hreflist); -} - -/** - * THE function that should be used to generate any patheffectlist string. - * one of the methods to change the effect list: - * - create temporary href list - * - populate the templist with the effects from the old list that you want to have and their order - * - call this function with temp list as param - */ -static std::string hreflist_svg_string(HRefList const & list) -{ - std::string r; - bool semicolon_first = false; - - for (HRefList::const_iterator it = list.begin(); it != list.end(); ++it) - { - if (semicolon_first) { - r += ';'; - } - - semicolon_first = true; - - r += (*it); - } - - return r; -} - -// Return a copy of the effect list -PathEffectList SPLPEItem::getEffectList() -{ - return *path_effect_list; -} - -// Return a copy of the effect list -PathEffectList const SPLPEItem::getEffectList() const -{ - return *path_effect_list; -} - -Inkscape::LivePathEffect::LPEObjectReference* SPLPEItem::getCurrentLPEReference() -{ - if (!this->current_path_effect && !this->path_effect_list->empty()) { - setCurrentPathEffect(this->path_effect_list->back()); - } - - return this->current_path_effect; -} - -Inkscape::LivePathEffect::Effect* SPLPEItem::getCurrentLPE() -{ - Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); - - if (lperef && lperef->lpeobject) - return lperef->lpeobject->get_lpe(); - else - return NULL; -} - -bool SPLPEItem::setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef) -{ - for (PathEffectList::iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) { - if ((*it)->lpeobject_repr == lperef->lpeobject_repr) { - this->current_path_effect = (*it); // current_path_effect should always be a pointer from the path_effect_list ! - return true; - } - } - - return false; -} - -/** - * Writes a new "inkscape:path-effect" string to xml, where the old_lpeobjects are substituted by the new ones. - * Note that this method messes up the item's \c PathEffectList. - */ -void SPLPEItem::replacePathEffects( std::vector const &old_lpeobjs, - std::vector const &new_lpeobjs ) -{ - HRefList hreflist; - for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject const * current_lpeobj = (*it)->lpeobject; - std::vector::const_iterator found_it(std::find(old_lpeobjs.begin(), old_lpeobjs.end(), current_lpeobj)); - - if ( found_it != old_lpeobjs.end() ) { - std::vector::difference_type found_index = std::distance (old_lpeobjs.begin(), found_it); - const gchar * repr_id = new_lpeobjs[found_index]->getRepr()->attribute("id"); - gchar *hrefstr = g_strdup_printf("#%s", repr_id); - hreflist.push_back( std::string(hrefstr) ); - g_free(hrefstr); - } - else { - hreflist.push_back( std::string((*it)->lpeobject_href) ); - } - } - - this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); -} - -/** - * Check all effects in the stack if they are used by other items, and fork them if so. - * It is not recommended to fork the effects by yourself calling LivePathEffectObject::fork_private_if_necessary, - * use this method instead. - * Returns true if one or more effects were forked; returns false if nothing was done. - */ -bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users) -{ - bool forked = false; - - if ( this->hasPathEffect() ) { - // If one of the path effects is used by 2 or more items, fork it - // so that each object has its own independent copy of the effect. - // Note: replacing path effects messes up the path effect list - - // Clones of the LPEItem will increase the refcount of the lpeobjects. - // Therefore, nr_of_allowed_users should be increased with the number of clones (i.e. refs to the lpeitem) - nr_of_allowed_users += this->hrefcount; - - std::vector old_lpeobjs, new_lpeobjs; - PathEffectList effect_list = this->getEffectList(); - for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - LivePathEffectObject *forked_lpeobj = lpeobj->fork_private_if_necessary(nr_of_allowed_users); - if (forked_lpeobj != lpeobj) { - forked = true; - old_lpeobjs.push_back(lpeobj); - new_lpeobjs.push_back(forked_lpeobj); - } - } - } - - if (forked) { - this->replacePathEffects(old_lpeobjs, new_lpeobjs); - } - } - - return forked; -} - -// Enable or disable the path effects of the item. -// The counter allows nested calls -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) -{ - if (enable) { - lpeitem->path_effects_enabled++; - } - else { - lpeitem->path_effects_enabled--; - } -} - -// Are the path effects enabled on this item ? -bool SPLPEItem::pathEffectsEnabled() const -{ - return path_effects_enabled > 0; -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- GitLab From c3ce2b284f2f7d5ce4fc1fd425f7e4aaf332eaba Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 28 Jan 2018 11:29:25 +0100 Subject: [PATCH 29/57] Refactoring LPE --- src/live_effects/lpe-interpolate.cpp | 2 +- src/live_effects/lpe-perp_bisector.cpp | 2 +- src/path-chemistry.cpp | 2 +- src/sp-conn-end-pair.cpp | 2 +- src/sp-ellipse.cpp | 7 +-- src/sp-lpe-item.cpp | 4 +- src/sp-path.cpp | 68 +++++++++++++------------- src/sp-path.h | 9 ++-- src/sp-shape.cpp | 17 +++++-- src/sp-shape.h | 6 +-- src/ui/tool/path-manipulator.cpp | 2 +- src/ui/tools/connector-tool.cpp | 4 +- 12 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index db3faa307c..7ee019de36 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -102,7 +102,7 @@ LPEInterpolate::resetDefaults(SPItem const* item) if (!SP_IS_PATH(item)) return; - SPCurve const *crv = SP_PATH(item)->get_curve_reference(); + SPCurve const *crv = SP_PATH(item)->get_curve_for_edit(true); Geom::PathVector const &pathv = crv->get_pathvector(); if ( (pathv.size() < 2) ) return; diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index dab169cfe8..f65dfc912a 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -120,7 +120,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) SPCurve *c = new SPCurve(); c->moveto(A); c->lineto(B); - // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work? + // TODO: Why doesn't sp_path_set_curve_before_LPE(SP_PATH(lpeitem), c, TRUE, true) work? SP_PATH(lpeitem)->original_curve = c->ref(); c->unref(); **/ diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 41079bc1fd..8edf58095f 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -643,7 +643,7 @@ ObjectSet::pathReverse() did = true; - SPCurve *rcurve = path->get_curve_reference()->create_reverse(); + SPCurve *rcurve = path->get_curve_for_edit(true)->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp index daadd0cddc..84c41ce33c 100644 --- a/src/sp-conn-end-pair.cpp +++ b/src/sp-conn-end-pair.cpp @@ -175,7 +175,7 @@ void SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const { void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { - SPCurve const *curve = _path->get_curve_reference(); + SPCurve const *curve = _path->get_curve_for_edit(true); SPItem *h2attItem[2] = {0}; getAttachedItems(h2attItem); Geom::Affine i2d = _path->i2doc_affine(); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index f06f1659df..bdad5d05fd 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -625,7 +625,7 @@ void SPGenericEllipse::modified(guint flags) void SPGenericEllipse::update_patheffect(bool write) { Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(true)) { + if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ this->setCurveInsync(c_lpe, TRUE); @@ -637,11 +637,6 @@ void SPGenericEllipse::update_patheffect(bool write) this->setCurveInsync(c_lpe, TRUE); this->applyToClipPath(this); this->applyToMask(this); - } else { - // LPE was unsuccessful. Read the old 'd'-attribute. - if (gchar const * value = repr->attribute("d")) { - this->setCurve(this->getCurveForEdit(), TRUE); - } } } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index b7f73bad77..4127f96a94 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -704,7 +704,7 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(false, true), TRUE); } } } @@ -723,7 +723,7 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(false, true), TRUE); } } } diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 9dd2c955d4..582ad6231f 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -192,11 +192,11 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->set_original_curve(curve, TRUE, true); + this->set_curve_before_LPE(curve, TRUE, true); curve->unref(); } } else { - this->set_original_curve(NULL, TRUE, true); + this->set_curve_before_LPE(NULL, TRUE, true); } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -332,7 +332,7 @@ void SPPath::update_patheffect(bool write) { g_message("sp_path_update_patheffect"); #endif Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(true)) { + if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ this->setCurveInsync(c_lpe, TRUE); @@ -344,11 +344,6 @@ g_message("sp_path_update_patheffect"); this->setCurveInsync(c_lpe, TRUE); this->applyToClipPath(this); this->applyToMask(this); - } else { - // LPE was unsuccessful. Read the old 'd'-attribute. - if (gchar const * value = repr->attribute("d")) { - this->setCurve(this->getCurveForEdit(), TRUE); - } } } @@ -396,7 +391,7 @@ g_message("sp_path_update_patheffect"); * and also triggers a request to update the display. Does not write * result to XML when write=false. */ -void SPPath::set_original_curve (SPCurve *new_curve, unsigned int owner, bool write) +void SPPath::set_curve_before_LPE (SPCurve *new_curve, unsigned int owner, bool write) { if (_curve_before_lpe) { _curve_before_lpe = _curve_before_lpe->unref(); @@ -415,51 +410,54 @@ void SPPath::set_original_curve (SPCurve *new_curve, unsigned int owner, bool wr } /** - * Return duplicate of _curve_before_lpe (if any exists) or NULL if there is no curve + * Return duplicate of _curve (if any exists) or NULL if there is no curve */ -SPCurve * SPPath::get_original_curve () const +SPCurve* SPPath::get_curve (bool reference) { - if (hasPathEffectRecursive() && _curve_before_lpe) { - return _curve_before_lpe->copy(); + if (_curve) { + if (reference) { + return _curve; + } + return _curve->copy(); } - return NULL; } + /** - * Return duplicate of edittable curve which is _curve_before_lpe if it exists or - * shape->curve if not. + * Return duplicate of _curve_before_lpe (if any exists) or NULL if there is no curve */ -SPCurve* SPPath::get_curve_for_edit(bool force) const +SPCurve * SPPath::get_curve_before_LPE (bool reference, bool force) const { if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (reference) { + return _curve_before_lpe; + } return _curve_before_lpe->copy(); } - return _curve; -} -/** - * 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 && hasPathEffectRecursive()) { - return _curve_before_lpe; - } - return _curve; + return NULL; } /** - * Returns \c _curve_before_lpe if it is not NULL and a valid LPE is applied or \c curve if not. - * \todo should only be available to class friends! + * Return duplicate of edittable curve which is _curve_before_lpe if it exists or + * shape->curve if not. */ -SPCurve* SPPath::get_curve () +SPCurve* SPPath::get_curve_for_edit(bool reference, bool force) const { - if (_curve_before_lpe && hasPathEffectRecursive()) { - return _curve_before_lpe; + if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (reference) { + return _curve_before_lpe; + } + return _curve_before_lpe->copy(); } - return _curve; + if (_curve) { + if (reference) { + return _curve; + } + return _curve->copy(); + } + return NULL; } /* diff --git a/src/sp-path.h b/src/sp-path.h index 798ee04514..24438bff06 100644 --- a/src/sp-path.h +++ b/src/sp-path.h @@ -35,13 +35,12 @@ public: int nodesInPath() const; // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. - void set_original_curve (SPCurve *curve, unsigned int owner, bool write); - SPCurve* get_original_curve () const; - SPCurve* get_curve_for_edit (bool force = false) const; - const SPCurve* get_curve_reference() const; + void set_curve_before_LPE (SPCurve *curve, unsigned int owner, bool write); + SPCurve* get_curve_before_LPE (bool reference = false, bool force = false) const; + SPCurve* get_curve_for_edit (bool reference = false, bool force = false) const; public: // should be made protected - SPCurve* get_curve(); + SPCurve* get_curve(bool reference = false); friend class SPConnEndPair; public: diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 25ccb782ab..1dbd6baee3 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -1013,9 +1013,12 @@ SPShape::setCurveBeforeLPE (SPCurve *new_curve) /** * Return duplicate of curve (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurve() const +SPCurve * SPShape::getCurve(bool reference) const { if (_curve) { + if(reference) { + return _curve; + } return _curve->copy(); } @@ -1025,9 +1028,12 @@ SPCurve * SPShape::getCurve() const /** * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurveBeforeLPE() const +SPCurve * SPShape::getCurveBeforeLPE(bool reference.bool force) const { if (hasPathEffectRecursive() && _curve_before_lpe) { + if (reference) { + return _curve_before_lpe; + } return _curve_before_lpe->copy(); } return NULL; @@ -1036,12 +1042,15 @@ SPCurve * SPShape::getCurveBeforeLPE() const /** * Return curve for edit */ -SPCurve * SPShape::getCurveForEdit(bool force) const +SPCurve * SPShape::getCurveForEdit(bool reference, bool force) const { if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (reference) { + return _curve_before_lpe; + } return _curve_before_lpe->copy(); } - return getCurve(); + return getCurve(reference); } diff --git a/src/sp-shape.h b/src/sp-shape.h index ffa1e09ff1..2530cf500e 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -39,9 +39,9 @@ public: SPShape(); virtual ~SPShape(); - SPCurve * getCurve () const; - SPCurve * getCurveBeforeLPE () const; - SPCurve * getCurveForEdit (bool force = false) const; + SPCurve * getCurve (bool reference = false) const; + SPCurve * getCurveBeforeLPE (bool reference = false, bool force = false) const; + SPCurve * getCurveForEdit (bool reference = false, bool force = false) const; void setCurve (SPCurve *curve, unsigned int owner); void setCurveInsync (SPCurve *curve, unsigned int owner); void setCurveBeforeLPE (SPCurve *curve); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 26250be2f7..4abed8dca6 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1502,7 +1502,7 @@ void PathManipulator::_setGeometry() if (empty()) return; if (SPCurve * original = _path->get_curve_for_edit()){ if(!_spcurve->is_equal(original)) { - _path->set_original_curve(_spcurve, false, false); + _path->set_curve_before_LPE(_spcurve, false, false); delete original; } } else if(!_spcurve->is_equal(_path->get_curve())) { diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index bb2e724ae8..27482b6f4a 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -1130,7 +1130,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { g_assert( SP_IS_PATH(item) ); - const SPCurve *curve = SP_PATH(item)->get_curve_reference(); + const SPCurve *curve = SP_PATH(item)->get_curve_for_edit(true); Geom::Affine i2dt = item->i2dt_affine(); if (this->active_conn == item) { @@ -1270,7 +1270,7 @@ static bool cc_item_is_shape(SPItem *item) bool cc_item_is_connector(SPItem *item) { if (SP_IS_PATH(item)) { - bool closed = SP_PATH(item)->get_curve_reference()->is_closed(); + bool closed = SP_PATH(item)->get_curve_for_edit(true)->is_closed(); if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) { // To be considered a connector, an object must be a non-closed // path that is marked with a "inkscape:connector-type" attribute. -- GitLab From 98d538c227646b564b5a30847ec11b752679ffe3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 28 Jan 2018 18:19:43 +0100 Subject: [PATCH 30/57] Fixed clip and mask --- src/sp-conn-end-pair.cpp | 2 +- src/sp-ellipse.cpp | 7 +++- src/sp-lpe-item.cpp | 1 + src/sp-path.cpp | 21 ---------- src/sp-shape.cpp | 2 +- src/sp-spiral.cpp | 70 ++++++++++++++++--------------- src/sp-spiral.h | 2 +- src/sp-star.cpp | 71 +++++++++++++++++--------------- src/sp-star.h | 2 +- src/ui/tool/path-manipulator.cpp | 2 +- src/ui/tools/connector-tool.cpp | 2 +- 11 files changed, 86 insertions(+), 96 deletions(-) diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp index 84c41ce33c..33a8c0af94 100644 --- a/src/sp-conn-end-pair.cpp +++ b/src/sp-conn-end-pair.cpp @@ -322,7 +322,7 @@ bool SPConnEndPair::reroutePathFromLibavoid() return false; } - SPCurve *curve = _path->get_curve(); + SPCurve *curve = _path->get_curve(true); recreateCurve(curve, _connRef, _connCurvature); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index bdad5d05fd..a1b0efd8ee 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -476,11 +476,14 @@ void SPGenericEllipse::set_shape() curve->transform(aff); //If original shape dont change on a LPE item return here to allow LPE - if (this->getCurveForEdit()) { - if(this->getCurveForEdit()->get_pathvector() == curve->get_pathvector()) { + SPCurve * check = this->getCurveForEdit(false, true); + if (check) { + if(check->get_pathvector() == curve->get_pathvector()) { + check->unref(); curve->unref(); return; } + check->unref(); } /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 4127f96a94..2aee041e5c 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -841,6 +841,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa if (c) { c->unref(); } + shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 582ad6231f..f7467c84b0 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -357,29 +357,8 @@ g_message("sp_path_update_patheffect"); } } c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -// } else if(_curve_before_lpe) { -// SPCurve *curve = _curve_before_lpe->copy(); -// this->setCurveInsync(curve, TRUE); -// if (write) { -// // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. -//#ifdef PATH_VERBOSE -//g_message("sp_path_update_patheffect writes 'd' attribute"); -//#endif -// if (_curve) { -// gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); -// repr->setAttribute("d", str); -// g_free(str); -// } else { -// repr->setAttribute("d", NULL); -// } -// } -// this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -// curve->unref(); -// } - } diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 1dbd6baee3..07860c0666 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -1028,7 +1028,7 @@ SPCurve * SPShape::getCurve(bool reference) const /** * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurveBeforeLPE(bool reference.bool force) const +SPCurve * SPShape::getCurveBeforeLPE(bool reference, bool force) const { if (hasPathEffectRecursive() && _curve_before_lpe) { if (reference) { diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index e912713de3..45107c9160 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -197,21 +197,34 @@ void SPSpiral::update(SPCtx *ctx, guint flags) { } void SPSpiral::update_patheffect(bool write) { - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); + Inkscape::XML::Node *repr = this->getRepr(); + if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { + /* 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)*/ + this->setCurveInsync(c_lpe, TRUE); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); + } + } - if ( this->_curve != NULL ) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); + if (write && success) { + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } } + c_lpe->unref(); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } const char* SPSpiral::displayName() const { @@ -310,7 +323,7 @@ void SPSpiral::fitAndDraw(SPCurve* c, double dstep, Geom::Point darray[], Geom:: g_assert (is_unit_vector (hat2)); } -void SPSpiral::set_shape(bool force) { +void SPSpiral::set_shape() { if (hasBrokenPathEffect()) { 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"); @@ -363,31 +376,22 @@ void SPSpiral::set_shape(bool force) { this->fitAndDraw(c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); } - /* 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)*/ - if(this->getCurveForEdit()) { - if(!force && this->getCurveForEdit()->get_pathvector() == c->get_pathvector()) { + //If original shape dont change on a LPE item return here to allow LPE + SPCurve * check = this->getCurveForEdit(false, true); + if (check) { + if(check->get_pathvector() == c->get_pathvector()) { + check->unref(); c->unref(); return; } + check->unref(); } - setCurveInsync( c, TRUE); - setCurveBeforeLPE( c ); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - - if (success) { - this->setCurveInsync( c_lpe, TRUE); - this->applyToClipPath(this); - this->applyToMask(this); - } - - c_lpe->unref(); - } - + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + this->setCurveBeforeLPE(c); + this->setCurveInsync(c, TRUE); c->unref(); + return; } /** diff --git a/src/sp-spiral.h b/src/sp-spiral.h index ebf4c9e280..94724685c6 100644 --- a/src/sp-spiral.h +++ b/src/sp-spiral.h @@ -70,7 +70,7 @@ public: virtual const char* displayName() const; virtual char* description() const; - virtual void set_shape(bool force = false); + virtual void set_shape(); virtual void update_patheffect(bool write); private: diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 16ca27cfff..7480e00569 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -224,21 +224,34 @@ void SPStar::update(SPCtx *ctx, guint flags) { } void SPStar::update_patheffect(bool write) { - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); + Inkscape::XML::Node *repr = this->getRepr(); + if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { + /* 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)*/ + this->setCurveInsync(c_lpe, TRUE); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe, TRUE); + this->applyToClipPath(this); + this->applyToMask(this); + } + } - if ( this->_curve != NULL ) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); + if (write && success) { + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } } + c_lpe->unref(); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } const char* SPStar::displayName() const { @@ -364,7 +377,7 @@ sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ) #define NEXT false #define PREV true -void SPStar::set_shape(bool force) { +void SPStar::set_shape() { // perhaps we should convert all our shapes into LPEs without source path // and with knotholders for parameters, then this situation will be handled automatically // by disabling the entire stack (including the shape LPE) @@ -445,32 +458,22 @@ void SPStar::set_shape(bool force) { c->closepath(); - /* 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)*/ - if(this->getCurveForEdit()) { - if(!force && this->getCurveForEdit()->get_pathvector() == c->get_pathvector()) { + //If original shape dont change on a LPE item return here to allow LPE + SPCurve * check = this->getCurveForEdit(false, true); + if (check) { + if(check->get_pathvector() == c->get_pathvector()) { + check->unref(); c->unref(); return; } + check->unref(); } - this->setCurveInsync( c, TRUE); - this->setCurveBeforeLPE( c ); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - - if (success) { - this->setCurveInsync( c_lpe, TRUE); - this->applyToClipPath(this); - this->applyToMask(this); - } - - c_lpe->unref(); - - } - + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + this->setCurveBeforeLPE(c); + this->setCurveInsync(c, TRUE); c->unref(); + return; } void diff --git a/src/sp-star.h b/src/sp-star.h index 4519de8694..1ebe3298ad 100644 --- a/src/sp-star.h +++ b/src/sp-star.h @@ -55,7 +55,7 @@ public: virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void update_patheffect(bool write); - virtual void set_shape(bool force = false); + virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const& xform); }; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4abed8dca6..ae299fda3d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1505,7 +1505,7 @@ void PathManipulator::_setGeometry() _path->set_curve_before_LPE(_spcurve, false, false); delete original; } - } else if(!_spcurve->is_equal(_path->get_curve())) { + } else if(!_spcurve->is_equal(_path->get_curve(true))) { _path->setCurve(_spcurve, false); } } diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index 27482b6f4a..6452f7af72 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -612,7 +612,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) Geom::Affine i2d ( (this->clickeditem)->i2dt_affine() ); Geom::Affine d2i = i2d.inverse(); SPPath *path = SP_PATH(this->clickeditem); - SPCurve *curve = path->get_curve(); + SPCurve *curve = path->get_curve(true); if (this->clickedhandle == this->endpt_handle[0]) { Geom::Point o = this->endpt_handle[1]->pos; curve->stretch_endpoints(p * d2i, o * d2i); -- GitLab From 788f1d8ebc486139525ee001594818b79641b02f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 28 Jan 2018 20:23:31 +0100 Subject: [PATCH 31/57] Remove unused code --- src/selection-chemistry.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 12c46dc3e3..3abfb3da68 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -4199,15 +4199,6 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { // rebuild selection addList(items_to_select); - NodeTool *nt = NULL; - std::cout << "aaaaaaaaaaaaaaaaaaa" << std::endl; -// SPDesktop * desktop = desktop(); -// if (desktop && tools_isactive(desktop, TOOLS_NODES)) { -// nt = static_cast(desktop->event_context); -// if (nt) { -// nt->selection_changed(this); -// } -// } if (!skip_undo) { if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); -- GitLab From c912c72247c1841077fda43bfb01ebd3ce06a93b Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Tue, 30 Jan 2018 18:00:26 +0100 Subject: [PATCH 32/57] Fix rotate and mirror LPE issues on split --- src/live_effects/lpe-copy_rotate.cpp | 3 ++- src/live_effects/lpe-mirror_symmetry.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 7ab0123dcb..5a3c409c6f 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -233,7 +233,7 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; @@ -295,6 +295,7 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) Inkscape::GC::release(copy); elemref->deleteObject(); } + g_free(elemref_id); } void diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 884bf1c3db..378e433bb3 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -242,7 +242,7 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) if (document) { Inkscape::XML::Document *xml_doc = document->getReprDoc(); char * id_origin_char = id_origin.param_getSVGValue(); - const char * elemref_id = (Glib::ustring("mirror-") + Glib::ustring(id_origin_char)).c_str(); + char * elemref_id = g_strdup((Glib::ustring("mirror-") + Glib::ustring(id_origin_char)).c_str()); g_free(id_origin_char); items.clear(); items.push_back(elemref_id); @@ -305,6 +305,7 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) Inkscape::GC::release(copy); elemref->deleteObject(); } + g_free(elemref_id); } } -- GitLab From 6921ee0df46de3d963a9ef01700caf98a01002cf Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Tue, 30 Jan 2018 21:35:28 +0100 Subject: [PATCH 33/57] Fixes tosome LPE with satellite objects --- src/live_effects/lpe-copy_rotate.cpp | 28 ++- src/live_effects/lpe-measure-segments.cpp | 6 +- src/live_effects/lpe-mirror_symmetry.cpp | 243 +++++++++++++--------- src/live_effects/lpe-mirror_symmetry.h | 9 +- src/live_effects/lpegroupbbox.cpp | 8 +- src/ui/dialog/livepatheffect-editor.cpp | 11 + 6 files changed, 182 insertions(+), 123 deletions(-) diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 84d973e94c..0f83479222 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,6 +17,7 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/intersection-graph.h> #include "live_effects/lpe-copy_rotate.h" +#include "live_effects/lpeobject.h" #include "display/curve.h" #include "svg/path-string.h" #include "svg/svg.h" @@ -129,8 +130,8 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) if (numcopies_gap > 0 && num_copies != 0) { guint counter = num_copies - 1; while (numcopies_gap > 0) { - const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); - if (!id || strlen(id) == 0) { + char * id = g_strdup((Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(this->lpeobj->getId())).c_str()); + if (!id || strlen(id) == 0) { return; } SPObject *elemref = NULL; @@ -139,20 +140,22 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } counter++; numcopies_gap--; + g_free(id); } } previous_num_copies = num_copies; } SPObject *elemref = NULL; - const char * id = g_strdup(Glib::ustring("rotated-").append("0").append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); guint counter = 0; + char * id = g_strdup((Glib::ustring("rotated-0-").append(this->lpeobj->getId())).c_str()); while((elemref = document->getObjectById(id))) { - id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + id = g_strdup((Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(this->lpeobj->getId())).c_str()); if (SP_ITEM(elemref)->isHidden()) { - items.push_back(id); + items.push_back(g_strdup(id)); } counter++; } + g_free(id); Geom::Affine m = Geom::Translate(-origin) * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))); for (size_t i = 1; i < num_copies; ++i) { Geom::Affine r = Geom::identity(); @@ -200,15 +203,18 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo cloneD(*obj_it, dest_child, transform, false, reset); index++; } + return; } SPShape * shape = SP_SHAPE(orig); - if (shape && !SP_IS_PATH(dest)) { + SPPath * path = SP_PATH(dest); + if (shape && !path) { const char * id = dest->getId(); Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); dest->getRepr()->setAttribute("d", id); + path = SP_PATH(dest); } - if (SP_IS_PATH(dest) && shape) { + if (path && shape) { SPCurve *c = NULL; if (root) { c = new SPCurve(); @@ -217,10 +223,10 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo c = shape->getCurve(); } if (c) { - SP_PATH(dest)->setCurve(c, TRUE); + path->setCurve(c, TRUE); c->unref(); } else { - dest->getRepr()->setAttribute("d", NULL); + path->getRepr()->setAttribute("d", NULL); } if (reset) { dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); @@ -236,8 +242,8 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); - items.push_back(elemref_id); + char * elemref_id = g_strdup((Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(this->lpeobj->getId())).c_str()); + items.push_back(g_strdup(elemref_id)); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; if ((elemref = document->getObjectById(elemref_id))) { diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 18feaec502..3558e50774 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -140,7 +140,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_digits(2); star_ellipse_fix = Geom::identity(); locale_base = strdup(setlocale(LC_NUMERIC, NULL)); - //message.param_set_min_height(95); + message.param_set_min_height(85); } LPEMeasureSegments::~LPEMeasureSegments() {} @@ -349,7 +349,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng copy->setAttribute("id", id); elemref = elemref_copy; } - items.push_back(id); + items.push_back(g_strdup(id)); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.15; @@ -477,7 +477,7 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i elemref->deleteObject(); copy->setAttribute("id", id); } - items.push_back(id); + items.push_back(g_strdup(id)); } void diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e87d8895d5..5cce38e30a 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -61,8 +61,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), - id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) { show_orig_path = true; registerParameter(&mode); @@ -74,15 +73,13 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); - registerParameter(&id_origin); - id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(5); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); - id_origin.param_widget_is_visible(false); center_point.param_widget_is_visible(false); + reset = false; } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -97,30 +94,71 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) if (!document) { return; } + container = dynamic_cast(sp_lpe_item->parent); + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = document->getReprRoot(); + if (root_origin != root) { + return; + } if (split_items && !discard_orig_path) { - container = dynamic_cast(sp_lpe_item->parent); - Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); - Inkscape::XML::Node *root_origin = document->getReprRoot(); - if (root_origin != root) { - return; - } Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); m = m * sp_lpe_item->transform; - toMirror(m); + toMirror(m, reset); + reset = false; } else { processObjects(LPE_ERASE); items.clear(); } } +Gtk::Widget * +LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles")))); + reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEMirrorSymmetry::resetStyles)); + reset_button->set_size_request(110,20); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } + return dynamic_cast(vbox); +} + void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem, false, true); - //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); if (mode == MT_Y) { @@ -193,7 +231,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } void -LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool live, bool root) +LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool root, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -206,110 +244,117 @@ LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool live, bool root) for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, live, false); + cloneD(*obj_it, dest_child, false, reset); index++; } + return; } SPShape * shape = SP_SHAPE(orig); SPPath * path = SP_PATH(dest); - if (shape && !path) { + if (shape && !path) { + const char * id = dest->getId(); Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + dest->getRepr()->setAttribute("d", id); path = SP_PATH(dest); } if (path && shape) { - if ( live) { - SPCurve *c = NULL; - if (root) { - c = new SPCurve(); - c->set_pathvector(pathvector_after_effect); - } else { - c = shape->getCurve(); - } - if (c) { - path->setCurve(c, TRUE); - c->unref(); - } else { - dest->getRepr()->setAttribute("d", NULL); - } + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_after_effect); + } else { + c = shape->getCurve(); + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); } else { - dest->getRepr()->setAttribute("d", orig->getRepr()->attribute("d")); + path->getRepr()->setAttribute("d", NULL); + } + if (reset) { + dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); } } } void -LPEMirrorSymmetry::toMirror(Geom::Affine transform) +LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; - if (document) { - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - char * id_origin_char = id_origin.param_getSVGValue(); - char * elemref_id = g_strdup((Glib::ustring("mirror-") + Glib::ustring(id_origin_char)).c_str()); - g_free(id_origin_char); - items.clear(); - items.push_back(elemref_id); - SPObject *elemref= NULL; - Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id))) { - phantom = elemref->getRepr(); - } else { - phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); - std::vector attrs; - attrs.push_back("inkscape:path-effect"); - attrs.push_back("inkscape:original-d"); - attrs.push_back("sodipodi:type"); - attrs.push_back("sodipodi:rx"); - attrs.push_back("sodipodi:ry"); - attrs.push_back("sodipodi:cx"); - attrs.push_back("sodipodi:cy"); - attrs.push_back("sodipodi:end"); - attrs.push_back("sodipodi:start"); - attrs.push_back("inkscape:flatsided"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:rounded"); - attrs.push_back("sodipodi:arg1"); - attrs.push_back("sodipodi:arg2"); - attrs.push_back("sodipodi:r1"); - attrs.push_back("sodipodi:r2"); - attrs.push_back("sodipodi:sides"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("sodipodi:argument"); - attrs.push_back("sodipodi:expansion"); - attrs.push_back("sodipodi:radius"); - attrs.push_back("sodipodi:revolution"); - attrs.push_back("sodipodi:t0"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("x"); - attrs.push_back("y"); - attrs.push_back("rx"); - attrs.push_back("ry"); - attrs.push_back("width"); - attrs.push_back("height"); - for(const char * attr : attrs) { - phantom->setAttribute(attr, NULL); - } - } + if (!document) { + return; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + char * elemref_id = g_strdup((Glib::ustring("mirror-") + this->lpeobj->getId()).c_str()); + items.clear(); + items.push_back(g_strdup(elemref_id)); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if ((elemref = document->getObjectById(elemref_id))) { + phantom = elemref->getRepr(); + } else { + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + std::vector attrs; + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); phantom->setAttribute("id", elemref_id); - if (!elemref) { - elemref = container->appendChildRepr(phantom); - Inkscape::GC::release(phantom); - } - cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); - gchar *str = sp_svg_transform_write(transform); - elemref->getRepr()->setAttribute("transform" , str); - g_free(str); - if (elemref->parent != container) { - Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id); - container->appendChildRepr(copy); - Inkscape::GC::release(copy); - elemref->deleteObject(); + for(const char * attr : attrs) { + phantom->setAttribute(attr, NULL); } - g_free(elemref_id); } + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, reset); + gchar *str = sp_svg_transform_write(transform); + elemref->getRepr()->setAttribute("transform" , str); + g_free(str); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } + g_free(elemref_id); +} + +void +LPEMirrorSymmetry::resetStyles(){ + reset = true; + doAfterEffect(sp_lpe_item); } //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication @@ -359,10 +404,6 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) center_point.param_setValue(point_c); previous_center = center_point; SPLPEItem * splpeitem = const_cast(lpeitem); - if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet - id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); - id_origin.write_to_SVG(); - } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index e98c83f2b8..99a9cfc140 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -46,9 +46,10 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); - void toMirror(Geom::Affine transform); - // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); - void cloneD(SPObject *orig, SPObject *dest, bool live, bool root); + virtual Gtk::Widget * newWidget(); + void toMirror(Geom::Affine transform, bool reset); + void cloneD(SPObject *orig, SPObject *dest, bool root, bool reset); + void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -63,9 +64,9 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; - TextParam id_origin; Geom::Point previous_center; SPObject * container; + bool reset; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index eeee3ab60c..655d4088da 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -6,10 +6,10 @@ */ #include "live_effects/lpegroupbbox.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "sp-shape.h" -#include "sp-item-group.h" +#include "object/sp-clippath.h" +#include "object/sp-mask.h" +#include "object/sp-shape.h" +#include "object/sp-item-group.h" #include "object/sp-lpe-item.h" diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index ce17ccd2d9..6cf7f807a6 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -42,6 +42,7 @@ #include "object/sp-text.h" #include "ui/icon-names.h" +#include "ui/tools/node-tool.h" #include "ui/widget/imagetoggler.h" namespace Inkscape { @@ -554,6 +555,16 @@ void LivePathEffectEditor::on_effect_selection_changed() if (effect) { lpe_changed = true; showParams(*effect); + //To reload knots and helper paths + Inkscape::Selection *sel = _getSelection(); + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); + if (item) { + sel->clear(); + sel->add(item); + Inkscape::UI::Tools::sp_update_helperpath(); + } + } } } } -- GitLab From af528bd2e7fdd0e542c8f8774ff6daa859562bc4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 31 Jan 2018 08:38:42 +0100 Subject: [PATCH 34/57] Working on doAfterEffect --- src/live_effects/lpe-mirror_symmetry.cpp | 5 ++++- src/live_effects/parameter/point.cpp | 3 +++ src/object/sp-ellipse.cpp | 4 ++++ src/object/sp-item-group.cpp | 2 ++ src/object/sp-lpe-item.cpp | 17 ++++++++++++++--- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 5cce38e30a..3e65e62a7f 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -101,6 +101,7 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) return; } if (split_items && !discard_orig_path) { + std::cout << "kkkkkkkkkk" << std::endl; Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); m = m * sp_lpe_item->transform; @@ -178,7 +179,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } if ( mode == MT_X || mode == MT_Y ) { if (!are_near(previous_center, (Geom::Point)center_point, 0.01)) { - center_point.param_setValue(Geom::middle_point(point_a, point_b), true); + center_point.param_setValue(Geom::middle_point(point_a, point_b)); end_point.param_setValue(point_b); start_point.param_setValue(point_a); } else { @@ -206,6 +207,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) start_point.param_setValue(start_point * trans); end_point.param_setValue(end_point * trans); } + std::cout << "lolololo" << std::endl; } else if ( mode == MT_V){ SPDocument * document = SP_ACTIVE_DOCUMENT; if (document) { @@ -227,6 +229,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); } } + previous_center = center_point; } diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 9b4723da3e..1e9097fcbb 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -95,6 +95,9 @@ PointParam::param_hide_knot(bool hide) { void PointParam::param_setValue(Geom::Point newpoint, bool write) { + if (*dynamic_cast( this ) == newpoint) { + return; + } *dynamic_cast( this ) = newpoint; if(write){ Inkscape::SVGOStringStream os; diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index a1b0efd8ee..745c2b550a 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -631,6 +631,7 @@ void SPGenericEllipse::update_patheffect(bool write) if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ + SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe, TRUE); this->resetClipPathAndMaskLPE(); bool success = false; @@ -640,6 +641,8 @@ void SPGenericEllipse::update_patheffect(bool write) this->setCurveInsync(c_lpe, TRUE); this->applyToClipPath(this); this->applyToMask(this); + } else { + this->setCurveInsync(last, TRUE); } } @@ -653,6 +656,7 @@ void SPGenericEllipse::update_patheffect(bool write) } } c_lpe->unref(); + last->unref(); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index c83ee7aa31..b7692ef96f 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -968,6 +968,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } } c = sub_shape->getCurve(); + lpe->pathvector_before_effect = c->get_pathvector(); bool success = false; // only run LPEs when the shape has a curve defined if (c) { @@ -977,6 +978,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { sub_shape->setCurveInsync( c, TRUE); + lpe->pathvector_after_effect = c->get_pathvector(); if (write) { gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 2aee041e5c..74e67a3d2f 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -253,7 +253,9 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: //if is not clip or mask or LPE apply to clip and mask if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { lpe->setCurrentShape(current); - lpe->pathvector_before_effect = curve->get_pathvector(); + if (!SP_IS_GROUP(this)) { + lpe->pathvector_before_effect = curve->get_pathvector(); + } // To Calculate BBox on shapes and nested LPE current->setCurveInsync(curve, true); // Groups have their doBeforeEffect called elsewhere @@ -273,10 +275,19 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: } return false; } - - lpe->pathvector_after_effect = curve->get_pathvector(); + + if (!SP_IS_GROUP(this)) { + // To have processed the shape to doAfterEffect + current->setCurveInsync(curve, true); + lpe->pathvector_after_effect = curve->get_pathvector(); lpe->doAfterEffect(this); + } else { + SPCurve * c = curve->copy(); + c->transform(i2anc_affine(current, this).inverse()); + // To have processed the shape to doAfterEffect + current->setCurveInsync(c, true); + c->unref(); } } } -- GitLab From 148d034746261a1ec99d7ab587d7253d7d8e4473 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Wed, 31 Jan 2018 20:15:57 +0100 Subject: [PATCH 35/57] Improve reprocess --- src/live_effects/effect.cpp | 1 + src/live_effects/effect.h | 1 + src/live_effects/lpe-mirror_symmetry.cpp | 16 ++++++++++------ src/object/sp-ellipse.cpp | 17 +++++++++++++++++ src/object/sp-item-group.cpp | 17 ++++++++++++++++- src/object/sp-lpe-item.cpp | 4 ++-- src/object/sp-path.cpp | 15 +++++++++++++++ 7 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index c46eef7fae..2c3c49c7c6 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -390,6 +390,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), + skip_reprocess(0), current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden defaultsopen(false), diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 19c8c6421d..d746471569 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -136,6 +136,7 @@ public: bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool is_load; bool upd_params; + guint skip_reprocess; BoolParam is_visible; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 3e65e62a7f..11cab86b7a 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -100,8 +100,9 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } + std::cout << "kkkkkkkkkk" << std::endl; + if (split_items && !discard_orig_path) { - std::cout << "kkkkkkkkkk" << std::endl; Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); m = m * sp_lpe_item->transform; @@ -157,7 +158,7 @@ LPEMirrorSymmetry::newWidget() void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - + std::cout << "starting" << std::endl; using namespace Geom; original_bbox(lpeitem, false, true); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); @@ -201,11 +202,14 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } else if ( mode == MT_FREE) { if (are_near(previous_center, (Geom::Point)center_point, 0.01)) { - center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); + center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point), true); + this->skip_reprocess++; } else { Geom::Point trans = center_point - Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); - start_point.param_setValue(start_point * trans); - end_point.param_setValue(end_point * trans); + start_point.param_setValue(start_point * trans, true); + end_point.param_setValue(end_point * trans, true); + this->skip_reprocess++; + this->skip_reprocess++; } std::cout << "lolololo" << std::endl; } else if ( mode == MT_V){ @@ -229,8 +233,8 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); } } - previous_center = center_point; + std::cout << "ending" << std::endl; } void diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 745c2b550a..1128c94708 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -18,6 +18,8 @@ #include #include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include <2geom/angle.h> #include <2geom/circle.h> @@ -631,6 +633,21 @@ void SPGenericEllipse::update_patheffect(bool write) if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ + if (hasPathEffect() && pathEffectsEnabled()) { + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + if (lpe->skip_reprocess) { + lpe->skip_reprocess--; + return; + } + } + } + } + } SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe, TRUE); this->resetClipPathAndMaskLPE(); diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index b7692ef96f..ed4b02e8e7 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -900,7 +900,22 @@ void SPGroup::update_patheffect(bool write) { #ifdef GROUP_VERBOSE g_message("sp_group_update_patheffect: %p\n", lpeitem); #endif - + if (hasPathEffect() && pathEffectsEnabled()) { + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + if (lpe->skip_reprocess) { + std::cout << lpe->skip_reprocess << "lpe->skip_reprocess" << std::endl; + lpe->skip_reprocess--; + return; + } + } + } + } + } std::vector const item_list = sp_item_group_item_list(this); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 74e67a3d2f..e7d82c1f14 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -279,14 +279,14 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: if (!SP_IS_GROUP(this)) { // To have processed the shape to doAfterEffect - current->setCurveInsync(curve, true); + current->setCurveInsync(curve, false); lpe->pathvector_after_effect = curve->get_pathvector(); lpe->doAfterEffect(this); } else { SPCurve * c = curve->copy(); c->transform(i2anc_affine(current, this).inverse()); // To have processed the shape to doAfterEffect - current->setCurveInsync(c, true); + current->setCurveInsync(c, false); c->unref(); } } diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index f7467c84b0..032f34b675 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -335,6 +335,21 @@ g_message("sp_path_update_patheffect"); if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ + if (hasPathEffect() && pathEffectsEnabled()) { + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + if (lpe->skip_reprocess) { + lpe->skip_reprocess--; + return; + } + } + } + } + } this->setCurveInsync(c_lpe, TRUE); this->resetClipPathAndMaskLPE(); bool success = false; -- GitLab From b204419e231ff67e9f191f0858a771f596ad9461 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 2 Feb 2018 01:23:10 +0100 Subject: [PATCH 36/57] Working on srop double runs --- src/live_effects/effect.cpp | 3 ++- src/live_effects/effect.h | 2 +- src/live_effects/lpe-mirror_symmetry.cpp | 11 ++++---- src/live_effects/parameter/array.h | 3 +-- src/live_effects/parameter/bool.cpp | 7 +++--- src/live_effects/parameter/hidden.cpp | 6 ++--- .../parameter/originalitemarray.cpp | 3 +-- .../parameter/originalpatharray.cpp | 3 +-- src/live_effects/parameter/parameter.cpp | 6 ++--- src/live_effects/parameter/point.cpp | 25 ++++++++----------- src/live_effects/parameter/random.cpp | 6 ++--- src/live_effects/parameter/text.cpp | 6 ++--- src/live_effects/parameter/togglebutton.cpp | 6 ++--- .../parameter/transformedpoint.cpp | 6 ++--- src/live_effects/parameter/vector.cpp | 6 ++--- src/object/sp-ellipse.cpp | 4 +-- src/object/sp-item-group.cpp | 4 +-- src/object/sp-lpe-item.cpp | 2 +- src/object/sp-path.cpp | 4 +-- src/ui/widget/selected-style.cpp | 2 +- 20 files changed, 46 insertions(+), 69 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 2c3c49c7c6..05d1c7b1b1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -390,7 +390,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - skip_reprocess(0), + skip_reprocess(false), current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden defaultsopen(false), @@ -550,6 +550,7 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); doOnApply(lpeitem); + this->skip_reprocess = 0; } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index d746471569..4c410a918e 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -136,7 +136,7 @@ public: bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool is_load; bool upd_params; - guint skip_reprocess; + bool skip_reprocess; BoolParam is_visible; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 11cab86b7a..be5c8743de 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -202,14 +202,13 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } else if ( mode == MT_FREE) { if (are_near(previous_center, (Geom::Point)center_point, 0.01)) { - center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point), true); - this->skip_reprocess++; + center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); + } else { Geom::Point trans = center_point - Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); - start_point.param_setValue(start_point * trans, true); - end_point.param_setValue(end_point * trans, true); - this->skip_reprocess++; - this->skip_reprocess++; + start_point.param_setValue(start_point * trans); + end_point.param_setValue(end_point * trans); + } std::cout << "lolololo" << std::endl; } else if ( mode == MT_V){ diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index c66d53266e..b5ee8b5cf5 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -64,8 +64,7 @@ public: virtual gchar * param_getSVGValue() const { Inkscape::SVGOStringStream os; writesvg(os, _vector); - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } virtual gchar * param_getDefaultSVGValue() const { diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 1a01f269be..909ec0a680 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -57,15 +57,13 @@ BoolParam::param_readSVGValue(const gchar * strvalue) gchar * BoolParam::param_getSVGValue() const { - gchar * str = g_strdup(value ? "true" : "false"); - return str; + return g_strdup(value ? "true" : "false"); } gchar * BoolParam::param_getDefaultSVGValue() const { - gchar * str = g_strdup(defvalue ? "true" : "false"); - return str; + return g_strdup(defvalue ? "true" : "false"); } Gtk::Widget * @@ -94,6 +92,7 @@ void BoolParam::param_setValue(bool newvalue) { if (value != newvalue) { + param_effect->skip_reprocess=1; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index e08881f6d4..5a21f572b5 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -55,8 +55,7 @@ HiddenParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -64,8 +63,7 @@ HiddenParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } Gtk::Widget * diff --git a/src/live_effects/parameter/originalitemarray.cpp b/src/live_effects/parameter/originalitemarray.cpp index fe2dc0c8d6..b89485e2db 100644 --- a/src/live_effects/parameter/originalitemarray.cpp +++ b/src/live_effects/parameter/originalitemarray.cpp @@ -438,8 +438,7 @@ gchar * OriginalItemArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->actived ? "1" : "0"); } - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * OriginalItemArrayParam::param_getDefaultSVGValue() const diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 769e7706df..928bf29766 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -524,8 +524,7 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0") << "," << ((*iter)->visibled ? "1" : "0"); } - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * OriginalPathArrayParam::param_getDefaultSVGValue() const diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 497113e032..fe6e49ac87 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -91,8 +91,7 @@ ScalarParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -100,8 +99,7 @@ ScalarParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 1e9097fcbb..cca64a4bec 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -95,9 +95,7 @@ PointParam::param_hide_knot(bool hide) { void PointParam::param_setValue(Geom::Point newpoint, bool write) { - if (*dynamic_cast( this ) == newpoint) { - return; - } + param_effect->skip_reprocess = true; *dynamic_cast( this ) = newpoint; if(write){ Inkscape::SVGOStringStream os; @@ -131,8 +129,7 @@ PointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << *dynamic_cast( this ); - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -140,8 +137,7 @@ PointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void @@ -215,10 +211,12 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or s = A; } } - pparam->param_setValue(s); - SPLPEItem * splpeitem = dynamic_cast(item); - if(splpeitem && this->pparam->liveupdate){ - sp_lpe_item_update_patheffect(splpeitem, true, true); + if(this->pparam->liveupdate){ + std::cout << "knot_set" << std::endl; + pparam->param_setValue(s, true); + pparam->param_effect->skip_reprocess = true; + } else { + pparam->param_setValue(s); } } @@ -234,10 +232,7 @@ PointParamKnotHolderEntity::knot_click(guint state) if (state & GDK_CONTROL_MASK) { if (state & GDK_MOD1_MASK) { this->pparam->param_set_default(); - SPLPEItem * splpeitem = dynamic_cast(item); - if(splpeitem){ - sp_lpe_item_update_patheffect(splpeitem, true, true); - } + pparam->param_setValue(*pparam,true); } } } diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index 4afa43c6ea..23912bedbe 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -67,8 +67,7 @@ RandomParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value << ';' << startseed; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -76,8 +75,7 @@ RandomParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue << ';' << defseed; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 7e56b2c758..37ae3a1d7c 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -112,8 +112,7 @@ TextParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -121,8 +120,7 @@ TextParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index e26884d6ad..bb9d9a90e0 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -55,15 +55,13 @@ ToggleButtonParam::param_readSVGValue(const gchar * strvalue) gchar * ToggleButtonParam::param_getSVGValue() const { - gchar * str = g_strdup(value ? "true" : "false"); - return str; + return g_strdup(value ? "true" : "false"); } gchar * ToggleButtonParam::param_getDefaultSVGValue() const { - gchar * str = g_strdup(defvalue ? "true" : "false"); - return str; + return g_strdup(defvalue ? "true" : "false"); } void diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index a010faf27c..ab66e72569 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -78,8 +78,7 @@ TransformedPointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -87,8 +86,7 @@ TransformedPointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp index ced93ef0de..1207a05da2 100644 --- a/src/live_effects/parameter/vector.cpp +++ b/src/live_effects/parameter/vector.cpp @@ -97,8 +97,7 @@ VectorParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -106,8 +105,7 @@ VectorParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } Gtk::Widget * diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 1128c94708..3307a24f0a 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -641,8 +641,8 @@ void SPGenericEllipse::update_patheffect(bool write) Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); if (lpe) { if (lpe->skip_reprocess) { - lpe->skip_reprocess--; - return; + //lpe->skip_reprocess--; + //return; } } } diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index ed4b02e8e7..a8960831ef 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -907,9 +907,9 @@ void SPGroup::update_patheffect(bool write) { if (lpeobj) { Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); if (lpe) { + std::cout << lpe->skip_reprocess << "lpe->skip_reprocessxxxxx" << std::endl; if (lpe->skip_reprocess) { - std::cout << lpe->skip_reprocess << "lpe->skip_reprocess" << std::endl; - lpe->skip_reprocess--; + lpe->skip_reprocess = false; return; } } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index e7d82c1f14..b6d662f9a4 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -494,7 +494,7 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) } // perform this once when the effect is applied - lpe->doOnApply(this); + lpe->doOnApply_impl(this); // indicate that all necessary preparations are done and the effect can be performed lpe->setReady(); diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 032f34b675..b787171dd3 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -343,8 +343,8 @@ g_message("sp_path_update_patheffect"); Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); if (lpe) { if (lpe->skip_reprocess) { - lpe->skip_reprocess--; - return; + //lpe->skip_reprocess--; + //return; } } } diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index d317fa216e..3988ca544f 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -109,7 +109,7 @@ typedef enum { // code, those warnings are actually desired. They say "Hey! Fix this". We // definitely don't want to hide/ignore them. --JonCruz static const GtkTargetEntry ui_drop_target_entries [] = { - {"application/x-color", 0, APP_X_COLOR} + {g_strdup("application/x-color"), 0, APP_X_COLOR} }; static guint nui_drop_target_entries = G_N_ELEMENTS(ui_drop_target_entries); -- GitLab From d57a24b335c9d5268fdc44a3c4c9842f713565a5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 3 Feb 2018 13:24:32 +0100 Subject: [PATCH 37/57] Working on dont duplicate LPE proceses --- src/live_effects/effect.cpp | 1 + src/live_effects/lpe-measure-segments.cpp | 11 ++++++----- src/live_effects/parameter/enum.h | 6 ++---- src/object/sp-ellipse.cpp | 15 --------------- src/object/sp-item-group.cpp | 9 +++++---- src/object/sp-path.cpp | 15 --------------- 6 files changed, 14 insertions(+), 43 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 05d1c7b1b1..948c667163 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -556,6 +556,7 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); + std::cout << "dobefore" << std::endl; doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 3558e50774..ce9bcb1968 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -46,10 +46,11 @@ using namespace Geom; namespace Inkscape { namespace LivePathEffect { -static const Util::EnumData OrientationMethodData[] = { - { OM_HORIZONTAL, N_("Horizontal"), "horizontal" }, - { OM_VERTICAL, N_("Vertical"), "vertical" }, - { OM_PARALLEL, N_("Parallel"), "parallel" } + +static const Util::EnumData OrientationMethodData[OM_END] = { + { OM_HORIZONTAL , N_("Horizontal"), "horizontal" }, + { OM_VERTICAL , N_("Vertical") , "vertical" }, + { OM_PARALLEL , N_("Parallel") , "parallel" } }; static const Util::EnumDataConverter OMConverter(OrientationMethodData, OM_END); @@ -203,7 +204,7 @@ LPEMeasureSegments::createArrowMarker(const char * mode) elemref = SP_OBJECT(document->getDefs()->appendChildRepr(arrow)); Inkscape::GC::release(arrow); } - items.push_back(mode); + items.push_back(g_strdup(mode)); } void diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h index ca237c0f74..82eaa6d433 100644 --- a/src/live_effects/parameter/enum.h +++ b/src/live_effects/parameter/enum.h @@ -61,13 +61,11 @@ public: return true; }; gchar * param_getSVGValue() const { - gchar * str = g_strdup( enumdataconv->get_key(value).c_str() ); - return str; + return g_strdup( enumdataconv->get_key(value).c_str() ); }; gchar * param_getDefaultSVGValue() const { - gchar * str = g_strdup( enumdataconv->get_key(defvalue).c_str() ); - return str; + return g_strdup( enumdataconv->get_key(defvalue).c_str() ); }; E get_value() const { diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 3307a24f0a..4a5c4a545e 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -633,21 +633,6 @@ void SPGenericEllipse::update_patheffect(bool write) if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - if (hasPathEffect() && pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (lpe) { - if (lpe->skip_reprocess) { - //lpe->skip_reprocess--; - //return; - } - } - } - } - } SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe, TRUE); this->resetClipPathAndMaskLPE(); diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index a8960831ef..033e45690e 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -920,10 +920,11 @@ void SPGroup::update_patheffect(bool write) { for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; - - SPLPEItem *lpe_item = dynamic_cast(sub_item); - if (lpe_item) { - lpe_item->update_patheffect(write); + if (sub_item) { + SPLPEItem *lpe_item = dynamic_cast(sub_item); + if (lpe_item) { + lpe_item->update_patheffect(write); + } } } diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index b787171dd3..f7467c84b0 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -335,21 +335,6 @@ g_message("sp_path_update_patheffect"); if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - if (hasPathEffect() && pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (lpe) { - if (lpe->skip_reprocess) { - //lpe->skip_reprocess--; - //return; - } - } - } - } - } this->setCurveInsync(c_lpe, TRUE); this->resetClipPathAndMaskLPE(); bool success = false; -- GitLab From d9b229f7121cf39d5e3c390a9c3b96807bfdb525 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 6 Feb 2018 23:53:04 +0100 Subject: [PATCH 38/57] Fixing meassure segment LPE --- src/live_effects/effect.cpp | 10 +- src/live_effects/effect.h | 2 +- src/live_effects/lpe-copy_rotate.cpp | 37 ++- src/live_effects/lpe-measure-segments.cpp | 349 +++++++++++++--------- src/live_effects/lpe-measure-segments.h | 26 +- src/live_effects/lpe-mirror_symmetry.cpp | 14 +- src/live_effects/lpe-mirror_symmetry.h | 2 + 7 files changed, 247 insertions(+), 193 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 948c667163..6601e33f84 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -86,7 +86,6 @@ #include #include - #include #include @@ -466,14 +465,14 @@ Effect::processObjects(LpeAction lpe_action) if (!document) { return; } - for (std::vector::iterator el_it = items.begin(); + for (std::vector::iterator el_it = items.begin(); el_it != items.end(); ++el_it) { - const char * id = *el_it; - if (!id) { + Glib::ustring id = *el_it; + if (id.empty()) { return; } SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { + if ((elemref = document->getObjectById(id.c_str()))) { Inkscape::XML::Node * elemnode = elemref->getRepr(); std::vector item_list; item_list.push_back(SP_ITEM(elemref)); @@ -533,7 +532,6 @@ Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) //Do nothing for simple effects } - void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) { is_load = false; diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 4c410a918e..7258970731 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -177,7 +177,7 @@ protected: bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. SPShape * current_shape; // these get stored in performPathEffects. - std::vector items; + std::vector items; double current_zoom; std::vector selectedNodesPoints; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 0f83479222..0ef4bad9a9 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -130,32 +130,37 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) if (numcopies_gap > 0 && num_copies != 0) { guint counter = num_copies - 1; while (numcopies_gap > 0) { - char * id = g_strdup((Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(this->lpeobj->getId())).c_str()); - if (!id || strlen(id) == 0) { + Glib::ustring id = Glib::ustring("rotated-"); + id += std::to_string(counter); + id += "-"; + id += this->lpeobj->getId(); + if (id.empty()) { return; } SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { + if (elemref = document->getObjectById(id.c_str())) { SP_ITEM(elemref)->setHidden(true); } counter++; numcopies_gap--; - g_free(id); } } previous_num_copies = num_copies; } SPObject *elemref = NULL; guint counter = 0; - char * id = g_strdup((Glib::ustring("rotated-0-").append(this->lpeobj->getId())).c_str()); - while((elemref = document->getObjectById(id))) { - id = g_strdup((Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(this->lpeobj->getId())).c_str()); + Glib::ustring id = "rotated-0-"; + id += this->lpeobj->getId(); + while((elemref = document->getObjectById(id.c_str()))) { + id = Glib::ustring("rotated-"); + id += std::to_string(counter); + id += "-"; + id += this->lpeobj->getId(); if (SP_ITEM(elemref)->isHidden()) { - items.push_back(g_strdup(id)); + items.push_back(id); } counter++; } - g_free(id); Geom::Affine m = Geom::Translate(-origin) * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))); for (size_t i = 1; i < num_copies; ++i) { Geom::Affine r = Geom::identity(); @@ -242,11 +247,14 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - char * elemref_id = g_strdup((Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(this->lpeobj->getId())).c_str()); - items.push_back(g_strdup(elemref_id)); + Glib::ustring elemref_id = Glib::ustring("rotated-"); + elemref_id += std::to_string(i); + elemref_id += "-"; + elemref_id += this->lpeobj->getId(); + items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id))) { + if (elemref = document->getObjectById(elemref_id.c_str())) { phantom = elemref->getRepr(); } else { phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); @@ -283,7 +291,7 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) attrs.push_back("ry"); attrs.push_back("width"); attrs.push_back("height"); - phantom->setAttribute("id", elemref_id); + phantom->setAttribute("id", elemref_id.c_str()); for(const char * attr : attrs) { phantom->setAttribute(attr, NULL); } @@ -299,12 +307,11 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) SP_ITEM(elemref)->setHidden(false); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id); + copy->setAttribute("id", elemref_id.c_str()); container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); } - g_free(elemref_id); } void diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index ce9bcb1968..98f789ac72 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -8,36 +8,40 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/lpe-measure-segments.h" -#include "live_effects/lpeobject.h" -#include -#include "ui/dialog/livepatheffect-editor.h" -#include -#include "inkscape.h" -#include "xml/node.h" -#include "xml/sp-css-attr.h" -#include "preferences.h" -#include "util/units.h" -#include "svg/svg-length.h" -#include "svg/svg-color.h" -#include "svg/stringstream.h" -#include "svg/svg.h" + +#include +#include "2geom/affine.h" +#include "2geom/angle.h" +#include "2geom/point.h" +#include "2geom/ray.h" #include "display/curve.h" #include "helper/geom.h" -#include "2geom/affine.h" -#include "path-chemistry.h" -#include "document.h" -#include "document-undo.h" -#include -#include - -#include "object/sp-root.h" +#include "live_effects/lpe-measure-segments.h" #include "object/sp-defs.h" #include "object/sp-item.h" -#include "object/sp-shape.h" #include "object/sp-path.h" +#include "object/sp-root.h" +#include "object/sp-shape.h" #include "object/sp-star.h" #include "object/sp-spiral.h" +#include "svg/stringstream.h" +#include "svg/svg.h" +#include "svg/svg-color.h" +#include "svg/svg-length.h" +#include "util/units.h" +#include "xml/node.h" +#include "xml/sp-css-attr.h" + +#include "document.h" +#include "document-undo.h" +#include "inkscape.h" +#include "preferences.h" +#include "path-chemistry.h" + +#include +#include +#include +#include // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -47,7 +51,7 @@ namespace Inkscape { namespace LivePathEffect { -static const Util::EnumData OrientationMethodData[OM_END] = { +static const Util::EnumData OrientationMethodData[] = { { OM_HORIZONTAL , N_("Horizontal"), "horizontal" }, { OM_VERTICAL , N_("Vertical") , "vertical" }, { OM_PARALLEL , N_("Parallel") , "parallel" } @@ -142,17 +146,20 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : star_ellipse_fix = Geom::identity(); locale_base = strdup(setlocale(LC_NUMERIC, NULL)); message.param_set_min_height(85); + previous_size = 0; } LPEMeasureSegments::~LPEMeasureSegments() {} void -LPEMeasureSegments::createArrowMarker(const char * mode) +LPEMeasureSegments::createArrowMarker(Glib::ustring mode) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); Glib::ustring style; gchar c[32]; unsigned const rgb24 = coloropacity.get_value() >> 8; @@ -164,7 +171,7 @@ LPEMeasureSegments::createArrowMarker(const char * mode) Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref = NULL; Inkscape::XML::Node *arrow = NULL; - if ((elemref = document->getObjectById(mode))) { + if ((elemref = document->getObjectById(mode.c_str()))) { Inkscape::XML::Node *arrow= elemref->getRepr(); if (arrow) { arrow->setAttribute("sodipodi:insensitive", "true"); @@ -177,9 +184,13 @@ LPEMeasureSegments::createArrowMarker(const char * mode) } } else { arrow = xml_doc->createElement("svg:marker"); - arrow->setAttribute("id", mode); - arrow->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows-marker")).c_str()); - arrow->setAttribute("inkscape:stockid", mode); + arrow->setAttribute("id", mode.c_str()); + Glib::ustring classarrow = itemid; + classarrow += " "; + classarrow += lpobjid; + classarrow += " measure-arrows-marker"; + arrow->setAttribute("class", classarrow.c_str()); + arrow->setAttribute("inkscape:stockid", mode.c_str()); arrow->setAttribute("orient", "auto"); arrow->setAttribute("refX", "0.0"); arrow->setAttribute("refY", "0.0"); @@ -187,24 +198,29 @@ LPEMeasureSegments::createArrowMarker(const char * mode) arrow->setAttribute("sodipodi:insensitive", "true"); /* Create */ Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path"); - if (std::strcmp(mode, "ArrowDIN-start") == 0) { + if (std::strcmp(mode.c_str(), "ArrowDIN-start") == 0) { arrow_path->setAttribute("d", "M -8,0 8,-2.11 8,2.11 z"); - } else if (std::strcmp(mode, "ArrowDIN-end") == 0) { + } else if (std::strcmp(mode.c_str(), "ArrowDIN-end") == 0) { arrow_path->setAttribute("d", "M 8,0 -8,2.11 -8,-2.11 z"); - } else if (std::strcmp(mode, "ArrowDINout-start") == 0) { + } else if (std::strcmp(mode.c_str(), "ArrowDINout-start") == 0) { arrow_path->setAttribute("d", "M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z"); } else { arrow_path->setAttribute("d", "M 0,0 16,-2.11 16,-0.5 26,-0.5 26,0.5 16,0.5 16,2.11 z"); } - arrow_path->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows")).c_str()); - arrow_path->setAttribute("id", Glib::ustring(mode).append("_path").c_str()); + Glib::ustring classarrowpath = itemid; + classarrowpath += " "; + classarrowpath += lpobjid; + classarrowpath += " measure-arrows"; + arrow_path->setAttribute("class", classarrowpath.c_str()); + Glib::ustring arrowpath = mode + Glib::ustring("_path"); + arrow_path->setAttribute("id", arrowpath.c_str()); arrow_path->setAttribute("style", style.c_str()); arrow->addChild(arrow_path, NULL); Inkscape::GC::release(arrow_path); elemref = SP_OBJECT(document->getDefs()->appendChildRepr(arrow)); Inkscape::GC::release(arrow); } - items.push_back(g_strdup(mode)); + items.push_back(mode); } void @@ -217,26 +233,18 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *rtext = NULL; double doc_w = document->getRoot()->width.value; - Geom::Scale scale = document->getDocumentScale(); - SPNamedView *nv = sp_document_namedview(document, NULL); - Glib::ustring display_unit = nv->display_units->abbr; - if (display_unit.empty()) { - display_unit = "px"; - } - //only check constrain viewbox on X - doc_scale = Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units ); - if( doc_scale > 0 ) { - doc_scale= 1.0/doc_scale; - } else { - doc_scale = 1.0; - } - char * id = g_strdup((Glib::ustring("text-on-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str()); + + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); + Glib::ustring id = Glib::ustring("text-on-"); + id += Glib::ustring::format(counter); + id += "-"; + id += lpobjid; SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; - if ((elemref = document->getObjectById(id))) { + if ((elemref = document->getObjectById(id.c_str()))) { if (remove) { elemref->deleteObject(); - g_free(id); return; } rtext = elemref->getRepr(); @@ -246,36 +254,22 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtext->setAttribute("transform", NULL); } else { if (remove) { - g_free(id); return; } rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); - rtext->setAttribute("id", id); - rtext->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-labels")).c_str()); + rtext->setAttribute("id", id.c_str()); + Glib::ustring classlabel = itemid; + classlabel += " "; + classlabel += lpobjid; + classlabel += " measure-labels"; + rtext->setAttribute("class", classlabel.c_str()); rtext->setAttribute("sodipodi:insensitive", "true"); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtspan = xml_doc->createElement("svg:tspan"); rtspan->setAttribute("sodipodi:role", "line"); } - gchar * transform; - Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); - angle = std::fmod(angle, 2*M_PI); - if (angle < 0) angle += 2*M_PI; - if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); - if (angle < 0) angle += 2*M_PI; - } - affine *= Geom::Rotate(angle); - affine *= Geom::Translate(pos); - if (rotate_anotation) { - transform = sp_svg_transform_write(affine); - } else { - transform = NULL; - } - rtext->setAttribute("transform", transform); - g_free(transform); SPCSSAttr *css = sp_repr_css_attr_new(); Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); gchar * fontbutton_str = fontbutton.param_getSVGValue(); @@ -299,7 +293,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Glib::ustring css_str; sp_repr_css_write_string(css,css_str); rtext->setAttribute("style", css_str.c_str()); - rtspan->setAttribute("style", NULL); + rtspan->setAttribute("style", css_str.c_str()); rtspan->setAttribute("transform", NULL); sp_repr_css_attr_unref (css); if (!elemref) { @@ -347,24 +341,47 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); - copy->setAttribute("id", id); + copy->setAttribute("id", id.c_str()); elemref = elemref_copy; } - items.push_back(g_strdup(id)); + SP_ITEM(elemref)->updateRepr(); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.15; + rtspan->setAttribute("style", NULL); + } + gchar * transform; + if (rotate_anotation) { + Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); + angle = std::fmod(angle, 2*M_PI); + if (angle < 0) angle += 2*M_PI; + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { + angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); + if (angle < 0) angle += 2*M_PI; + } + affine *= Geom::Rotate(angle); + affine *= Geom::Translate(pos); + transform = sp_svg_transform_write(affine); + } else { + transform = NULL; } - g_free(id); + rtext->setAttribute("transform", transform); + g_free(transform); } void -LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows) +LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); + Glib::ustring id = name; + id += Glib::ustring::format(counter); + id += "-"; + id += lpobjid; Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref = NULL; Inkscape::XML::Node *line = NULL; @@ -380,14 +397,9 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i std::abs(text_top_bottom) < fontsize/1.5 && hide_back) { - double k = 0; - if (flip_side) { - k = (Geom::distance(start,end)/2.0) + (anotation_width/10.0) - (anotation_width/2.0); - } else { - k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); - } + double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); if (Geom::distance(start,end) < anotation_width){ - if ((elemref = document->getObjectById(id))) { + if ((elemref = document->getObjectById(id.c_str()))) { if (remove) { elemref->deleteObject(); } @@ -409,7 +421,7 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i line_path.appendNew(end); line_pathv.push_back(line_path); } - if ((elemref = document->getObjectById(id))) { + if ((elemref = document->getObjectById(id.c_str()))) { if (remove) { elemref->deleteObject(); return; @@ -425,11 +437,19 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i return; } line = xml_doc->createElement("svg:path"); - line->setAttribute("id", id); + line->setAttribute("id", id.c_str()); if (main) { - line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-DIM-lines measure-lines")).c_str()); + Glib::ustring classlinedim = itemid; + classlinedim += " "; + classlinedim += lpobjid; + classlinedim += " measure-DIM-lines measure-lines"; + line->setAttribute("class", classlinedim.c_str()); } else { - line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-helper-lines measure-lines")).c_str()); + Glib::ustring classlinehelper = itemid; + classlinehelper += " "; + classlinehelper += lpobjid; + classlinehelper += " measure-helper-lines measure-lines"; + line->setAttribute("class", classlinehelper.c_str()); } gchar * line_str = sp_svg_write_path( line_pathv ); line->setAttribute("d" , line_str); @@ -476,9 +496,8 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); - copy->setAttribute("id", id); + copy->setAttribute("id", id.c_str()); } - items.push_back(g_strdup(id)); } void @@ -592,14 +611,29 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) SPShape *shape = dynamic_cast(splpeitem); if (shape) { - SPCurve * c = NULL; - - SPPath *path = dynamic_cast(shape); - if (path) { - c = path->get_curve_for_edit(); + //only check constrain viewbox on X + Geom::Scale scaledoc = document->getDocumentScale(); + SPNamedView *nv = sp_document_namedview(document, NULL); + display_unit = nv->display_units->abbr; + if (display_unit.empty()) { + display_unit = "px"; + } + doc_scale = Inkscape::Util::Quantity::convert( scaledoc[Geom::X], "px", display_unit.c_str() ); + if( doc_scale > 0 ) { + doc_scale= 1.0/doc_scale; } else { - c = shape->getCurve(); + doc_scale = 1.0; } + gint fix_overlaps_degree = fix_overlaps; + SPCurve * c = NULL; + gchar * fontbutton_str = fontbutton.param_getSVGValue(); + Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); + Pango::FontDescription fontdesc(fontdesc_ustring); + fontsize = fontdesc.get_size()/(double)Pango::SCALE; + fontsize *= document->getRoot()->c2p.inverse().expansionX(); + g_free(fontbutton_str); + fontsize *= document->getRoot()->c2p.inverse().expansionX(); + c = shape->getCurve(); Geom::Point start_stored; Geom::Point end_stored; Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem->parent), SP_OBJECT(document->getRoot())); @@ -620,9 +654,11 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) g_free(format_str); size_t ncurves = pathvector.curveCount(); items.clear(); + double start_angle_cross = 0; double end_angle_cross = 0; size_t counter = -1; + Glib::ustring lpobjid = this->lpeobj->getId(); for (size_t i = 0; i < pathvector.size(); i++) { for (size_t j = 0; j < pathvector[i].size(); j++) { counter++; @@ -642,9 +678,12 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else if (pathvector[i].size() > j + 1) { next = pathvector[i].pointAt(j+2); } - const char * idstart = (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); + Glib::ustring idstart = Glib::ustring("infoline-on-start-"); + idstart += Glib::ustring::format(counter); + idstart += "-"; + idstart += lpobjid; SPObject *elemref = NULL; - if (elemref = document->getObjectById(idstart)) { + if (elemref = document->getObjectById(idstart.c_str())) { SPPath* path = dynamic_cast(elemref); if (path) { SPCurve* startcurve = path->get_curve(); @@ -654,9 +693,12 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) startcurve->unref(); } } - const char * idend = (Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")) + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); + Glib::ustring idend = Glib::ustring("infoline-on-end-"); + idend += Glib::ustring::format(counter); + idend += "-"; + idend += lpobjid; elemref = NULL; - if (elemref = document->getObjectById(idend)) { + if (elemref = document->getObjectById(idend.c_str())) { SPPath* path = dynamic_cast(elemref); if (path) { SPCurve* endcurve = path->get_curve(); @@ -666,8 +708,42 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) endcurve->unref(); } } + Glib::ustring infoline_on_start = "infoline-on-start-"; + infoline_on_start += Glib::ustring::format(counter); + infoline_on_start += "-"; + infoline_on_start += lpobjid; + items.push_back(infoline_on_start); + Glib::ustring infoline_on_end = "infoline-on-end-"; + infoline_on_end += Glib::ustring::format(counter); + infoline_on_end += "-"; + infoline_on_end += lpobjid; + items.push_back(infoline_on_end); + Glib::ustring infoline = "infoline-"; + infoline += Glib::ustring::format(counter); + infoline += "-"; + infoline += lpobjid; + items.push_back(infoline); + Glib::ustring downline = "downline-"; + downline += Glib::ustring::format(counter); + downline += "-"; + downline += lpobjid; + items.push_back(downline); + Glib::ustring texton = "text-on-"; + texton += Glib::ustring::format(counter); + texton += "-"; + texton += lpobjid; + items.push_back(texton); + if (arrows_outside) { + items.push_back(Glib::ustring("ArrowDINout-start")); + items.push_back(Glib::ustring("ArrowDINout-end")); + } else { + items.push_back(Glib::ustring("ArrowDIN-start")); + items.push_back(Glib::ustring("ArrowDIN-end")); + } + if (Geom::are_near(start, start_stored, 0.01) && - Geom::are_near(end, end_stored, 0.01)) + Geom::are_near(end, end_stored, 0.01) && + !this->upd_params) { continue; } @@ -676,8 +752,8 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) bool remove = false; if (Geom::are_near(hstart, hend)) { remove = true; + fix_overlaps_degree = 180; } - if (orientation == OM_VERTICAL) { Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]); if (flip_side) { @@ -732,15 +808,15 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) start_angle_cross *= -1; //turn *= -1; } - if (fix_overlaps != 180 && start_angle_cross != 0) { + if (fix_overlaps_degree != 180 && start_angle_cross != 0) { double position_turned = position / sin(start_angle_cross/2.0); hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned); } else { hstart = hstart - Point::polar(angle_cross, position); } - createLine(start, hstart, (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), false, remove); + createLine(start, hstart, Glib::ustring("infoline-on-start-"), counter, false, remove); - if (fix_overlaps != 180 && end_angle_cross != 0) { + if (fix_overlaps_degree != 180 && end_angle_cross != 0) { double position_turned = position / sin(end_angle_cross/2.0); hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned); } else { @@ -749,23 +825,15 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) double length = Geom::distance(hstart,hend) * scale; Geom::Point pos = Geom::middle_point(hstart,hend); if (arrows_outside) { - createArrowMarker("ArrowDINout-start"); - createArrowMarker("ArrowDINout-end"); + createArrowMarker(Glib::ustring("ArrowDINout-start")); + createArrowMarker(Glib::ustring("ArrowDINout-end")); } else { - createArrowMarker("ArrowDIN-start"); - createArrowMarker("ArrowDIN-end"); + createArrowMarker(Glib::ustring("ArrowDIN-start")); + createArrowMarker(Glib::ustring("ArrowDIN-end")); } - //We get the font size to offset the text to the middle - gchar * fontbutton_str = fontbutton.param_getSVGValue(); - Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); - Pango::FontDescription fontdesc(fontdesc_ustring); - fontsize = fontdesc.get_size()/(double)Pango::SCALE; - fontsize *= document->getRoot()->c2p.inverse().expansionX(); - g_free(fontbutton_str); - fontsize *= document->getRoot()->c2p.inverse().expansionX(); - + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); + pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } else { pos = pos + Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } @@ -781,7 +849,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { createTextLabel(pos, counter, length, angle, remove, true); } - const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-")+ Glib::ustring(this->getRepr()->attribute("id"))).c_str(); arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); @@ -794,40 +861,32 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if(flip_side) { arrow_gap *= -1; } - createLine(end, hend,(Glib::ustring("infoline-on-end-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), false, remove); + createLine(end, hend, Glib::ustring("infoline-on-end-"), counter, false, remove); if (!arrows_outside) { hstart = hstart + Point::polar(angle, arrow_gap); hend = hend - Point::polar(angle, arrow_gap ); } if ((anotation_width/2) < Geom::distance(hstart,hend)/2.0) { - createLine(hstart, hend, (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, remove, true); + createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, remove, true); } else { - createLine(hstart, hend, (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); + createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, true, true); } } else { - const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); - createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-start-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-end-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - const char * id = (Glib::ustring("text-on-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { - elemref->deleteObject(); - } + createLine(Geom::Point(), Geom::Point(), Glib::ustring("downline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); } } } - for (size_t k = ncurves; k <= previous_size; k++) { - const char * downline = (Glib::ustring("downline-") + Glib::ustring::format(counter) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); - createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-start-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - createLine(Geom::Point(), Geom::Point(), (Glib::ustring("infoline-on-end-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(), true, true, true); - const char * id = (Glib::ustring("text-on-") + Glib::ustring::format(k) + Glib::ustring("-") + Glib::ustring(this->getRepr()->attribute("id"))).c_str(); - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { - elemref->deleteObject(); + if (previous_size) { + for (size_t counter = ncurves; counter <= previous_size; counter++) { + createLine(Geom::Point(), Geom::Point(), Glib::ustring("downline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); } } previous_size = ncurves; @@ -863,12 +922,6 @@ LPEMeasureSegments::transform_multiply(Geom::Affine const& postmul, bool set) } } -Geom::PathVector -LPEMeasureSegments::doEffect_path(Geom::PathVector const &path_in) -{ - return path_in; -} - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index 19a8d4700d..0c02a8ab4f 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -11,19 +11,16 @@ */ #include "live_effects/effect.h" -#include "ui/dialog/styledialog.h" - +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/colorpicker.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/fontbutton.h" +#include "live_effects/parameter/message.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/unit.h" -#include "live_effects/parameter/bool.h" -#include "live_effects/parameter/colorpicker.h" -#include "live_effects/parameter/message.h" -#include -#include <2geom/angle.h> -#include <2geom/ray.h> -#include <2geom/point.h> + namespace Inkscape { namespace LivePathEffect { @@ -39,16 +36,15 @@ class LPEMeasureSegments : public Effect { public: LPEMeasureSegments(LivePathEffectObject *lpeobject); virtual ~LPEMeasureSegments(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doOnApply(SPLPEItem const* lpeitem); - virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); - virtual void doEffect (SPCurve * curve){}; //stop the chain + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* /*lpeitem*/); + virtual void doEffect(SPCurve * curve){}; //stop the chain virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual void transform_multiply(Geom::Affine const& postmul, bool set); - virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); - void createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows = false); + void createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows = false); void createTextLabel(Geom::Point pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid); - void createArrowMarker(const char * mode); + void createArrowMarker(Glib::ustring mode); bool hasMeassure (size_t i); private: UnitParam unit; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index be5c8743de..b286dd6aee 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -15,8 +15,6 @@ */ #include -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -41,7 +39,7 @@ namespace Inkscape { namespace LivePathEffect { -static const Util::EnumData ModeTypeData[MT_END] = { +static const Util::EnumData ModeTypeData[] = { { MT_V, N_("Vertical Page Center"), "vertical" }, { MT_H, N_("Horizontal Page Center"), "horizontal" }, { MT_FREE, N_("Free from reflection line"), "free" }, @@ -292,12 +290,13 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - char * elemref_id = g_strdup((Glib::ustring("mirror-") + this->lpeobj->getId()).c_str()); + Glib::ustring elemref_id = Glib::ustring("mirror-"); + elemref_id += this->lpeobj->getId(); items.clear(); - items.push_back(g_strdup(elemref_id)); + items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id))) { + if ((elemref = document->getObjectById(elemref_id.c_str()))) { phantom = elemref->getRepr(); } else { phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); @@ -334,7 +333,7 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) attrs.push_back("ry"); attrs.push_back("width"); attrs.push_back("height"); - phantom->setAttribute("id", elemref_id); + phantom->setAttribute("id", elemref_id.c_str()); for(const char * attr : attrs) { phantom->setAttribute(attr, NULL); } @@ -354,7 +353,6 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) Inkscape::GC::release(copy); elemref->deleteObject(); } - g_free(elemref_id); } void diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 99a9cfc140..ce0b9ee85d 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,6 +17,8 @@ */ #include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" -- GitLab From b8d2e066de56f7f2155952b43d4c1356aa246ff4 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Fri, 9 Feb 2018 18:11:11 +0100 Subject: [PATCH 39/57] Force update color in meassure LPE --- src/live_effects/lpe-measure-segments.cpp | 14 +++++++++----- src/live_effects/lpe-measure-segments.h | 1 + src/live_effects/parameter/parameter.cpp | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 98f789ac72..1d4d6fbd72 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -162,7 +162,6 @@ LPEMeasureSegments::createArrowMarker(Glib::ustring mode) Glib::ustring itemid = sp_lpe_item->getId(); Glib::ustring style; gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); style = Glib::ustring("fill:") + Glib::ustring(c); Inkscape::SVGOStringStream os; @@ -280,7 +279,6 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng font_size << fontsize << "pt"; setlocale (LC_NUMERIC, locale_base); gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); sp_repr_css_set_property (css, "fill",c); Inkscape::SVGOStringStream os; @@ -476,7 +474,6 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring setlocale (LC_NUMERIC, locale_base); style = style + Glib::ustring("stroke-width:" + stroke_w.str()); gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); style = style + Glib::ustring(";stroke:") + Glib::ustring(c); Inkscape::SVGOStringStream os; @@ -624,6 +621,12 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { doc_scale = 1.0; } + unsigned const color = coloropacity.get_value() >> 8; + bool colorchanged = false; + if (color != rgb24) { + colorchanged = true; + } + rgb24 = color; gint fix_overlaps_degree = fix_overlaps; SPCurve * c = NULL; gchar * fontbutton_str = fontbutton.param_getSVGValue(); @@ -740,10 +743,11 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) items.push_back(Glib::ustring("ArrowDIN-start")); items.push_back(Glib::ustring("ArrowDIN-end")); } - + std::cout << this->upd_params << "this->upd_params" << std::endl; if (Geom::are_near(start, start_stored, 0.01) && Geom::are_near(end, end_stored, 0.01) && - !this->upd_params) + !this->upd_params && + !colorchanged) { continue; } diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index 0c02a8ab4f..1b6a5a81d7 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -74,6 +74,7 @@ private: double fontsize; double anotation_width; double previous_size; + unsigned rgb24; double arrow_gap; gchar const* locale_base; Geom::Affine star_ellipse_fix; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index fe6e49ac87..a7f1e8312e 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -127,6 +127,9 @@ ScalarParam::param_update_default(const gchar * default_value) void ScalarParam::param_set_value(gdouble val) { + if (value != newvalue) { + param_effect->upd_params = true; + } value = val; if (integer) value = round(value); -- GitLab From fb5a34e6dbc6e99c88ccbf216252eaea5171f775 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Fri, 9 Feb 2018 19:29:45 +0100 Subject: [PATCH 40/57] Fixing meassure segments --- src/live_effects/lpe-measure-segments.cpp | 35 +++++++++++------------ src/live_effects/parameter/parameter.cpp | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 1d4d6fbd72..131c60ad04 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -397,7 +397,7 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring { double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); if (Geom::distance(start,end) < anotation_width){ - if ((elemref = document->getObjectById(id.c_str()))) { + if (elemref = document->getObjectById(id.c_str())) { if (remove) { elemref->deleteObject(); } @@ -665,22 +665,22 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) for (size_t i = 0; i < pathvector.size(); i++) { for (size_t j = 0; j < pathvector[i].size(); j++) { counter++; - if(hasMeassure(counter + 1)) { - Geom::Point prev = Geom::Point(0,0); - if (j == 0 && pathvector[i].closed()) { - prev = pathvector.pointAt(pathvector[i].size() - 1); - } else if (j != 0) { - prev = pathvector[i].pointAt(j - 1); - } - Geom::Point start = pathvector[i].pointAt(j); - Geom::Point end = pathvector[i].pointAt(j + 1); - Geom::Point next = Geom::Point(0,0); - if(pathvector[i].closed() && pathvector[i].size() == j+1){ - end = pathvector[i].pointAt(0); - next = pathvector[i].pointAt(1); - } else if (pathvector[i].size() > j + 1) { - next = pathvector[i].pointAt(j+2); - } + Geom::Point prev = Geom::Point(0,0); + if (j == 0 && pathvector[i].closed()) { + prev = pathvector.pointAt(pathvector[i].size() - 1); + } else if (j != 0) { + prev = pathvector[i].pointAt(j - 1); + } + Geom::Point start = pathvector[i].pointAt(j); + Geom::Point end = pathvector[i].pointAt(j + 1); + Geom::Point next = Geom::Point(0,0); + if(pathvector[i].closed() && pathvector[i].size() == j+1){ + end = pathvector[i].pointAt(0); + next = pathvector[i].pointAt(1); + } else if (pathvector[i].size() > j + 1) { + next = pathvector[i].pointAt(j+2); + } + if(hasMeassure(counter)) { Glib::ustring idstart = Glib::ustring("infoline-on-start-"); idstart += Glib::ustring::format(counter); idstart += "-"; @@ -743,7 +743,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) items.push_back(Glib::ustring("ArrowDIN-start")); items.push_back(Glib::ustring("ArrowDIN-end")); } - std::cout << this->upd_params << "this->upd_params" << std::endl; if (Geom::are_near(start, start_stored, 0.01) && Geom::are_near(end, end_stored, 0.01) && !this->upd_params && diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a7f1e8312e..a175359f09 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -127,7 +127,7 @@ ScalarParam::param_update_default(const gchar * default_value) void ScalarParam::param_set_value(gdouble val) { - if (value != newvalue) { + if (value != val) { param_effect->upd_params = true; } value = val; -- GitLab From 065e3d66631bbd6bc8ecbe617d44ded64649af4f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 12 Feb 2018 00:12:12 +0100 Subject: [PATCH 41/57] Adding some recursive and LPE changes --- src/live_effects/effect.cpp | 47 ++--- src/live_effects/effect.h | 4 +- src/live_effects/lpe-bspline.cpp | 2 +- src/live_effects/lpe-copy_rotate.cpp | 87 ++++---- src/live_effects/lpe-copy_rotate.h | 3 +- src/live_effects/lpe-interpolate.cpp | 2 +- src/live_effects/lpe-measure-segments.cpp | 188 +++++++++++------- src/live_effects/lpe-mirror_symmetry.cpp | 103 ++++------ src/live_effects/lpe-mirror_symmetry.h | 3 +- src/live_effects/lpe-perp_bisector.cpp | 2 +- src/live_effects/lpe-powerclip.cpp | 18 +- src/live_effects/lpe-powerclip.h | 1 + src/live_effects/lpe-transform_2pts.cpp | 6 +- src/live_effects/lpegroupbbox.cpp | 2 +- src/live_effects/parameter/bool.cpp | 2 +- src/live_effects/parameter/colorpicker.cpp | 1 + src/live_effects/parameter/fontbutton.cpp | 1 + src/live_effects/parameter/hidden.cpp | 1 + src/live_effects/parameter/message.cpp | 1 + src/live_effects/parameter/parameter.cpp | 1 + src/live_effects/parameter/path.cpp | 1 + src/live_effects/parameter/point.cpp | 2 - src/live_effects/parameter/random.cpp | 1 + src/live_effects/parameter/text.cpp | 1 + src/live_effects/parameter/togglebutton.cpp | 1 + .../parameter/transformedpoint.cpp | 1 + src/object/box3d-side.cpp | 4 +- src/object/sp-conn-end-pair.cpp | 4 +- src/object/sp-ellipse.cpp | 10 +- src/object/sp-item-group.cpp | 4 +- src/object/sp-line.cpp | 2 +- src/object/sp-lpe-item.cpp | 77 +++++-- src/object/sp-lpe-item.h | 2 + src/object/sp-object.cpp | 1 - src/object/sp-offset.cpp | 4 +- src/object/sp-path.cpp | 89 +-------- src/object/sp-path.h | 30 +-- src/object/sp-rect.cpp | 4 +- src/object/sp-shape.cpp | 74 ++++--- src/object/sp-shape.h | 10 +- src/object/sp-spiral.cpp | 8 +- src/object/sp-star.cpp | 8 +- src/path-chemistry.cpp | 6 +- src/splivarot.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 21 +- src/ui/tools/connector-tool.cpp | 10 +- src/ui/tools/freehand-base.cpp | 2 +- 47 files changed, 430 insertions(+), 424 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 6601e33f84..b7694a8c77 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -554,7 +554,6 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - std::cout << "dobefore" << std::endl; doBeforeEffect(lpeitem); update_helperpath(); } @@ -816,29 +815,29 @@ Effect::defaultParamSet() if ((*it)->widget_is_visible) { has_params = true; Parameter * param = *it; - char * param_value_char = param->param_getSVGValue(); Glib::ustring * tip = param->param_getTooltip(); - const gchar * key = param->param_key.c_str(); - const gchar * value = param->param_label.c_str(); - gchar* defvalue = param->param_getDefaultSVGValue(); - Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + - effectkey + - (Glib::ustring)"/" + - (Glib::ustring)key; + const gchar * key = param->param_key.c_str(); + const gchar * label = param->param_label.c_str(); + Glib::ustring value = param->param_getSVGValue(); + Glib::ustring defvalue = param->param_getDefaultSVGValue(); + Glib::ustring pref_path = "/live_effects/"; + pref_path += effectkey; + pref_path +="/"; + pref_path += key; bool valid = prefs->getEntry(pref_path).isValid(); const gchar * set_or_upd; - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); if (valid) { set_or_upd = _("Update"); - def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); } else { set_or_upd = _("Set"); ove = Glib::ustring(_("Default value overridden: None\n")); } - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(param->param_getSVGValue()); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) ); - Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START)); + Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START)); parameter_label->set_use_markup(true); parameter_label->set_use_underline(true); Glib::ustring tooltip = Glib::ustring("") + parameter_label->get_text () + Glib::ustring("\n") + param->param_tooltip + Glib::ustring("\n\n"); @@ -847,9 +846,9 @@ Effect::defaultParamSet() vbox_param->pack_start(*parameter_label, true, true, 2); Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); - unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param_value_char, defvalue, parameter_label, set, unset)); + unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); - set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param_value_char, defvalue, parameter_label, set, unset)); + set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); if (!valid) { unset->set_sensitive(false); } @@ -857,8 +856,6 @@ Effect::defaultParamSet() vbox_param->pack_start(*unset, true, true, 2); vbox_expander->pack_start(*vbox_param, true, true, 2); - g_free(defvalue); - g_free(param_value_char); } ++it; } @@ -886,30 +883,30 @@ Effect::onDefaultsExpanderChanged(Gtk::Expander * expander) } void -Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(pref_path, (Glib::ustring)value); + prefs->setString(pref_path, value); gchar * label = _("Update"); set->set_label((Glib::ustring)label); unset->set_sensitive(true); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(value) + Glib::ustring("\n"); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + value + Glib::ustring("\n"); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } void -Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->remove(pref_path); gchar * label = _("Set"); set->set_label((Glib::ustring)label); unset->set_sensitive(false); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: None\n")); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) +value; parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 7258970731..7052f95259 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -183,8 +183,8 @@ protected: private: void onDefaultsExpanderChanged(Gtk::Expander * expander); - void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); - void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); bool provides_own_flash_paths; // if true, the standard flash path is suppressed bool is_ready; diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 6d1e0154b1..7834ff108b 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -167,7 +167,7 @@ void LPEBSpline::changeWeight(double weight_ammount) { SPPath *path = dynamic_cast(sp_lpe_item); if(path) { - SPCurve *curve = path->get_curve_for_edit(); + SPCurve *curve = path->getCurveForEdit(); doBSplineFromWidget(curve, weight_ammount/100.0); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 0ef4bad9a9..6bf2a78bd3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -56,7 +56,6 @@ pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const & return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; } - LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), method(_("Method:"), _("Rotate methods"), "method", RMConverter, &wr, this, RM_NORMAL), @@ -67,7 +66,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), gap(_("Gap"), _("Gap"), "gap", &wr, this, -0.0001), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, false), + mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, true), split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), dist_angle_handle(100.0) { @@ -192,7 +191,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } void -LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset) +LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -205,7 +204,7 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, transform, false, reset); + cloneD(*obj_it, dest_child, transform, reset); index++; } return; @@ -220,15 +219,11 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo path = SP_PATH(dest); } if (path && shape) { - SPCurve *c = NULL; - if (root) { - c = new SPCurve(); - c->set_pathvector(pathvector_after_effect); - } else { - c = shape->getCurve(); - } + SPCurve *c = shape->getCurve(); if (c) { - path->setCurve(c, TRUE); + gchar *str = sp_svg_write_path(c->get_pathvector()); + path->getRepr()->setAttribute("d", str); + g_free(str); c->unref(); } else { path->getRepr()->setAttribute("d", NULL); @@ -239,6 +234,33 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } } +Inkscape::XML::Node * +LPECopyRotate::createPathBase(SPObject *elemref) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return NULL; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Node *prev = elemref->getRepr(); + SPGroup *group = dynamic_cast(elemref); + if (group) { + Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); + container->setAttribute("transform", prev->attribute("transform")); + std::vector const item_list = sp_item_group_item_list(group); + Inkscape::XML::Node *previous = NULL; + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *sub_item = *iter; + Inkscape::XML::Node *resultnode = createPathBase(sub_item); + container->addChild(resultnode, previous); + previous = resultnode; + } + return container; + } + Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); + resultnode->setAttribute("transform", prev->attribute("transform")); + return resultnode; +} + void LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) { @@ -257,50 +279,15 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) if (elemref = document->getObjectById(elemref_id.c_str())) { phantom = elemref->getRepr(); } else { - phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); - std::vector attrs; - attrs.push_back("inkscape:path-effect"); - attrs.push_back("inkscape:original-d"); - attrs.push_back("sodipodi:type"); - attrs.push_back("sodipodi:rx"); - attrs.push_back("sodipodi:ry"); - attrs.push_back("sodipodi:cx"); - attrs.push_back("sodipodi:cy"); - attrs.push_back("sodipodi:end"); - attrs.push_back("sodipodi:start"); - attrs.push_back("inkscape:flatsided"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:rounded"); - attrs.push_back("sodipodi:arg1"); - attrs.push_back("sodipodi:arg2"); - attrs.push_back("sodipodi:r1"); - attrs.push_back("sodipodi:r2"); - attrs.push_back("sodipodi:sides"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("sodipodi:argument"); - attrs.push_back("sodipodi:expansion"); - attrs.push_back("sodipodi:radius"); - attrs.push_back("sodipodi:revolution"); - attrs.push_back("sodipodi:t0"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("x"); - attrs.push_back("y"); - attrs.push_back("rx"); - attrs.push_back("ry"); - attrs.push_back("width"); - attrs.push_back("height"); + phantom = createPathBase(sp_lpe_item); phantom->setAttribute("id", elemref_id.c_str()); - for(const char * attr : attrs) { - phantom->setAttribute(attr, NULL); - } + reset = true; } if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, true, reset); + cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, reset); gchar *str = sp_svg_transform_write(transform); elemref->getRepr()->setAttribute("transform" , str); g_free(str); diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index a0a3d4dc15..dcbd1c45eb 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,7 +48,8 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toItem(Geom::Affine transform, size_t i, bool reset); - void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset); + void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset); + Inkscape::XML::Node * createPathBase(SPObject *elemref); void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index 7bf2c50674..70bc92a27f 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -104,7 +104,7 @@ LPEInterpolate::resetDefaults(SPItem const* item) if (!SP_IS_PATH(item)) return; - SPCurve const *crv = SP_PATH(item)->get_curve_for_edit(true); + SPCurve const *crv = SP_PATH(item)->getCurveForEdit(true); Geom::PathVector const &pathv = crv->get_pathvector(); if ( (pathv.size() < 2) ) return; diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 131c60ad04..cff5aec4b8 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -149,7 +149,9 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : previous_size = 0; } -LPEMeasureSegments::~LPEMeasureSegments() {} +LPEMeasureSegments::~LPEMeasureSegments() { + doOnRemove(NULL); +} void LPEMeasureSegments::createArrowMarker(Glib::ustring mode) @@ -241,20 +243,15 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng id += lpobjid; SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; - if ((elemref = document->getObjectById(id.c_str()))) { - if (remove) { - elemref->deleteObject(); - return; - } + elemref = document->getObjectById(id.c_str()); + + if (elemref) { rtext = elemref->getRepr(); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtext->setAttribute("sodipodi:insensitive", "true"); rtext->setAttribute("transform", NULL); } else { - if (remove) { - return; - } rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); rtext->setAttribute("id", id.c_str()); @@ -288,6 +285,10 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtspan = rtext->firstChild(); } sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); + if (remove) { + sp_repr_css_set_property (css, "display","hidden"); + } + sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); Glib::ustring css_str; sp_repr_css_write_string(css,css_str); rtext->setAttribute("style", css_str.c_str()); @@ -338,7 +339,9 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - elemref->deleteObject(); + sp_object_ref(elemref, 0 ); + elemref->deleteObject(true); + sp_object_unref(elemref); copy->setAttribute("id", id.c_str()); elemref = elemref_copy; } @@ -380,8 +383,9 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring id += Glib::ustring::format(counter); id += "-"; id += lpobjid; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); - SPObject *elemref = NULL; + SPObject *elemref = document->getObjectById(id.c_str()); Inkscape::XML::Node *line = NULL; if (!main) { Geom::Ray ray(start, end); @@ -390,20 +394,13 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring end = end + Point::polar(angle, helpline_overlap ); } Geom::PathVector line_pathv; - + + double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); if (main && std::abs(text_top_bottom) < fontsize/1.5 && - hide_back) + hide_back && + k > 0) { - double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); - if (Geom::distance(start,end) < anotation_width){ - if (elemref = document->getObjectById(id.c_str())) { - if (remove) { - elemref->deleteObject(); - } - return; - } - } //k = std::max(k , arrow_gap -1); Geom::Ray ray(end, start); Geom::Coord angle = ray.angle(); @@ -419,11 +416,7 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring line_path.appendNew(end); line_pathv.push_back(line_path); } - if ((elemref = document->getObjectById(id.c_str()))) { - if (remove) { - elemref->deleteObject(); - return; - } + if (elemref) { line = elemref->getRepr(); gchar * line_str = sp_svg_write_path( line_pathv ); @@ -431,9 +424,6 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring line->setAttribute("transform", NULL); g_free(line_str); } else { - if (remove) { - return; - } line = xml_doc->createElement("svg:path"); line->setAttribute("id", id.c_str()); if (main) { @@ -453,32 +443,40 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring line->setAttribute("d" , line_str); g_free(line_str); } + line->setAttribute("sodipodi:insensitive", "true"); line_pathv.clear(); Glib::ustring style; + if (remove) { + style ="display:none;"; + } if (main) { line->setAttribute("inkscape:label", "dinline"); if (arrows_outside) { - style = style + Glib::ustring("marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"); + style += "marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"; } else { - style = style + Glib::ustring("marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"); + style += "marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"; } } else { line->setAttribute("inkscape:label", "dinhelpline"); } std::stringstream stroke_w; setlocale (LC_NUMERIC, "C"); + double stroke_width = Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); stroke_w << stroke_width; setlocale (LC_NUMERIC, locale_base); - style = style + Glib::ustring("stroke-width:" + stroke_w.str()); + style += "stroke-width:"; + style += stroke_w.str(); gchar c[32]; sprintf(c, "#%06x", rgb24); - style = style + Glib::ustring(";stroke:") + Glib::ustring(c); + style += ";stroke:"; + style += Glib::ustring(c); Inkscape::SVGOStringStream os; os << SP_RGBA32_A_F(coloropacity.get_value()); - style = style + Glib::ustring(";stroke-opacity:") + Glib::ustring(os.str()); + style += ";stroke-opacity:"; + style += os.str(); SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, style.c_str()); Glib::ustring css_str; @@ -492,7 +490,9 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - elemref->deleteObject(); + sp_object_ref(elemref, 0 ); + elemref->deleteObject(true); + sp_object_unref(elemref); copy->setAttribute("id", id.c_str()); } } @@ -627,7 +627,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) colorchanged = true; } rgb24 = color; - gint fix_overlaps_degree = fix_overlaps; SPCurve * c = NULL; gchar * fontbutton_str = fontbutton.param_getSVGValue(); Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); @@ -637,8 +636,10 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) g_free(fontbutton_str); fontsize *= document->getRoot()->c2p.inverse().expansionX(); c = shape->getCurve(); - Geom::Point start_stored; - Geom::Point end_stored; + Geom::Point prev_stored = Geom::Point(0,0); + Geom::Point start_stored = Geom::Point(0,0); + Geom::Point end_stored = Geom::Point(0,0); + Geom::Point next_stored = Geom::Point(0,0); Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem->parent), SP_OBJECT(document->getRoot())); Geom::PathVector pathvector = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); c->unref(); @@ -657,14 +658,15 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) g_free(format_str); size_t ncurves = pathvector.curveCount(); items.clear(); - double start_angle_cross = 0; double end_angle_cross = 0; - size_t counter = -1; + gint counter = -1; Glib::ustring lpobjid = this->lpeobj->getId(); + bool previous_fix_overlaps = true; for (size_t i = 0; i < pathvector.size(); i++) { for (size_t j = 0; j < pathvector[i].size(); j++) { counter++; + gint fix_overlaps_degree = fix_overlaps; Geom::Point prev = Geom::Point(0,0); if (j == 0 && pathvector[i].closed()) { prev = pathvector.pointAt(pathvector[i].size() - 1); @@ -680,16 +682,31 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else if (pathvector[i].size() > j + 1) { next = pathvector[i].pointAt(j+2); } - if(hasMeassure(counter)) { + if(hasMeassure(counter) && !Geom::are_near(start, end)) { + Glib::ustring idprev = Glib::ustring("infoline-on-start-"); + idprev += Glib::ustring::format(counter-1); + idprev += "-"; + idprev += lpobjid; + SPObject *elemref = NULL; + if (elemref = document->getObjectById(idprev.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* prevcurve = path->getCurve(); + if (prevcurve) { + prev_stored = *prevcurve->first_point(); + } + prevcurve->unref(); + } + } Glib::ustring idstart = Glib::ustring("infoline-on-start-"); idstart += Glib::ustring::format(counter); idstart += "-"; idstart += lpobjid; - SPObject *elemref = NULL; + elemref = NULL; if (elemref = document->getObjectById(idstart.c_str())) { SPPath* path = dynamic_cast(elemref); if (path) { - SPCurve* startcurve = path->get_curve(); + SPCurve* startcurve = path->getCurve(); if (startcurve) { start_stored = *startcurve->first_point(); } @@ -704,13 +721,28 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (elemref = document->getObjectById(idend.c_str())) { SPPath* path = dynamic_cast(elemref); if (path) { - SPCurve* endcurve = path->get_curve(); + SPCurve* endcurve = path->getCurve(); if (endcurve) { end_stored = *endcurve->first_point(); } endcurve->unref(); } } + Glib::ustring idnext = Glib::ustring("infoline-on-start-"); + idnext += Glib::ustring::format(counter+1); + idnext += "-"; + idnext += lpobjid; + elemref = NULL; + if (elemref = document->getObjectById(idnext.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* nextcurve = path->getCurve(); + if (nextcurve) { + next_stored = *nextcurve->first_point(); + } + nextcurve->unref(); + } + } Glib::ustring infoline_on_start = "infoline-on-start-"; infoline_on_start += Glib::ustring::format(counter); infoline_on_start += "-"; @@ -726,11 +758,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) infoline += "-"; infoline += lpobjid; items.push_back(infoline); - Glib::ustring downline = "downline-"; - downline += Glib::ustring::format(counter); - downline += "-"; - downline += lpobjid; - items.push_back(downline); Glib::ustring texton = "text-on-"; texton += Glib::ustring::format(counter); texton += "-"; @@ -743,7 +770,9 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) items.push_back(Glib::ustring("ArrowDIN-start")); items.push_back(Glib::ustring("ArrowDIN-end")); } - if (Geom::are_near(start, start_stored, 0.01) && + if ((Geom::are_near(prev, prev_stored, 0.01) && Geom::are_near(next, next_stored, 0.01) || + fix_overlaps_degree == 180) && + Geom::are_near(start, start_stored, 0.01) && Geom::are_near(end, end_stored, 0.01) && !this->upd_params && !colorchanged) @@ -753,10 +782,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Point hstart = start; Geom::Point hend = end; bool remove = false; - if (Geom::are_near(hstart, hend)) { - remove = true; - fix_overlaps_degree = 180; - } if (orientation == OM_VERTICAL) { Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]); if (flip_side) { @@ -785,16 +810,23 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (Geom::are_near(hstart[Geom::X], hend[Geom::X])) { remove = true; } - } else if (fix_overlaps != 180) { - start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps); + } else if (fix_overlaps_degree != 180) { + start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps_degree); if (prev == Geom::Point(0,0)) { start_angle_cross = 0; } - end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps); + end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps_degree); if (next == Geom::Point(0,0)) { end_angle_cross = 0; } } + if (remove) { + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); + continue; + } Geom::Ray ray(hstart,hend); Geom::Coord angle = ray.angle(); if (flip_side) { @@ -811,21 +843,32 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) start_angle_cross *= -1; //turn *= -1; } - if (fix_overlaps_degree != 180 && start_angle_cross != 0) { - double position_turned = position / sin(start_angle_cross/2.0); - hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned); + double position_turned_start = position / sin(start_angle_cross/2.0); + double length = Geom::distance(start,end); + if (fix_overlaps_degree != 180 && + start_angle_cross != 0 && + position_turned_start < length && + previous_fix_overlaps) + { + hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned_start); } else { hstart = hstart - Point::polar(angle_cross, position); } - createLine(start, hstart, Glib::ustring("infoline-on-start-"), counter, false, remove); - - if (fix_overlaps_degree != 180 && end_angle_cross != 0) { - double position_turned = position / sin(end_angle_cross/2.0); - hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned); + createLine(start, hstart, Glib::ustring("infoline-on-start-"), counter, false, false); + double position_turned_end = position / sin(end_angle_cross/2.0); + double endlength = Geom::distance(end,next); + if (fix_overlaps_degree != 180 && + end_angle_cross != 0 && + position_turned_end < length && + position_turned_end < endlength) + { + hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned_end); + previous_fix_overlaps = true; } else { hend = hend - Point::polar(angle_cross, position); + previous_fix_overlaps = false; } - double length = Geom::distance(hstart,hend) * scale; + length = Geom::distance(start,end) * scale; Geom::Point pos = Geom::middle_point(hstart,hend); if (arrows_outside) { createArrowMarker(Glib::ustring("ArrowDINout-start")); @@ -834,7 +877,6 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) createArrowMarker(Glib::ustring("ArrowDIN-start")); createArrowMarker(Glib::ustring("ArrowDIN-end")); } - if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } else { @@ -864,18 +906,17 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if(flip_side) { arrow_gap *= -1; } - createLine(end, hend, Glib::ustring("infoline-on-end-"), counter, false, remove); + createLine(end, hend, Glib::ustring("infoline-on-end-"), counter, false, false); if (!arrows_outside) { hstart = hstart + Point::polar(angle, arrow_gap); hend = hend - Point::polar(angle, arrow_gap ); } - if ((anotation_width/2) < Geom::distance(hstart,hend)/2.0) { - createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, remove, true); + if ((anotation_width/2.0) + arrow_gap < Geom::distance(hstart,hend)/2.0) { + createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, false, true); } else { createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, true, true); } } else { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("downline-"), counter, true, true, true); createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); @@ -884,8 +925,7 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } } if (previous_size) { - for (size_t counter = ncurves; counter <= previous_size; counter++) { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("downline-"), counter, true, true, true); + for (size_t counter = ncurves; counter < previous_size; counter++) { createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index b286dd6aee..1e62a98d51 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -49,6 +49,7 @@ static const Util::EnumData ModeTypeData[] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); + LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -98,7 +99,6 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) if (root_origin != root) { return; } - std::cout << "kkkkkkkkkk" << std::endl; if (split_items && !discard_orig_path) { Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); @@ -156,7 +156,6 @@ LPEMirrorSymmetry::newWidget() void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - std::cout << "starting" << std::endl; using namespace Geom; original_bbox(lpeitem, false, true); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); @@ -208,7 +207,6 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) end_point.param_setValue(end_point * trans); } - std::cout << "lolololo" << std::endl; } else if ( mode == MT_V){ SPDocument * document = SP_ACTIVE_DOCUMENT; if (document) { @@ -231,11 +229,10 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } previous_center = center_point; - std::cout << "ending" << std::endl; } void -LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool root, bool reset) +LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -248,33 +245,22 @@ LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool root, bool reset) for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, false, reset); + cloneD(*obj_it, dest_child, reset); index++; } return; } SPShape * shape = SP_SHAPE(orig); SPPath * path = SP_PATH(dest); - if (shape && !path) { - const char * id = dest->getId(); - Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); - dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); - dest->getRepr()->setAttribute("d", id); - path = SP_PATH(dest); - } if (path && shape) { - SPCurve *c = NULL; - if (root) { - c = new SPCurve(); - c->set_pathvector(pathvector_after_effect); - } else { - c = shape->getCurve(); - } + SPCurve *c = shape->getCurve(); if (c) { - path->setCurve(c, TRUE); + gchar *str = sp_svg_write_path(c->get_pathvector()); + dest->getRepr()->setAttribute("d", str); + g_free(str); c->unref(); } else { - path->getRepr()->setAttribute("d", NULL); + dest->getRepr()->setAttribute("d", NULL); } if (reset) { dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); @@ -282,6 +268,33 @@ LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool root, bool reset) } } +Inkscape::XML::Node * +LPEMirrorSymmetry::createPathBase(SPObject *elemref) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return NULL; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Node *prev = elemref->getRepr(); + SPGroup *group = dynamic_cast(elemref); + if (group) { + Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); + container->setAttribute("transform", prev->attribute("transform")); + std::vector const item_list = sp_item_group_item_list(group); + Inkscape::XML::Node *previous = NULL; + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *sub_item = *iter; + Inkscape::XML::Node *resultnode = createPathBase(sub_item); + container->addChild(resultnode, previous); + previous = resultnode; + } + return container; + } + Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); + resultnode->setAttribute("transform", prev->attribute("transform")); + return resultnode; +} + void LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) { @@ -294,55 +307,20 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) elemref_id += this->lpeobj->getId(); items.clear(); items.push_back(elemref_id); - SPObject *elemref= NULL; + SPObject *elemref = NULL; Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id.c_str()))) { + if (elemref = document->getObjectById(elemref_id.c_str())) { phantom = elemref->getRepr(); } else { - phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); - std::vector attrs; - attrs.push_back("inkscape:path-effect"); - attrs.push_back("inkscape:original-d"); - attrs.push_back("sodipodi:type"); - attrs.push_back("sodipodi:rx"); - attrs.push_back("sodipodi:ry"); - attrs.push_back("sodipodi:cx"); - attrs.push_back("sodipodi:cy"); - attrs.push_back("sodipodi:end"); - attrs.push_back("sodipodi:start"); - attrs.push_back("inkscape:flatsided"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:rounded"); - attrs.push_back("sodipodi:arg1"); - attrs.push_back("sodipodi:arg2"); - attrs.push_back("sodipodi:r1"); - attrs.push_back("sodipodi:r2"); - attrs.push_back("sodipodi:sides"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("sodipodi:argument"); - attrs.push_back("sodipodi:expansion"); - attrs.push_back("sodipodi:radius"); - attrs.push_back("sodipodi:revolution"); - attrs.push_back("sodipodi:t0"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("x"); - attrs.push_back("y"); - attrs.push_back("rx"); - attrs.push_back("ry"); - attrs.push_back("width"); - attrs.push_back("height"); + phantom = createPathBase(sp_lpe_item); phantom->setAttribute("id", elemref_id.c_str()); - for(const char * attr : attrs) { - phantom->setAttribute(attr, NULL); - } + reset = true; } if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneD(SP_OBJECT(sp_lpe_item), elemref, true, reset); + cloneD(SP_OBJECT(sp_lpe_item), elemref, reset); gchar *str = sp_svg_transform_write(transform); elemref->getRepr()->setAttribute("transform" , str); g_free(str); @@ -355,6 +333,7 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) } } + void LPEMirrorSymmetry::resetStyles(){ reset = true; diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index ce0b9ee85d..d2d04c2059 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -50,7 +50,8 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toMirror(Geom::Affine transform, bool reset); - void cloneD(SPObject *orig, SPObject *dest, bool root, bool reset); + void cloneD(SPObject *orig, SPObject *dest, bool reset); + Inkscape::XML::Node * createPathBase(SPObject *elemref); void resetStyles(); protected: diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index 0458bd30df..afaa6b9ca5 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -113,7 +113,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) { /* make the path a straight line */ /** - SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? + SPCurve* curve = sp_path_getCurveForEdit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? Geom::Point A(curve->first_point()); Geom::Point B(curve->last_point()); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 13e507ef01..22fd3a3f56 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -168,6 +168,13 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ } } +void +LPEPowerClip::doAfterEffect (SPLPEItem const* lpeitem){ + if (!hide_clip && flatten && isVisible()) { + SP_ITEM(sp_lpe_item)->clip_ref->detach(); + } +} + void LPEPowerClip::addInverse (SPItem * clip_data){ gchar * is_inverse_str = is_inverse.param_getSVGValue(); @@ -193,7 +200,10 @@ LPEPowerClip::addInverse (SPItem * clip_data){ c->set_pathvector(c_pv); SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); - is_inverse.param_setValue((Glib::ustring)"true", true); + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if (strcmp(is_inverse_str, "true") != 0) { + is_inverse.param_setValue((Glib::ustring)"true", true); + } SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -232,7 +242,10 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ c->set_pathvector(c_pv); SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); - is_inverse.param_setValue((Glib::ustring)"false", true); + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if (strcmp(is_inverse_str, "false") != 0) { + is_inverse.param_setValue((Glib::ustring)"false", true); + } SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -331,7 +344,6 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ flattenClip(SP_ITEM(clip_data), path_out); } } - SP_ITEM(sp_lpe_item)->clip_ref->detach(); } return path_out; } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 6f99d220f6..240a1809b3 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -23,6 +23,7 @@ public: virtual Gtk::Widget * newWidget(); //virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 4c41ea5201..47f8864ce3 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -95,7 +95,7 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_curve_for_edit()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(!pathvector.empty()) { point_a = pathvector.initialPoint(); @@ -127,7 +127,7 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_curve_for_edit()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(from_original_width_toggler != from_original_width) { from_original_width_toggler = from_original_width; @@ -183,7 +183,7 @@ LPETransform2Pts::updateIndex() SPLPEItem * splpeitem = const_cast(sp_lpe_item); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_curve_for_edit()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(pathvector.empty()) { return; diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 655d4088da..fbbd6ad1e8 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -66,7 +66,7 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo } Geom::OptRect bbox; - if (clipmask && 1>2) { + if (clipmask) { SPLPEItem * item = const_cast(lpeitem); bbox = getItemClipMaskBounds(item, transform); } else { diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 909ec0a680..c4f8e306be 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -92,7 +92,7 @@ void BoolParam::param_setValue(bool newvalue) { if (value != newvalue) { - param_effect->skip_reprocess=1; + param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/colorpicker.cpp b/src/live_effects/parameter/colorpicker.cpp index f6521d0c06..2e9c8c6f22 100644 --- a/src/live_effects/parameter/colorpicker.cpp +++ b/src/live_effects/parameter/colorpicker.cpp @@ -131,6 +131,7 @@ ColorPickerParam::param_newWidget() void ColorPickerParam::param_setValue(const guint32 newvalue) { + param_effect->skip_reprocess = true; value = newvalue; } diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp index 49edb850a3..f6f2d6f06d 100644 --- a/src/live_effects/parameter/fontbutton.cpp +++ b/src/live_effects/parameter/fontbutton.cpp @@ -83,6 +83,7 @@ void FontButtonParam::param_setValue(const Glib::ustring newvalue) { if (value != newvalue) { + param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 5a21f572b5..8c35cf142c 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -76,6 +76,7 @@ void HiddenParam::param_setValue(const Glib::ustring newvalue, bool write) { value = newvalue; + param_effect->skip_reprocess = true; if (write) { param_write_to_repr(value.c_str()); } diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 03eb2219f5..9ea80d3b8e 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -104,6 +104,7 @@ void MessageParam::param_setValue(const gchar * strvalue) { if (strcmp(strvalue, message) != 0) { + param_effect->skip_reprocess = true; param_effect->upd_params = true; } message = strvalue; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a175359f09..135b316047 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -129,6 +129,7 @@ ScalarParam::param_set_value(gdouble val) { if (value != val) { param_effect->upd_params = true; + param_effect->skip_reprocess = true; } value = val; if (integer) diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index ab385daa64..be7683f235 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -325,6 +325,7 @@ void PathParam::set_new_value (Geom::Piecewise > const & newpath, bool write_to_svg) { remove_link(); + param_effect->skip_reprocess = true; _pathvector = Geom::path_from_piecewise(newpath, LPE_CONVERSION_TOLERANCE); if (write_to_svg) { diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index cca64a4bec..f6ee79b413 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -212,9 +212,7 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or } } if(this->pparam->liveupdate){ - std::cout << "knot_set" << std::endl; pparam->param_setValue(s, true); - pparam->param_effect->skip_reprocess = true; } else { pparam->param_setValue(s); } diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index 23912bedbe..096788a3d0 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -102,6 +102,7 @@ void RandomParam::param_set_value(gdouble val, long newseed) { value = val; + param_effect->skip_reprocess = true; if (integer) value = round(value); if (value > max) diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 37ae3a1d7c..6da0bbf9f9 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -154,6 +154,7 @@ void TextParam::param_setValue(const Glib::ustring newvalue) { if (value != newvalue) { + param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index bb9d9a90e0..88d848a602 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -172,6 +172,7 @@ void ToggleButtonParam::param_setValue(bool newvalue) { if (value != newvalue) { + param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index ab66e72569..7342bd02ae 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -133,6 +133,7 @@ TransformedPointParam::param_newWidget() void TransformedPointParam::set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector) { + param_effect->skip_reprocess = true; setValues(new_origin, new_vector); gchar * str = param_getSVGValue(); param_write_to_repr(str); diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index af3703224b..3dcbe80f1d 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -194,14 +194,14 @@ void Box3DSide::set_shape() { /* Reset the this'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)*/ - this->setCurveInsync( c, TRUE); + this->setCurveInsync(c); if (hasPathEffect() && pathEffectsEnabled()) { SPCurve *c_lpe = c->copy(); bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); } diff --git a/src/object/sp-conn-end-pair.cpp b/src/object/sp-conn-end-pair.cpp index 33a8c0af94..1a0ec5d705 100644 --- a/src/object/sp-conn-end-pair.cpp +++ b/src/object/sp-conn-end-pair.cpp @@ -175,7 +175,7 @@ void SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const { void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { - SPCurve const *curve = _path->get_curve_for_edit(true); + SPCurve const *curve = _path->getCurveForEdit(true); SPItem *h2attItem[2] = {0}; getAttachedItems(h2attItem); Geom::Affine i2d = _path->i2doc_affine(); @@ -322,7 +322,7 @@ bool SPConnEndPair::reroutePathFromLibavoid() return false; } - SPCurve *curve = _path->get_curve(true); + SPCurve *curve = _path->getCurve(true); recreateCurve(curve, _connRef, _connCurvature); diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 4a5c4a545e..1b51a6fef8 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -422,7 +422,7 @@ void SPGenericEllipse::set_shape() // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync(cold, TRUE); + this->setCurveInsync(cold); cold->unref(); } @@ -490,7 +490,7 @@ void SPGenericEllipse::set_shape() /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ this->setCurveBeforeLPE(curve); - this->setCurveInsync(curve, TRUE); + this->setCurveInsync(curve); curve->unref(); return; } @@ -634,17 +634,17 @@ void SPGenericEllipse::update_patheffect(bool write) /* 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)*/ SPCurve * last = this->getCurve(); - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; if (hasPathEffect() && pathEffectsEnabled()) { success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); } else { - this->setCurveInsync(last, TRUE); + this->setCurveInsync(last); } } diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 033e45690e..25e4947e7f 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -993,10 +993,10 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - sub_shape->setCurveInsync( c, TRUE); + sub_shape->setCurveInsync(c); lpe->pathvector_after_effect = c->get_pathvector(); if (write) { - gchar *str = sp_svg_write_path(c->get_pathvector()); + gchar *str = sp_svg_write_path(lpe->pathvector_after_effect); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE g_message("sp_group_perform_patheffect writes 'd' attribute"); diff --git a/src/object/sp-line.cpp b/src/object/sp-line.cpp index 09ffd1f17d..2ba6339728 100644 --- a/src/object/sp-line.cpp +++ b/src/object/sp-line.cpp @@ -150,7 +150,7 @@ void SPLine::set_shape() { c->moveto(this->x1.computed, this->y1.computed); c->lineto(this->x2.computed, this->y2.computed); - this->setCurveInsync(c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update + this->setCurveInsync(c); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update this->setCurveBeforeLPE(c); // LPE's cannot be applied to lines. (the result can (generally) not be represented as SPLine) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index b6d662f9a4..8eec8e813f 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -257,7 +257,7 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: lpe->pathvector_before_effect = curve->get_pathvector(); } // To Calculate BBox on shapes and nested LPE - current->setCurveInsync(curve, true); + current->setCurveInsync(curve); // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); @@ -279,15 +279,8 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: if (!SP_IS_GROUP(this)) { // To have processed the shape to doAfterEffect - current->setCurveInsync(curve, false); lpe->pathvector_after_effect = curve->get_pathvector(); lpe->doAfterEffect(this); - } else { - SPCurve * c = curve->copy(); - c->transform(i2anc_affine(current, this).inverse()); - // To have processed the shape to doAfterEffect - current->setCurveInsync(c, false); - c->unref(); } } } @@ -646,6 +639,8 @@ bool SPLPEItem::hasBrokenPathEffect() const return false; } + + bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { if (path_effect_list->empty()) { @@ -668,6 +663,46 @@ bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const return false; } +/** + * returns true when any LPE apply to clip or mask. + */ +bool SPLPEItem::hasPathEffectOnClipOrMask(SPLPEItem * shape) const +{ + if (shape->hasPathEffectRecursive()) { + return true; + } + if (!path_effect_list || path_effect_list->empty()) { + return false; + } + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj) { + continue; + } + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe->apply_to_clippath_and_mask) { + return true; + } + } + return false; +} + +/** + * returns true when any LPE apply to clip or mask. + */ +bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const +{ + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (parent_lpe_item) { + return hasPathEffectOnClipOrMask(shape) || parent_lpe_item->hasPathEffectOnClipOrMaskRecursive(shape); + } + else { + return hasPathEffectOnClipOrMask(shape); + } +} + bool SPLPEItem::hasPathEffect() const { if (!path_effect_list || path_effect_list->empty()) { @@ -715,7 +750,10 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(false, true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(false, true)); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } } } } @@ -734,7 +772,10 @@ SPLPEItem::resetClipPathAndMaskLPE() } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(false, true), TRUE); + shape->setCurveInsync( shape->getCurveForEdit(false, true)); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } } } } @@ -805,21 +846,27 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa } } } - c = shape->getCurve(); + if (lpe) { //group + c = shape->getCurve(); + } else { + c = shape->getCurveForEdit(false, true); + //we ressurrect if the clip or mask has a allowed LPE + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } if (c) { bool success = false; try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); if (lpe) { - success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + success = this->performOnePathEffect(c, shape, lpe, true); } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + success = this->performPathEffect(c, shape, true); } c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); } else { if (lpe) { - success = this->performOnePathEffect(c, SP_SHAPE(clip_mask), lpe, true); + success = this->performOnePathEffect(c, shape, lpe, true); } else { success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); } @@ -834,7 +881,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa } Inkscape::XML::Node *repr = clip_mask->getRepr(); if (success && c) { - shape->setCurveInsync( c, TRUE); + shape->setCurveInsync(c); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 89491dc967..408879a08d 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -76,6 +76,8 @@ public: bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; + bool hasPathEffectOnClipOrMask(SPLPEItem * shape) const; + bool hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; diff --git a/src/object/sp-object.cpp b/src/object/sp-object.cpp index bc930a4304..d3c429c2a9 100644 --- a/src/object/sp-object.cpp +++ b/src/object/sp-object.cpp @@ -413,7 +413,6 @@ std::vector SPObject::childList(bool add_ref, Action) { l.push_back(&child); } return l; - } gchar const *SPObject::label() const { diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index 82e0b49476..2864e88cb9 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -361,7 +361,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c, TRUE); + this->setCurveInsync (c); this->setCurveBeforeLPE(c); c->unref(); @@ -669,7 +669,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c, TRUE); + this->setCurveInsync (c); this->setCurveBeforeLPE(c); c->unref(); diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 4eade916c6..81a0cda068 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -191,13 +191,14 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->set_curve_before_LPE(curve, TRUE, true); + this->setCurveBeforeLPE(curve); curve->unref(); } } else { - this->set_curve_before_LPE(NULL, TRUE, true); + this->setCurveBeforeLPE(NULL); + } - + sp_lpe_item_update_patheffect(this, true, true); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -334,13 +335,13 @@ g_message("sp_path_update_patheffect"); if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; if (hasPathEffect() && pathEffectsEnabled()) { success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); } @@ -360,84 +361,6 @@ g_message("sp_path_update_patheffect"); } } - -/** - * Adds a original_curve to the path. If owner is specified, a reference - * will be made, otherwise the curve will be copied into the path. - * Any existing curve in the path will be unreferenced first. - * This routine triggers reapplication of an effect if present - * and also triggers a request to update the display. Does not write - * result to XML when write=false. - */ -void SPPath::set_curve_before_LPE (SPCurve *new_curve, unsigned int owner, bool write) -{ - if (_curve_before_lpe) { - _curve_before_lpe = _curve_before_lpe->unref(); - } - - if (new_curve) { - if (owner) { - _curve_before_lpe = new_curve->ref(); - } else { - _curve_before_lpe = new_curve->copy(); - } - } - - sp_lpe_item_update_patheffect(this, true, write); - requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -/** - * Return duplicate of _curve (if any exists) or NULL if there is no curve - */ -SPCurve* SPPath::get_curve (bool reference) -{ - if (_curve) { - if (reference) { - return _curve; - } - return _curve->copy(); - } - return NULL; -} - - -/** - * Return duplicate of _curve_before_lpe (if any exists) or NULL if there is no curve - */ -SPCurve * SPPath::get_curve_before_LPE (bool reference, bool force) const -{ - if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { - if (reference) { - return _curve_before_lpe; - } - return _curve_before_lpe->copy(); - } - - return NULL; -} - -/** - * Return duplicate of edittable curve which is _curve_before_lpe if it exists or - * shape->curve if not. - */ -SPCurve* SPPath::get_curve_for_edit(bool reference, bool force) const -{ - if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { - if (reference) { - return _curve_before_lpe; - } - return _curve_before_lpe->copy(); - } - if (_curve) { - if (reference) { - return _curve; - } - return _curve->copy(); - } - return NULL; -} - /* Local Variables: mode:c++ diff --git a/src/object/sp-path.h b/src/object/sp-path.h index 24438bff06..0e8766f95e 100644 --- a/src/object/sp-path.h +++ b/src/object/sp-path.h @@ -29,33 +29,23 @@ class SPCurve; */ class SPPath : public SPShape { public: - SPPath(); - virtual ~SPPath(); + SPPath(); + virtual ~SPPath(); int nodesInPath() const; - - // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. - void set_curve_before_LPE (SPCurve *curve, unsigned int owner, bool write); - SPCurve* get_curve_before_LPE (bool reference = false, bool force = false) const; - SPCurve* get_curve_for_edit (bool reference = false, bool force = false) const; - -public: // should be made protected - SPCurve* get_curve(bool reference = false); friend class SPConnEndPair; - -public: SPConnEndPair connEndPair; - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void release(); - virtual void update(SPCtx* ctx, unsigned int flags); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual void release(); + virtual void update(SPCtx* ctx, unsigned int flags); - virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); - virtual const char* displayName() const; - virtual char* description() const; - virtual Geom::Affine set_transform(Geom::Affine const &transform); + virtual const char* displayName() const; + virtual char* description() const; + virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; virtual void update_patheffect(bool write); diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index 88dad5354f..52c08e29c3 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -198,7 +198,7 @@ const char* SPRect::displayName() const { void SPRect::set_shape() { if ((this->height.computed < 1e-18) || (this->width.computed < 1e-18)) { - this->setCurveInsync( NULL, TRUE); + this->setCurveInsync(NULL); this->setCurveBeforeLPE( NULL ); return; } @@ -265,7 +265,7 @@ void SPRect::set_shape() { } c->closepath(); - this->setCurveInsync(c, true); + this->setCurveInsync(c); this->setCurveBeforeLPE(c); // LPE is not applied because result can generally not be represented as SPRect diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 07860c0666..250a33eeb4 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -995,28 +995,53 @@ void SPShape::setCurve(SPCurve *new_curve, unsigned int owner) this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } + /** * Sets _curve_before_lpe to refer to the curve. */ void -SPShape::setCurveBeforeLPE (SPCurve *new_curve) +SPShape::setCurveBeforeLPE(SPCurve *new_curve, unsigned int owner) { if (_curve_before_lpe) { _curve_before_lpe = _curve_before_lpe->unref(); } if (new_curve) { - _curve_before_lpe = new_curve->ref(); + if (owner) { + _curve_before_lpe = new_curve->ref(); + } else { + _curve_before_lpe = new_curve->copy(); + } } } /** - * Return duplicate of curve (if any exists) or NULL if there is no curve + * Same as sp_shape_set_curve but without updating the display + */ +void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) +{ + if (_curve) { + _curve = _curve->unref(); + } + + if (new_curve) { + if (owner) { + _curve = new_curve->ref(); + } else { + _curve = new_curve->copy(); + } + } +} + + +/** + * Return curve (if any exists) or NULL if there is no curve +* if owner == 0 return a copy */ -SPCurve * SPShape::getCurve(bool reference) const +SPCurve * SPShape::getCurve(unsigned int owner) const { if (_curve) { - if(reference) { + if(owner) { return _curve; } return _curve->copy(); @@ -1026,12 +1051,15 @@ SPCurve * SPShape::getCurve(bool reference) const } /** - * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve + * Return curve *before* LPE (if any exists) or NULL if there is no curve + * If force is set allow return curve_before_lpe even if not + * has path effect like in clips and mask + * if owner == 0 return a copy */ -SPCurve * SPShape::getCurveBeforeLPE(bool reference, bool force) const +SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner, bool force) const { - if (hasPathEffectRecursive() && _curve_before_lpe) { - if (reference) { + if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (owner) { return _curve_before_lpe; } return _curve_before_lpe->copy(); @@ -1041,35 +1069,19 @@ SPCurve * SPShape::getCurveBeforeLPE(bool reference, bool force) const /** * Return curve for edit + * If force is set allow return curve_before_lpe even if not + * has path effect like in clips and mask + * if owner == 0 return a copy */ -SPCurve * SPShape::getCurveForEdit(bool reference, bool force) const +SPCurve * SPShape::getCurveForEdit(unsigned int owner, bool force) const { if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { - if (reference) { + if (owner) { return _curve_before_lpe; } return _curve_before_lpe->copy(); } - return getCurve(reference); -} - - -/** - * Same as sp_shape_set_curve but without updating the display - */ -void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) -{ - if (_curve) { - _curve = _curve->unref(); - } - - if (new_curve) { - if (owner) { - _curve = new_curve->ref(); - } else { - _curve = new_curve->copy(); - } - } + return getCurve(owner); } void SPShape::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const { diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index 2530cf500e..524888c118 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -39,12 +39,12 @@ public: SPShape(); virtual ~SPShape(); - SPCurve * getCurve (bool reference = false) const; - SPCurve * getCurveBeforeLPE (bool reference = false, bool force = false) const; - SPCurve * getCurveForEdit (bool reference = false, bool force = false) const; + SPCurve * getCurve (unsigned int owner = FALSE) const; + SPCurve * getCurveBeforeLPE (unsigned int owner = FALSE, bool force = FALSE) const; + SPCurve * getCurveForEdit (unsigned int owner = FALSE, bool force = FALSE) const; void setCurve (SPCurve *curve, unsigned int owner); - void setCurveInsync (SPCurve *curve, unsigned int owner); - void setCurveBeforeLPE (SPCurve *curve); + void setCurveBeforeLPE (SPCurve *new_curve, unsigned int owner = TRUE); + void setCurveInsync (SPCurve *curve, unsigned int owner = TRUE); int hasMarkers () const; int numberOfMarkers (int type) const; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index 45107c9160..4c620a55b7 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -201,13 +201,13 @@ void SPSpiral::update_patheffect(bool write) { if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; if (hasPathEffect() && pathEffectsEnabled()) { success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); } @@ -331,7 +331,7 @@ void SPSpiral::set_shape() { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync( cold, TRUE); + this->setCurveInsync(cold); this->setCurveBeforeLPE( cold ); cold->unref(); } @@ -389,7 +389,7 @@ void SPSpiral::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ this->setCurveBeforeLPE(c); - this->setCurveInsync(c, TRUE); + this->setCurveInsync(c); c->unref(); return; } diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 7480e00569..45be151213 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -228,13 +228,13 @@ void SPStar::update_patheffect(bool write) { if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; if (hasPathEffect() && pathEffectsEnabled()) { success = this->performPathEffect(c_lpe, SP_SHAPE(this)); if (success) { - this->setCurveInsync(c_lpe, TRUE); + this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); } @@ -388,7 +388,7 @@ void SPStar::set_shape() { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync( cold, TRUE); + this->setCurveInsync(cold); this->setCurveBeforeLPE(cold); cold->unref(); } @@ -471,7 +471,7 @@ void SPStar::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ this->setCurveBeforeLPE(c); - this->setCurveInsync(c, TRUE); + this->setCurveInsync(c); c->unref(); return; } diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 8efaa1f442..7d5346f317 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -123,7 +123,7 @@ ObjectSet::combine(bool skip_undo) did = true; } - SPCurve *c = path->get_curve_for_edit(); + SPCurve *c = path->getCurveForEdit(); if (first == NULL) { // this is the topmost path first = item; parent = first->getRepr()->parent(); @@ -225,7 +225,7 @@ ObjectSet::breakApart(bool skip_undo) continue; } - SPCurve *curve = path->get_curve_for_edit(); + SPCurve *curve = path->getCurveForEdit(); if (curve == NULL) { continue; } @@ -650,7 +650,7 @@ ObjectSet::pathReverse() did = true; - SPCurve *rcurve = path->get_curve_for_edit(true)->create_reverse(); + SPCurve *rcurve = path->getCurveForEdit(true)->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { diff --git a/src/splivarot.cpp b/src/splivarot.cpp index dd5534736f..4550b8144d 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2538,7 +2538,7 @@ SPCurve* curve_for_item(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { if (SP_IS_PATH(item)) { - curve = SP_PATH(item)->get_curve_for_edit(); + curve = SP_PATH(item)->getCurveForEdit(); } else { curve = SP_SHAPE(item)->getCurve(); } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 34cb42b6da..645df826be 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -190,7 +190,7 @@ void PathManipulator::writeXML() { if (!_live_outline) _updateOutline(); - if (!_live_objects) + if (_live_objects) _setGeometry(); if (!_path) return; @@ -1374,6 +1374,10 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) if (pathv.empty()) { return; } + + if (_spcurve->get_pathvector() == pathv) { + return; + } _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? @@ -1387,7 +1391,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } } } - if (_live_outline) _updateOutline(); if (_live_objects) @@ -1481,7 +1484,7 @@ void PathManipulator::_getGeometry() } } else { _spcurve->unref(); - _spcurve = _path->get_curve_for_edit(); + _spcurve = _path->getCurveForEdit(); // never allow NULL to sneak in here! if (_spcurve == NULL) { _spcurve = new SPCurve(); @@ -1493,7 +1496,6 @@ void PathManipulator::_getGeometry() void PathManipulator::_setGeometry() { using namespace Inkscape::LivePathEffect; - if (!_lpe_key.empty()) { // copied from nodepath.cpp // NOTE: if we are editing an LPE param, _path is not actually an SPPath, it is @@ -1501,17 +1503,22 @@ void PathManipulator::_setGeometry() Effect *lpe = LIVEPATHEFFECT(_path)->get_lpe(); if (lpe) { PathParam *pathparam = dynamic_cast(lpe->getParameter(_lpe_key.data())); + if (pathparam->get_pathvector() == _spcurve->get_pathvector()) { + return; //False we dont update LPE + } pathparam->set_new_value(_spcurve->get_pathvector(), false); LIVEPATHEFFECT(_path)->requestModified(SP_OBJECT_MODIFIED_FLAG); } } else { + // return true to leave the decission on empty to the caller. + // Maybe the path become empty and we want to update to empty if (empty()) return; - if (SPCurve * original = _path->get_curve_for_edit()){ + if (SPCurve * original = _path->getCurveBeforeLPE()){ if(!_spcurve->is_equal(original)) { - _path->set_curve_before_LPE(_spcurve, false, false); + _path->setCurveBeforeLPE(_spcurve); delete original; } - } else if(!_spcurve->is_equal(_path->get_curve(true))) { + } else if(!_spcurve->is_equal(_path->getCurve(true))) { _path->setCurve(_spcurve, false); } } diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index f4cf4ec1b4..20b309a98f 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -617,7 +617,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) Geom::Affine i2d ( (this->clickeditem)->i2dt_affine() ); Geom::Affine d2i = i2d.inverse(); SPPath *path = SP_PATH(this->clickeditem); - SPCurve *curve = path->get_curve(true); + SPCurve *curve = path->getCurve(true); if (this->clickedhandle == this->endpt_handle[0]) { Geom::Point o = this->endpt_handle[1]->pos; curve->stretch_endpoints(p * d2i, o * d2i); @@ -628,7 +628,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) sp_conn_reroute_path_immediate(path); // Copy this to the temporary visible path - this->red_curve = path->get_curve_for_edit(); + this->red_curve = path->getCurveForEdit(); this->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve, true); @@ -1041,7 +1041,7 @@ static gboolean endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool * } // Show the red path for dragging. - cc->red_curve = SP_PATH(cc->clickeditem)->get_curve_for_edit(); + cc->red_curve = SP_PATH(cc->clickeditem)->getCurveForEdit(); Geom::Affine i2d = (cc->clickeditem)->i2dt_affine(); cc->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve, true); @@ -1135,7 +1135,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { g_assert( SP_IS_PATH(item) ); - const SPCurve *curve = SP_PATH(item)->get_curve_for_edit(true); + const SPCurve *curve = SP_PATH(item)->getCurveForEdit(true); Geom::Affine i2dt = item->i2dt_affine(); if (this->active_conn == item) { @@ -1275,7 +1275,7 @@ static bool cc_item_is_shape(SPItem *item) bool cc_item_is_connector(SPItem *item) { if (SP_IS_PATH(item)) { - bool closed = SP_PATH(item)->get_curve_for_edit(true)->is_closed(); + bool closed = SP_PATH(item)->getCurveForEdit(true)->is_closed(); if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) { // To be considered a connector, an object must be a non-closed // path that is marked with a "inkscape:connector-type" attribute. diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 26d8123940..b57aa2fb03 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -645,7 +645,7 @@ static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/ // Curve list // We keep it in desktop coordinates to eliminate calculation errors - SPCurve *norm = SP_PATH(item)->get_curve_for_edit(); + SPCurve *norm = SP_PATH(item)->getCurveForEdit(); norm->transform((dc->white_item)->i2dt_affine()); g_return_if_fail( norm != NULL ); dc->white_curves = norm->split(); -- GitLab From 4884aaf38f7a2f83678339fdd08e4b59c3da237f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 12 Feb 2018 21:54:26 +0100 Subject: [PATCH 42/57] some fixes to recurse cleanup clip and mask --- src/object/sp-lpe-item.cpp | 40 ++++++++++++++++++++++++++++++-------- src/object/sp-lpe-item.h | 2 +- src/object/sp-path.cpp | 4 ++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 8eec8e813f..a277238689 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -259,7 +259,7 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: // To Calculate BBox on shapes and nested LPE current->setCurveInsync(curve); // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this)) { + if (!SP_IS_GROUP(this) && !is_clip_or_mask) { lpe->doBeforeEffect_impl(this); } @@ -474,8 +474,6 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) if( SP_IS_GENERICELLIPSE(this)) { SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); } - // make sure there is an original-d for paths!!! - sp_lpe_item_create_original_path_recursive(this); LivePathEffectObject *lpeobj = this->path_effect_list->back()->lpeobject; if (lpeobj && lpeobj->get_lpe()) { @@ -733,8 +731,30 @@ bool SPLPEItem::hasPathEffectRecursive() const } void -SPLPEItem::resetClipPathAndMaskLPE() +SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) { + if (fromrecurse) { + SPGroup* group = dynamic_cast(this); + SPShape* shape = dynamic_cast(this); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(true); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit(false, true)); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); + } + } + return; + } SPClipPath *clip_path = this->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); @@ -746,13 +766,16 @@ SPLPEItem::resetClipPathAndMaskLPE() for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { SPLPEItem * subitem = dynamic_cast(*iter2); if (subitem) { - subitem->resetClipPathAndMaskLPE(); + subitem->resetClipPathAndMaskLPE(true); } } } else if (shape) { shape->setCurveInsync( shape->getCurveForEdit(false, true)); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); } } } @@ -768,13 +791,16 @@ SPLPEItem::resetClipPathAndMaskLPE() for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { SPLPEItem * subitem = dynamic_cast(*iter2); if (subitem) { - subitem->resetClipPathAndMaskLPE(); + subitem->resetClipPathAndMaskLPE(true); } } } else if (shape) { shape->setCurveInsync( shape->getCurveForEdit(false, true)); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); } } } @@ -850,8 +876,6 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa c = shape->getCurve(); } else { c = shape->getCurveForEdit(false, true); - //we ressurrect if the clip or mask has a allowed LPE - shape->getRepr()->setAttribute("inkscape:original-d", NULL); } if (c) { bool success = false; diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 408879a08d..0e6049d4e6 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -94,7 +94,7 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void resetClipPathAndMaskLPE(); + void resetClipPathAndMaskLPE(bool fromrecurse = false); void applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); void applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 81a0cda068..1c2c4b61d5 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -335,6 +335,7 @@ g_message("sp_path_update_patheffect"); if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ + SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; @@ -344,6 +345,8 @@ g_message("sp_path_update_patheffect"); this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); + } else { + this->setCurveInsync(last); } } @@ -357,6 +360,7 @@ g_message("sp_path_update_patheffect"); } } c_lpe->unref(); + last->unref(); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } -- GitLab From 0a9256ae40a1159329c1e3ada2be92277f6a2509 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 13 Feb 2018 02:00:42 +0100 Subject: [PATCH 43/57] Simpifi bounding clip and mask --- src/live_effects/lpegroupbbox.cpp | 28 +++++++++++----------------- src/live_effects/lpegroupbbox.h | 8 ++++---- src/object/sp-ellipse.cpp | 4 ---- src/object/sp-lpe-item.cpp | 2 ++ src/object/sp-path.cpp | 4 ---- 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index fbbd6ad1e8..984bcf8209 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -28,33 +28,29 @@ namespace LivePathEffect { */ Geom::OptRect -GroupBBoxEffect::getItemClipMaskBounds(SPLPEItem* item, Geom::Affine transform) { +GroupBBoxEffect::clip_mask_bbox(SPLPEItem *item, Geom::Affine transform) +{ Geom::OptRect bbox; - SPClipPath *clip_path = item->clip_ref->getObject(); + SPClipPath * clip_path = item->clip_ref->getObject(); if(clip_path) { - //clip path dont need visualbouds use geometrical bbox.unionWith(clip_path->geometricBounds(transform)); } - - SPMask *mask_path = item->mask_ref->getObject(); + SPMask * mask_path = item->mask_ref->getObject(); if(mask_path) { bbox.unionWith(mask_path->geometricBounds(transform)); } SPGroup * group = dynamic_cast(item); - SPShape * shape = dynamic_cast(item); if (group) { - std::vector item_list = sp_item_group_item_list(group); + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPLPEItem *subitem = dynamic_cast(*iter); - bbox.unionWith(getItemClipMaskBounds(subitem, group->transform * transform)); + SPLPEItem * subitem = dynamic_cast(*iter); + bbox.unionWith(clip_mask_bbox(subitem, transform)); } - } else if (shape) { - bbox.unionWith(item->geometricBounds(shape->transform * transform)); } return bbox; } -void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, bool clipmask) +void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, bool clip_mask) { // Get item bounding box Geom::Affine transform; @@ -65,12 +61,10 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo transform = Geom::identity(); } - Geom::OptRect bbox; - if (clipmask) { + Geom::OptRect bbox = lpeitem->geometricBounds(transform); + if (clip_mask) { SPLPEItem * item = const_cast(lpeitem); - bbox = getItemClipMaskBounds(item, transform); - } else { - bbox = lpeitem->geometricBounds(transform); + bbox.unionWith(clip_mask_bbox(item, transform)); } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; diff --git a/src/live_effects/lpegroupbbox.h b/src/live_effects/lpegroupbbox.h index a49c32c68e..de20138c93 100644 --- a/src/live_effects/lpegroupbbox.h +++ b/src/live_effects/lpegroupbbox.h @@ -18,13 +18,13 @@ namespace LivePathEffect { class GroupBBoxEffect { protected: - // Bounding box of the item the path effect is applied on + // Bounding box of the item the path effect is applied on Geom::Interval boundingbox_X; Geom::Interval boundingbox_Y; - //This sets boundingbox_X and boundingbox_Y - Geom::OptRect getItemClipMaskBounds(SPLPEItem* item, Geom::Affine transform); - void original_bbox(SPLPEItem const* lpeitem, bool absolute = false, bool clipmask = false); + //This sets boundingbox_X and boundingbox_Y + Geom::OptRect clip_mask_bbox(SPLPEItem * item, Geom::Affine transform); + void original_bbox(SPLPEItem const* lpeitem, bool absolute = false, bool clip_mask = false); }; }; //namespace LivePathEffect diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 1b51a6fef8..f75c641b83 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -633,7 +633,6 @@ void SPGenericEllipse::update_patheffect(bool write) if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; @@ -643,8 +642,6 @@ void SPGenericEllipse::update_patheffect(bool write) this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); - } else { - this->setCurveInsync(last); } } @@ -658,7 +655,6 @@ void SPGenericEllipse::update_patheffect(bool write) } } c_lpe->unref(); - last->unref(); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index a277238689..dcb3410860 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -474,6 +474,8 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) if( SP_IS_GENERICELLIPSE(this)) { SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); } + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(this); LivePathEffectObject *lpeobj = this->path_effect_list->back()->lpeobject; if (lpeobj && lpeobj->get_lpe()) { diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 1c2c4b61d5..81a0cda068 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -335,7 +335,6 @@ g_message("sp_path_update_patheffect"); if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { /* 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)*/ - SPCurve * last = this->getCurve(); this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; @@ -345,8 +344,6 @@ g_message("sp_path_update_patheffect"); this->setCurveInsync(c_lpe); this->applyToClipPath(this); this->applyToMask(this); - } else { - this->setCurveInsync(last); } } @@ -360,7 +357,6 @@ g_message("sp_path_update_patheffect"); } } c_lpe->unref(); - last->unref(); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } -- GitLab From 230ca7177d355dd8ab5e8cdbf2919870f7aa9406 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 14 Feb 2018 01:17:44 +0100 Subject: [PATCH 44/57] fixing clip and mask clipaths --- src/live_effects/lpe-bendpath.cpp | 2 +- src/live_effects/lpegroupbbox.cpp | 10 ++++++---- src/object/sp-clippath.cpp | 6 ++---- src/object/sp-item-group.cpp | 2 +- src/object/sp-mask.cpp | 3 +-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 4ff900cc05..b5dc2d25a0 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -170,7 +170,7 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - if (sp_lpe_item) { //Check is object + if (sp_lpe_item && !postmul.isTranslation()) { //Check is object sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } } diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 984bcf8209..232a61617e 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -5,12 +5,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "document.h" #include "live_effects/lpegroupbbox.h" #include "object/sp-clippath.h" #include "object/sp-mask.h" +#include "object/sp-root.h" #include "object/sp-shape.h" #include "object/sp-item-group.h" - #include "object/sp-lpe-item.h" namespace Inkscape { @@ -31,20 +32,21 @@ Geom::OptRect GroupBBoxEffect::clip_mask_bbox(SPLPEItem *item, Geom::Affine transform) { Geom::OptRect bbox; + Geom::Affine affine = transform * item->transform; SPClipPath * clip_path = item->clip_ref->getObject(); if(clip_path) { - bbox.unionWith(clip_path->geometricBounds(transform)); + bbox.unionWith(clip_path->geometricBounds(affine)); } SPMask * mask_path = item->mask_ref->getObject(); if(mask_path) { - bbox.unionWith(mask_path->geometricBounds(transform)); + bbox.unionWith(mask_path->visualBounds(affine)); } SPGroup * group = dynamic_cast(item); if (group) { std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPLPEItem * subitem = dynamic_cast(*iter); - bbox.unionWith(clip_mask_bbox(subitem, transform)); + bbox.unionWith(clip_mask_bbox(subitem, affine)); } } return bbox; diff --git a/src/object/sp-clippath.cpp b/src/object/sp-clippath.cpp index 4f69bd0262..4afbf7e510 100644 --- a/src/object/sp-clippath.cpp +++ b/src/object/sp-clippath.cpp @@ -238,14 +238,12 @@ void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox) { Geom::OptRect SPClipPath::geometricBounds(Geom::Affine const &transform) { Geom::OptRect bbox; - for (auto& i: children) { if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); - bbox.unionWith(tmp); + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(transform); + bbox.unionWith(tmp); } } - return bbox; } diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 25e4947e7f..d2d666a90a 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -984,10 +984,10 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } } c = sub_shape->getCurve(); - lpe->pathvector_before_effect = c->get_pathvector(); bool success = false; // only run LPEs when the shape has a curve defined if (c) { + lpe->pathvector_before_effect = c->get_pathvector(); c->transform(i2anc_affine(sub_item, top_group)); success = top_group->performOnePathEffect(c, sub_shape, lpe); c->transform(i2anc_affine(sub_item, top_group).inverse()); diff --git a/src/object/sp-mask.cpp b/src/object/sp-mask.cpp index 7d3a7fcc5a..2e764131c2 100644 --- a/src/object/sp-mask.cpp +++ b/src/object/sp-mask.cpp @@ -132,10 +132,9 @@ SPMask::geometricBounds(Geom::Affine const &transform) { Geom::OptRect SPMask::visualBounds(Geom::Affine const &transform) { Geom::OptRect bbox; - for (auto& i: children) { if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->visualBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); + Geom::OptRect tmp = SP_ITEM(&i)->visualBounds(transform); bbox.unionWith(tmp); } } -- GitLab From e0c26b8cfe61f0fe2131abaf3c59b0fb3325a382 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 14 Feb 2018 23:50:46 +0100 Subject: [PATCH 45/57] Fixes to LPE when transforming --- src/live_effects/effect.cpp | 2 -- src/live_effects/effect.h | 1 - src/live_effects/lpegroupbbox.cpp | 2 +- src/live_effects/parameter/bool.cpp | 1 - src/live_effects/parameter/colorpicker.cpp | 1 - src/live_effects/parameter/fontbutton.cpp | 1 - src/live_effects/parameter/hidden.cpp | 1 - src/live_effects/parameter/message.cpp | 1 - src/live_effects/parameter/parameter.cpp | 1 - src/live_effects/parameter/path.cpp | 1 - src/live_effects/parameter/point.cpp | 1 - src/live_effects/parameter/random.cpp | 1 - src/live_effects/parameter/text.cpp | 1 - src/live_effects/parameter/togglebutton.cpp | 1 - src/live_effects/parameter/transformedpoint.cpp | 1 - src/object/sp-item-group.cpp | 16 ---------------- src/object/sp-lpe-item.cpp | 13 +++++-------- 17 files changed, 6 insertions(+), 40 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index b7694a8c77..4cdd8148ee 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -389,7 +389,6 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - skip_reprocess(false), current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden defaultsopen(false), @@ -548,7 +547,6 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); doOnApply(lpeitem); - this->skip_reprocess = 0; } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 7052f95259..d162b8bb4d 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -136,7 +136,6 @@ public: bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool is_load; bool upd_params; - bool skip_reprocess; BoolParam is_visible; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 232a61617e..6df6278b11 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -66,7 +66,7 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo Geom::OptRect bbox = lpeitem->geometricBounds(transform); if (clip_mask) { SPLPEItem * item = const_cast(lpeitem); - bbox.unionWith(clip_mask_bbox(item, transform)); + bbox.unionWith(clip_mask_bbox(item, transform * item->transform.inverse())); } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index c4f8e306be..bfbda2bfd2 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -92,7 +92,6 @@ void BoolParam::param_setValue(bool newvalue) { if (value != newvalue) { - param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/colorpicker.cpp b/src/live_effects/parameter/colorpicker.cpp index 2e9c8c6f22..f6521d0c06 100644 --- a/src/live_effects/parameter/colorpicker.cpp +++ b/src/live_effects/parameter/colorpicker.cpp @@ -131,7 +131,6 @@ ColorPickerParam::param_newWidget() void ColorPickerParam::param_setValue(const guint32 newvalue) { - param_effect->skip_reprocess = true; value = newvalue; } diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp index f6f2d6f06d..49edb850a3 100644 --- a/src/live_effects/parameter/fontbutton.cpp +++ b/src/live_effects/parameter/fontbutton.cpp @@ -83,7 +83,6 @@ void FontButtonParam::param_setValue(const Glib::ustring newvalue) { if (value != newvalue) { - param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 8c35cf142c..5a21f572b5 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -76,7 +76,6 @@ void HiddenParam::param_setValue(const Glib::ustring newvalue, bool write) { value = newvalue; - param_effect->skip_reprocess = true; if (write) { param_write_to_repr(value.c_str()); } diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 9ea80d3b8e..03eb2219f5 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -104,7 +104,6 @@ void MessageParam::param_setValue(const gchar * strvalue) { if (strcmp(strvalue, message) != 0) { - param_effect->skip_reprocess = true; param_effect->upd_params = true; } message = strvalue; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 135b316047..a175359f09 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -129,7 +129,6 @@ ScalarParam::param_set_value(gdouble val) { if (value != val) { param_effect->upd_params = true; - param_effect->skip_reprocess = true; } value = val; if (integer) diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index be7683f235..ab385daa64 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -325,7 +325,6 @@ void PathParam::set_new_value (Geom::Piecewise > const & newpath, bool write_to_svg) { remove_link(); - param_effect->skip_reprocess = true; _pathvector = Geom::path_from_piecewise(newpath, LPE_CONVERSION_TOLERANCE); if (write_to_svg) { diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index f6ee79b413..b811b7f2b9 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -95,7 +95,6 @@ PointParam::param_hide_knot(bool hide) { void PointParam::param_setValue(Geom::Point newpoint, bool write) { - param_effect->skip_reprocess = true; *dynamic_cast( this ) = newpoint; if(write){ Inkscape::SVGOStringStream os; diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index 096788a3d0..23912bedbe 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -102,7 +102,6 @@ void RandomParam::param_set_value(gdouble val, long newseed) { value = val; - param_effect->skip_reprocess = true; if (integer) value = round(value); if (value > max) diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 6da0bbf9f9..37ae3a1d7c 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -154,7 +154,6 @@ void TextParam::param_setValue(const Glib::ustring newvalue) { if (value != newvalue) { - param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index 88d848a602..bb9d9a90e0 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -172,7 +172,6 @@ void ToggleButtonParam::param_setValue(bool newvalue) { if (value != newvalue) { - param_effect->skip_reprocess = true; param_effect->upd_params = true; } value = newvalue; diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index 7342bd02ae..ab66e72569 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -133,7 +133,6 @@ TransformedPointParam::param_newWidget() void TransformedPointParam::set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector) { - param_effect->skip_reprocess = true; setValues(new_origin, new_vector); gchar * str = param_getSVGValue(); param_write_to_repr(str); diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index d2d666a90a..db9a34f9e5 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -900,22 +900,6 @@ void SPGroup::update_patheffect(bool write) { #ifdef GROUP_VERBOSE g_message("sp_group_update_patheffect: %p\n", lpeitem); #endif - if (hasPathEffect() && pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (lpe) { - std::cout << lpe->skip_reprocess << "lpe->skip_reprocessxxxxx" << std::endl; - if (lpe->skip_reprocess) { - lpe->skip_reprocess = false; - return; - } - } - } - } - } std::vector const item_list = sp_item_group_item_list(this); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index dcb3410860..2790930310 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -180,13 +180,11 @@ void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { } void SPLPEItem::modified(unsigned int flags) { - //TODO: finale remove tghe commented code if no regressions - /* The SP_OBJECT_USER_MODIFIED_FLAG_B is used to mark the fact that it's only a - transformation. It's apparently safe comment this. */ - if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) /*&& (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)*/) { - sp_lpe_item_update_patheffect(this, true, true); - } -// SPItem::onModified(flags); + //TODO: remove if no regressions + //stop update when modified and make the effect update on the LPE transform method if the effect require it + //if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + // sp_lpe_item_update_patheffect(this, true, true); + //} } Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { @@ -925,7 +923,6 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa if (c) { c->unref(); } - shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } -- GitLab From b7a84ea95181d4350c39001b1a2c4a362f3aed77 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 17 Feb 2018 01:23:52 +0100 Subject: [PATCH 46/57] working on maren feedback --- src/object/box3d-side.cpp | 28 +++++++++---------- src/object/sp-ellipse.cpp | 33 ----------------------- src/object/sp-ellipse.h | 2 -- src/object/sp-lpe-item.cpp | 1 + src/object/sp-path.cpp | 35 ------------------------ src/object/sp-path.h | 2 -- src/object/sp-shape.cpp | 36 ++++++++++++++++++++++++- src/object/sp-shape.h | 2 ++ src/object/sp-spiral.cpp | 32 ---------------------- src/object/sp-spiral.h | 1 - src/object/sp-star.cpp | 32 +--------------------- src/object/sp-star.h | 1 - src/ui/dialog/livepatheffect-editor.cpp | 5 ++-- 13 files changed, 53 insertions(+), 157 deletions(-) diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index 3dcbe80f1d..bd3e8d09eb 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -192,24 +192,20 @@ void Box3DSide::set_shape() { c->lineto(box3d_get_corner_screen(box, corners[3])); c->closepath(); - /* Reset the this'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)*/ - this->setCurveInsync(c); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); + //If original shape dont change on a LPE item return here to allow LPE + SPCurve * check = this->getCurveForEdit(false, true); + if (check) { + if(check->get_pathvector() == c->get_pathvector()) { + check->unref(); + c->unref(); + return; } - - c_lpe->unref(); - + check->unref(); } - + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + this->setCurveBeforeLPE(c); + this->setCurveInsync(c); c->unref(); } diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index f75c641b83..5e87cf953e 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -492,7 +492,6 @@ void SPGenericEllipse::set_shape() this->setCurveBeforeLPE(curve); this->setCurveInsync(curve); curve->unref(); - return; } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) @@ -627,38 +626,6 @@ void SPGenericEllipse::modified(guint flags) SPShape::modified(flags); } -void SPGenericEllipse::update_patheffect(bool write) -{ - Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { - /* 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)*/ - this->setCurveInsync(c_lpe); - this->resetClipPathAndMaskLPE(); - bool success = false; - if (hasPathEffect() && pathEffectsEnabled()) { - success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); - } - } - - if (write && success) { - if (c_lpe != NULL) { - gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} - void SPGenericEllipse::normalize() { Geom::AngleInterval a(this->start, this->end, true); diff --git a/src/object/sp-ellipse.h b/src/object/sp-ellipse.h index c179e3ff0f..0aa3dd1c62 100644 --- a/src/object/sp-ellipse.h +++ b/src/object/sp-ellipse.h @@ -71,8 +71,6 @@ public: virtual void modified(unsigned int flags); - virtual void update_patheffect(bool write); - /** * @brief Makes sure that start and end lie between 0 and 2 * PI. */ diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 2790930310..a7b6433d7f 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -429,6 +429,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, { if (!keep_paths) { repr->setAttribute("d", NULL); + sp_lpe_item_update_patheffect(lpeitem, true, true); } else { SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (desktop) { diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index ecb3233bb4..91136e0d94 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -372,41 +372,6 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { return Geom::identity(); } - -void SPPath::update_patheffect(bool write) { -#ifdef PATH_VERBOSE -g_message("sp_path_update_patheffect"); -#endif - Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { - /* 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)*/ - this->setCurveInsync(c_lpe); - this->resetClipPathAndMaskLPE(); - bool success = false; - if (hasPathEffect() && pathEffectsEnabled()) { - success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); - } - } - - if (write && success) { - if (c_lpe != NULL) { - gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} - /* Local Variables: mode:c++ diff --git a/src/object/sp-path.h b/src/object/sp-path.h index 2933c6ab89..380c8b4c7b 100644 --- a/src/object/sp-path.h +++ b/src/object/sp-path.h @@ -49,8 +49,6 @@ public: virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; - virtual void update_patheffect(bool write); - private: SPStyleSrc d_source; // Source of 'd' value, saved for output. }; diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 250a33eeb4..d450fe18d2 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -37,7 +37,8 @@ #include "sp-path.h" #include "preferences.h" #include "attributes.h" - +#include "svg/svg.h" +#include "svg/path-string.h" #include "live_effects/lpeobject.h" #include "helper/mathfns.h" // for triangle_area() @@ -738,6 +739,39 @@ void SPShape::print(SPPrintContext* ctx) { } } +void SPShape::update_patheffect(bool write) +{ + std::cout << "AAAAAAAAAAAAAA" << std::endl; + Inkscape::XML::Node *repr = this->getRepr(); + if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { + /* 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)*/ + this->setCurveInsync(c_lpe); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe); + this->applyToClipPath(this); + this->applyToMask(this); + } + } + + if (write && success) { + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + c_lpe->unref(); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index 524888c118..9a0a36d60e 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -48,6 +48,7 @@ public: int hasMarkers () const; int numberOfMarkers (int type) const; + public: // temporarily public, until SPPath is properly classed, etc. SPCurve *_curve_before_lpe; SPCurve *_curve; @@ -74,6 +75,7 @@ public: virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void set_shape(); + virtual void update_patheffect(bool write); }; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index 4c620a55b7..d714074287 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -196,37 +196,6 @@ void SPSpiral::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -void SPSpiral::update_patheffect(bool write) { - Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { - /* 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)*/ - this->setCurveInsync(c_lpe); - this->resetClipPathAndMaskLPE(); - bool success = false; - if (hasPathEffect() && pathEffectsEnabled()) { - success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); - } - } - - if (write && success) { - if (c_lpe != NULL) { - gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} - const char* SPSpiral::displayName() const { return _("Spiral"); } @@ -391,7 +360,6 @@ void SPSpiral::set_shape() { this->setCurveBeforeLPE(c); this->setCurveInsync(c); c->unref(); - return; } /** diff --git a/src/object/sp-spiral.h b/src/object/sp-spiral.h index 94724685c6..138eae9149 100644 --- a/src/object/sp-spiral.h +++ b/src/object/sp-spiral.h @@ -71,7 +71,6 @@ public: virtual char* description() const; virtual void set_shape(); - virtual void update_patheffect(bool write); private: Geom::Point getTangent(double t) const; diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 45be151213..a68f8d4be3 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -223,36 +223,6 @@ void SPStar::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -void SPStar::update_patheffect(bool write) { - Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { - /* 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)*/ - this->setCurveInsync(c_lpe); - this->resetClipPathAndMaskLPE(); - bool success = false; - if (hasPathEffect() && pathEffectsEnabled()) { - success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); - } - } - - if (write && success) { - if (c_lpe != NULL) { - gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} const char* SPStar::displayName() const { if (this->flatsided == false) @@ -472,8 +442,8 @@ void SPStar::set_shape() { * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ this->setCurveBeforeLPE(c); this->setCurveInsync(c); + this->update_patheffect(false); c->unref(); - return; } void diff --git a/src/object/sp-star.h b/src/object/sp-star.h index 1ebe3298ad..86f3e8ef91 100644 --- a/src/object/sp-star.h +++ b/src/object/sp-star.h @@ -54,7 +54,6 @@ public: virtual char* description() const; virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; - virtual void update_patheffect(bool write); virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const& xform); }; diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 6cf7f807a6..6264512fb8 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -279,12 +279,11 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( item ) { SPLPEItem *lpeitem = dynamic_cast(item); if ( lpeitem ) { - effect_list_reload(lpeitem); - - current_lpeitem = lpeitem; set_sensitize_all(true); if ( lpeitem->hasPathEffect() ) { + effect_list_reload(lpeitem); + current_lpeitem = lpeitem; Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE(); if (lpe) { showParams(*lpe); -- GitLab From c397abf690f76183f48a1916248f67108994bdc8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 17 Feb 2018 21:33:26 +0100 Subject: [PATCH 47/57] working on maren feedback --- src/object/sp-lpe-item.cpp | 3 ++- src/object/sp-shape.cpp | 20 ++++++++++++------ src/object/sp-shape.h | 6 +++--- src/object/sp-star.cpp | 28 +++++++++++++------------ src/ui/dialog/livepatheffect-editor.cpp | 5 +++-- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index a7b6433d7f..f1d0fb845c 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -418,6 +418,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, repr->setAttribute("d", repr->attribute("inkscape:original-d")); } repr->setAttribute("inkscape:original-d", NULL); + path->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); @@ -429,7 +430,6 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, { if (!keep_paths) { repr->setAttribute("d", NULL); - sp_lpe_item_update_patheffect(lpeitem, true, true); } else { SPDesktop * desktop = SP_ACTIVE_DESKTOP; if (desktop) { @@ -440,6 +440,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, sp_item_list_to_curves(items, selected, to_select, true); } } + shape->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index d450fe18d2..b54fe5c633 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -741,11 +741,19 @@ void SPShape::print(SPPrintContext* ctx) { void SPShape::update_patheffect(bool write) { - std::cout << "AAAAAAAAAAAAAA" << std::endl; + Inkscape::XML::Node *repr = this->getRepr(); - if (SPCurve *c_lpe = this->getCurveForEdit(false, true)) { + if (SPCurve *c_lpe = this->getCurveForEdit()) { /* 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)*/ + SPCurve * before = this->getCurveBeforeLPE(); + std::cout << c_lpe->get_pathvector() << "AAAAAAAAAAAAAA" << std::endl; + if (!before) { + this->setCurveBeforeLPE(c_lpe); + } else { + before->unref(); + } + std::cout << this->getCurveBeforeLPE()->get_pathvector() << "AAAAAAAAAAAAAA" << std::endl; this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; @@ -1090,9 +1098,9 @@ SPCurve * SPShape::getCurve(unsigned int owner) const * has path effect like in clips and mask * if owner == 0 return a copy */ -SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner, bool force) const +SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner) const { - if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (_curve_before_lpe) { if (owner) { return _curve_before_lpe; } @@ -1107,9 +1115,9 @@ SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner, bool force) const * has path effect like in clips and mask * if owner == 0 return a copy */ -SPCurve * SPShape::getCurveForEdit(unsigned int owner, bool force) const +SPCurve * SPShape::getCurveForEdit(unsigned int owner) const { - if (_curve_before_lpe && (hasPathEffectRecursive() || force)) { + if (_curve_before_lpe) { if (owner) { return _curve_before_lpe; } diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index 9a0a36d60e..be097e390a 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -40,9 +40,9 @@ public: virtual ~SPShape(); SPCurve * getCurve (unsigned int owner = FALSE) const; - SPCurve * getCurveBeforeLPE (unsigned int owner = FALSE, bool force = FALSE) const; - SPCurve * getCurveForEdit (unsigned int owner = FALSE, bool force = FALSE) const; - void setCurve (SPCurve *curve, unsigned int owner); + SPCurve * getCurveBeforeLPE (unsigned int owner = FALSE) const; + SPCurve * getCurveForEdit (unsigned int owner = FALSE) const; + void setCurve (SPCurve *curve, unsigned int owner = TRUE); void setCurveBeforeLPE (SPCurve *new_curve, unsigned int owner = TRUE); void setCurveInsync (SPCurve *curve, unsigned int owner = TRUE); int hasMarkers () const; diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index a68f8d4be3..f78ab9b325 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -428,21 +428,23 @@ void SPStar::set_shape() { c->closepath(); - //If original shape dont change on a LPE item return here to allow LPE - SPCurve * check = this->getCurveForEdit(false, true); - if (check) { - if(check->get_pathvector() == c->get_pathvector()) { - check->unref(); - c->unref(); - return; - } - check->unref(); - } /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveBeforeLPE(c); - this->setCurveInsync(c); - this->update_patheffect(false); + SPCurve * before = this->getCurveBeforeLPE(); + SPCurve * edit = this->getCurveForEdit(false, true); + if (edit && before) { + this->setCurveBeforeLPE(c); + std::cout << c->get_pathvector() << "beforebeforebeforebeforebeforebefore" << std::endl; + } else { + std::cout << c->get_pathvector() << "editediteditediteditediteditediteditedit" << std::endl; + this->setCurveInsync(c); + } + if (before) { + before->unref(); + } + if (edit) { + edit->unref(); + } c->unref(); } diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 6264512fb8..6cf7f807a6 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -279,11 +279,12 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( item ) { SPLPEItem *lpeitem = dynamic_cast(item); if ( lpeitem ) { + effect_list_reload(lpeitem); + + current_lpeitem = lpeitem; set_sensitize_all(true); if ( lpeitem->hasPathEffect() ) { - effect_list_reload(lpeitem); - current_lpeitem = lpeitem; Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE(); if (lpe) { showParams(*lpe); -- GitLab From 0e7d44c22b30ef99007110f5631c0375fd496e24 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 18 Feb 2018 01:29:10 +0100 Subject: [PATCH 48/57] working on maren feedback --- src/live_effects/lpe-powerclip.cpp | 6 ++--- src/object/box3d-side.cpp | 30 +++++++++++++---------- src/object/sp-ellipse.cpp | 38 +++++++++++++++++------------- src/object/sp-item-group.cpp | 2 +- src/object/sp-lpe-item.cpp | 26 +++++++++++++------- src/object/sp-path.cpp | 6 ++--- src/object/sp-polygon.cpp | 2 +- src/object/sp-polyline.cpp | 2 +- src/object/sp-rect.cpp | 2 +- src/object/sp-shape.cpp | 8 ------- src/object/sp-spiral.cpp | 30 +++++++++++++---------- src/object/sp-star.cpp | 11 +++++---- src/widgets/pencil-toolbar.cpp | 4 ++-- 13 files changed, 94 insertions(+), 73 deletions(-) diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 22fd3a3f56..60237b54ef 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -128,7 +128,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Geom::PathVector c_pv = c->get_pathvector(); c_pv *= affine; c->set_pathvector(c_pv); - SP_SHAPE(clip_to_path)->setCurve(c, TRUE); + SP_SHAPE(clip_to_path)->setCurve(c); c->unref(); } @@ -198,7 +198,7 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } c_pv.push_back(clip_box); c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + SP_SHAPE(clip_data)->setCurve(c); c->unref(); gchar * is_inverse_str = is_inverse.param_getSVGValue(); if (strcmp(is_inverse_str, "true") != 0) { @@ -240,7 +240,7 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ c_pv.pop_back(); } c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + SP_SHAPE(clip_data)->setCurve(c); c->unref(); gchar * is_inverse_str = is_inverse.param_getSVGValue(); if (strcmp(is_inverse_str, "false") != 0) { diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index bd3e8d09eb..7f731d4c6b 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -192,20 +192,26 @@ void Box3DSide::set_shape() { c->lineto(box3d_get_corner_screen(box, corners[3])); c->closepath(); - //If original shape dont change on a LPE item return here to allow LPE - SPCurve * check = this->getCurveForEdit(false, true); - if (check) { - if(check->get_pathvector() == c->get_pathvector()) { - check->unref(); - c->unref(); - return; - } - check->unref(); - } /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveBeforeLPE(c); - this->setCurveInsync(c); + SPCurve * before = this->getCurveBeforeLPE(); + SPCurve * edit = this->getCurveForEdit(); + if (edit && before) { + if (before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); + } + } else { + this->setCurveInsync(c); + } + if (before) { + before->unref(); + } + if (edit) { + edit->unref(); + } c->unref(); } diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 5e87cf953e..305441fa9e 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -434,7 +434,7 @@ void SPGenericEllipse::set_shape() this->normalize(); - SPCurve *curve = NULL; + SPCurve *c = NULL; // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. Geom::Circle circle(0, 0, 1); @@ -467,7 +467,7 @@ void SPGenericEllipse::set_shape() } else { pb.flush(); } - curve = new SPCurve(pb.peek()); + c = new SPCurve(pb.peek()); // gchar *str = sp_svg_write_path(curve->get_pathvector()); // std::cout << " path: " << str << std::endl; @@ -475,23 +475,29 @@ void SPGenericEllipse::set_shape() // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); - curve->transform(aff); + c->transform(aff); - //If original shape dont change on a LPE item return here to allow LPE - SPCurve * check = this->getCurveForEdit(false, true); - if (check) { - if(check->get_pathvector() == curve->get_pathvector()) { - check->unref(); - curve->unref(); - return; + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + SPCurve * before = this->getCurveBeforeLPE(); + SPCurve * edit = this->getCurveForEdit(); + if (edit && before) { + if (before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } - check->unref(); + } else { + this->setCurveInsync(c); } - /* Reset the shape's curve to the "original_curve" - * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveBeforeLPE(curve); - this->setCurveInsync(curve); - curve->unref(); + if (before) { + before->unref(); + } + if (edit) { + edit->unref(); + } + c->unref(); } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index db9a34f9e5..6f7507ccc3 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -994,7 +994,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - sub_shape->setCurve(oldcurve, TRUE); + sub_shape->setCurve(oldcurve); oldcurve->unref(); } } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index f1d0fb845c..4f92a43a6d 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -359,18 +359,24 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) } } if (SP_IS_GROUP(lpeitem)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); + std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); } } - } - else if (SP_IS_PATH(lpeitem)) { - Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); + } else if (SPPath * path = dynamic_cast(lpeitem)) { + Inkscape::XML::Node *pathrepr = path->getRepr(); if ( !pathrepr->attribute("inkscape:original-d") ) { pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); + path->setCurveBeforeLPE(path->getCurve()); + } + } else if (SPShape * shape = dynamic_cast(lpeitem)) { + if (SPCurve * c_lpe = shape->getCurveBeforeLPE()) { + c_lpe->unref(); + } else { + shape->setCurveBeforeLPE(shape->getCurve()); } } } @@ -747,7 +753,7 @@ SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(false, true)); + shape->setCurveInsync( shape->getCurveForEdit()); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); } else { @@ -772,9 +778,10 @@ SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(false, true)); + shape->setCurveInsync( shape->getCurveForEdit()); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); } else { // make sure there is an original-d for paths!!! sp_lpe_item_create_original_path_recursive(shape); @@ -797,9 +804,10 @@ SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) } } } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit(false, true)); + shape->setCurveInsync( shape->getCurveForEdit()); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); } else { // make sure there is an original-d for paths!!! sp_lpe_item_create_original_path_recursive(shape); @@ -877,7 +885,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa if (lpe) { //group c = shape->getCurve(); } else { - c = shape->getCurveForEdit(false, true); + c = shape->getCurveForEdit(); } if (c) { bool success = false; @@ -917,7 +925,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); + SP_SHAPE(clip_mask)->setCurve(oldcurve); oldcurve->unref(); } } diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index 91136e0d94..e0e8c4cc31 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -218,11 +218,11 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); } } else { - this->setCurve(NULL, TRUE); + this->setCurve(NULL); } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -309,7 +309,7 @@ void SPPath::update(SPCtx *ctx, guint flags) { if (curve) { // Update curve - this->setCurveInsync(curve, TRUE); + this->setCurveInsync(curve); curve->unref(); // Convert from property to attribute (convert back on write) diff --git a/src/object/sp-polygon.cpp b/src/object/sp-polygon.cpp index 14fd104b33..b2a0c14808 100644 --- a/src/object/sp-polygon.cpp +++ b/src/object/sp-polygon.cpp @@ -157,7 +157,7 @@ void SPPolygon::set(unsigned int key, const gchar* value) { curve->closepath(); } - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); break; } diff --git a/src/object/sp-polyline.cpp b/src/object/sp-polyline.cpp index 29054f934a..3be4700eb8 100644 --- a/src/object/sp-polyline.cpp +++ b/src/object/sp-polyline.cpp @@ -91,7 +91,7 @@ void SPPolyLine::set(unsigned int key, const gchar* value) { } } - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); break; } diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index 52c08e29c3..f21dafd54f 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -199,7 +199,7 @@ const char* SPRect::displayName() const { void SPRect::set_shape() { if ((this->height.computed < 1e-18) || (this->width.computed < 1e-18)) { this->setCurveInsync(NULL); - this->setCurveBeforeLPE( NULL ); + this->setCurveBeforeLPE(NULL); return; } diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index b54fe5c633..868298d293 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -746,14 +746,6 @@ void SPShape::update_patheffect(bool write) if (SPCurve *c_lpe = this->getCurveForEdit()) { /* 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)*/ - SPCurve * before = this->getCurveBeforeLPE(); - std::cout << c_lpe->get_pathvector() << "AAAAAAAAAAAAAA" << std::endl; - if (!before) { - this->setCurveBeforeLPE(c_lpe); - } else { - before->unref(); - } - std::cout << this->getCurveBeforeLPE()->get_pathvector() << "AAAAAAAAAAAAAA" << std::endl; this->setCurveInsync(c_lpe); this->resetClipPathAndMaskLPE(); bool success = false; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index d714074287..60cd9b08b1 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -345,20 +345,26 @@ void SPSpiral::set_shape() { this->fitAndDraw(c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); } - //If original shape dont change on a LPE item return here to allow LPE - SPCurve * check = this->getCurveForEdit(false, true); - if (check) { - if(check->get_pathvector() == c->get_pathvector()) { - check->unref(); - c->unref(); - return; + /* Reset the shape's curve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + SPCurve * before = this->getCurveBeforeLPE(); + SPCurve * edit = this->getCurveForEdit(); + if (edit && before) { + if (before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } - check->unref(); + } else { + this->setCurveInsync(c); + } + if (before) { + before->unref(); + } + if (edit) { + edit->unref(); } - /* Reset the shape's curve to the "original_curve" - * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveBeforeLPE(c); - this->setCurveInsync(c); c->unref(); } diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index f78ab9b325..e36c4ea348 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -431,12 +431,15 @@ void SPStar::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); - SPCurve * edit = this->getCurveForEdit(false, true); + SPCurve * edit = this->getCurveForEdit(); if (edit && before) { - this->setCurveBeforeLPE(c); - std::cout << c->get_pathvector() << "beforebeforebeforebeforebeforebefore" << std::endl; + if (before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); + } } else { - std::cout << c->get_pathvector() << "editediteditediteditediteditediteditedit" << std::endl; this->setCurveInsync(c); } if (before) { diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 9182cf24bb..d2939c7209 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -328,7 +328,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c,0); + shape->setCurve(c, false); } break; } @@ -369,7 +369,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c,0); + shape->setCurve(c, false); } break; } -- GitLab From b5d3fa9bdff95f39d9d63be56c2b4c4b50f60f01 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 18 Feb 2018 16:46:03 +0100 Subject: [PATCH 49/57] working on maren feedback --- src/live_effects/lpe-bendpath.cpp | 5 +---- src/object/sp-item-group.cpp | 7 +++---- src/object/sp-lpe-item.cpp | 3 +-- src/object/sp-lpe-item.h | 1 + src/object/sp-shape.cpp | 5 +++-- src/selection-chemistry.cpp | 4 ---- 6 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index b5dc2d25a0..d03839e9ba 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -151,7 +151,6 @@ void LPEBendPath::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); @@ -170,9 +169,7 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - if (sp_lpe_item && !postmul.isTranslation()) { //Check is object - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); - } + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); } void diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 6f7507ccc3..a5ddab1b21 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -88,10 +88,10 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) SPLPEItem::child_added(child, ref); SPObject *last_child = this->lastChild(); - + SPItem *item = NULL; if (last_child && last_child->getRepr() == child) { // optimization for the common special case where the child is being added at the end - SPItem *item = dynamic_cast(last_child); + item = dynamic_cast(last_child); if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; @@ -105,7 +105,7 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } else { // general case - SPItem *item = dynamic_cast(get_child_by_repr(child)); + item = dynamic_cast(get_child_by_repr(child)); if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; @@ -121,7 +121,6 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } - this->requestModified(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 4f92a43a6d..ec78c534da 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -50,7 +50,6 @@ static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); -static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); typedef std::list HRefList; @@ -320,7 +319,6 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) else { top = lpeitem; } - top->update_patheffect(write); } @@ -756,6 +754,7 @@ SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) shape->setCurveInsync( shape->getCurveForEdit()); if (!hasPathEffectOnClipOrMaskRecursive(shape)) { shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); } else { // make sure there is an original-d for paths!!! sp_lpe_item_create_original_path_recursive(shape); diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 0e6049d4e6..d8cc59c57d 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -102,6 +102,7 @@ public: void editNextParamOncanvas(SPDesktop *dt); }; +void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name! #endif /* !SP_LPE_ITEM_H_SEEN */ diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 868298d293..4d44aec328 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -741,8 +741,7 @@ void SPShape::print(SPPrintContext* ctx) { void SPShape::update_patheffect(bool write) { - - Inkscape::XML::Node *repr = this->getRepr(); + sp_lpe_item_create_original_path_recursive(this); if (SPCurve *c_lpe = this->getCurveForEdit()) { /* 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)*/ @@ -759,6 +758,7 @@ void SPShape::update_patheffect(bool write) } if (write && success) { + Inkscape::XML::Node *repr = this->getRepr(); if (c_lpe != NULL) { gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); repr->setAttribute("d", str); @@ -1115,6 +1115,7 @@ SPCurve * SPShape::getCurveForEdit(unsigned int owner) const } return _curve_before_lpe->copy(); } + std::cout << "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" << std::endl; return getCurve(owner); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 49201af6ca..622a843e4c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -771,10 +771,6 @@ Inkscape::XML::Node* ObjectSet::group() { group->setPosition(topmost + 1); set(doc->getObjectByRepr(group)); - SPLPEItem *lpeitem = dynamic_cast(*(items().begin())); - if (lpeitem) { - sp_lpe_item_update_patheffect(lpeitem, true, true); - } DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); -- GitLab From b7754594b78dc3cd90ff839b1be7893345e05025 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 19 Feb 2018 00:52:46 +0100 Subject: [PATCH 50/57] fix compiling bug --- src/object/sp-star.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 67e4239668..ae702f3a59 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -432,7 +432,7 @@ void SPStar::set_shape() { * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); SPCurve * edit = this->getCurveForEdit(); - if (edit && (before || this->hasPathEffectRecursive()) { + if (edit && (before || this->hasPathEffectRecursive())) { if (before->get_pathvector() != c->get_pathvector()){ this->setCurveBeforeLPE(c); this->update_patheffect(false); -- GitLab From 2e575325fe18ebf3b756597508be2e3ea7b3f845 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 21 Feb 2018 00:26:48 +0100 Subject: [PATCH 51/57] Fixing grouping and ungrouping --- src/live_effects/lpe-bendpath.cpp | 2 +- src/object/box3d-side.cpp | 8 ++------ src/object/sp-ellipse.cpp | 10 +++------- src/object/sp-lpe-item.cpp | 1 + src/object/sp-shape.cpp | 1 - src/object/sp-spiral.cpp | 10 +++------- src/object/sp-star.cpp | 8 ++------ 7 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index d03839e9ba..11694249a3 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -169,7 +169,7 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); + //block parameters be transformed because shapes with bend store transform in the element } void diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index 7f731d4c6b..6ecd3a1fae 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -195,9 +195,8 @@ void Box3DSide::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); - SPCurve * edit = this->getCurveForEdit(); - if (edit && before) { - if (before->get_pathvector() != c->get_pathvector()){ + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ this->setCurveBeforeLPE(c); this->update_patheffect(false); } else { @@ -209,9 +208,6 @@ void Box3DSide::set_shape() { if (before) { before->unref(); } - if (edit) { - edit->unref(); - } c->unref(); } diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 305441fa9e..95bfd61606 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -478,11 +478,10 @@ void SPGenericEllipse::set_shape() c->transform(aff); /* Reset the shape's curve to the "original_curve" - * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); - SPCurve * edit = this->getCurveForEdit(); - if (edit && before) { - if (before->get_pathvector() != c->get_pathvector()){ + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ this->setCurveBeforeLPE(c); this->update_patheffect(false); } else { @@ -494,9 +493,6 @@ void SPGenericEllipse::set_shape() if (before) { before->unref(); } - if (edit) { - edit->unref(); - } c->unref(); } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 7c7aae8935..e0ef848af0 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -932,6 +932,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa if (c) { c->unref(); } + shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 1cd76c2584..07416650ea 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -1114,7 +1114,6 @@ SPCurve * SPShape::getCurveForEdit(unsigned int owner) const } return _curve_before_lpe->copy(); } - std::cout << "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" << std::endl; return getCurve(owner); } diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index 60cd9b08b1..7a449807df 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -346,11 +346,10 @@ void SPSpiral::set_shape() { } /* Reset the shape's curve to the "original_curve" - * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); - SPCurve * edit = this->getCurveForEdit(); - if (edit && before) { - if (before->get_pathvector() != c->get_pathvector()){ + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ this->setCurveBeforeLPE(c); this->update_patheffect(false); } else { @@ -362,9 +361,6 @@ void SPSpiral::set_shape() { if (before) { before->unref(); } - if (edit) { - edit->unref(); - } c->unref(); } diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index ae702f3a59..097b5d9893 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -431,9 +431,8 @@ void SPStar::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ SPCurve * before = this->getCurveBeforeLPE(); - SPCurve * edit = this->getCurveForEdit(); - if (edit && (before || this->hasPathEffectRecursive())) { - if (before->get_pathvector() != c->get_pathvector()){ + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ this->setCurveBeforeLPE(c); this->update_patheffect(false); } else { @@ -445,9 +444,6 @@ void SPStar::set_shape() { if (before) { before->unref(); } - if (edit) { - edit->unref(); - } c->unref(); } -- GitLab From 2e1041690bbff6b4ce852d20e4f90c18df032e54 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Wed, 21 Feb 2018 09:46:54 +0100 Subject: [PATCH 52/57] Fix running problem --- src/object/sp-item-group.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 2e2c45f28d..a3fa6c6e87 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -88,10 +88,9 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) SPLPEItem::child_added(child, ref); SPObject *last_child = this->lastChild(); - SPItem *item = NULL; if (last_child && last_child->getRepr() == child) { // optimization for the common special case where the child is being added at the end - item = dynamic_cast(last_child); + SPItem *item = dynamic_cast(last_child); if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; @@ -105,7 +104,7 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } else { // general case - item = dynamic_cast(get_child_by_repr(child)); + SPItem *item = dynamic_cast(get_child_by_repr(child)); if ( item ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; @@ -121,7 +120,6 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } - item->requestModified(SP_OBJECT_MODIFIED_FLAG); this->requestModified(SP_OBJECT_MODIFIED_FLAG); } -- GitLab From 73f2a803e2cce12fd0843068fad5c499e7dacb6a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 21 Feb 2018 22:56:06 +0100 Subject: [PATCH 53/57] Allow shapes knots on LPE items --- src/ui/shape-editor-knotholders.cpp | 22 +++++++++----- src/ui/shape-editor.cpp | 47 +++++++++++++++++++++++++++-- src/ui/shape-editor.h | 2 ++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/ui/shape-editor-knotholders.cpp b/src/ui/shape-editor-knotholders.cpp index 5fb677f27a..885f3ef40d 100644 --- a/src/ui/shape-editor-knotholders.cpp +++ b/src/ui/shape-editor-knotholders.cpp @@ -107,13 +107,7 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) { KnotHolder *knotholder = NULL; - SPLPEItem *lpe = dynamic_cast(item); - if (lpe && - lpe->getCurrentLPE() && - lpe->getCurrentLPE()->isVisible() && - lpe->getCurrentLPE()->providesKnotholder()) { - knotholder = sp_lpe_knot_holder(lpe, desktop); - } else if (dynamic_cast(item)) { + if (dynamic_cast(item)) { knotholder = new RectKnotHolder(desktop, item, NULL); } else if (dynamic_cast(item)) { knotholder = new Box3DKnotHolder(desktop, item, NULL); @@ -139,6 +133,20 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) return knotholder; } +KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knotholder = NULL; + + SPLPEItem *lpe = dynamic_cast(item); + if (lpe && + lpe->getCurrentLPE() && + lpe->getCurrentLPE()->isVisible() && + lpe->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(lpe, desktop); + } + return knotholder; +} + } } // namespace Inkscape diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp index 3a5aec056d..b40bec86f7 100644 --- a/src/ui/shape-editor.cpp +++ b/src/ui/shape-editor.cpp @@ -29,13 +29,16 @@ namespace Inkscape { namespace UI { KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); +KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop); bool ShapeEditor::_blockSetItem = false; ShapeEditor::ShapeEditor(SPDesktop *dt, Geom::Affine edit_transform) : desktop(dt), knotholder(nullptr), + lpeknotholder(nullptr), knotholder_listener_attached_for(nullptr), + lpeknotholder_listener_attached_for(nullptr), _edit_transform(edit_transform) { } @@ -58,25 +61,43 @@ void ShapeEditor::unset_item(bool keep_knotholder) { this->knotholder = NULL; } } + if (this->lpeknotholder) { + Inkscape::XML::Node *old_repr = this->lpeknotholder->repr; + if (old_repr && old_repr == lpeknotholder_listener_attached_for) { + sp_repr_remove_listener_by_data(old_repr, this); + Inkscape::GC::release(old_repr); + lpeknotholder_listener_attached_for = NULL; + } + + if (!keep_knotholder) { + delete this->lpeknotholder; + this->lpeknotholder = NULL; + } + } } bool ShapeEditor::has_knotholder() { - return this->knotholder != NULL; + return this->knotholder != NULL || this->lpeknotholder != NULL; } void ShapeEditor::update_knotholder() { if (this->knotholder) this->knotholder->update_knots(); + if (this->lpeknotholder) + this->lpeknotholder->update_knots(); } bool ShapeEditor::has_local_change() { - return (this->knotholder && this->knotholder->local_change != 0); + return (this->knotholder && this->knotholder->local_change != 0) || (this->lpeknotholder && this->lpeknotholder->local_change != 0); } void ShapeEditor::decrement_local_change() { if (this->knotholder) { this->knotholder->local_change = FALSE; } + if (this->lpeknotholder) { + this->lpeknotholder->local_change = FALSE; + } } void ShapeEditor::event_attr_changed(Inkscape::XML::Node * node, gchar const *name, gchar const *, gchar const *, bool, void *data) @@ -123,6 +144,10 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { // only recreate knotholder if none is present this->knotholder = createKnotHolder(item, desktop); } + if (!this->lpeknotholder) { + // only recreate knotholder if none is present + this->lpeknotholder = createLPEKnotHolder(item, desktop); + } if (this->knotholder) { this->knotholder->setEditTransform(_edit_transform); this->knotholder->update_knots(); @@ -134,6 +159,17 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { knotholder_listener_attached_for = repr; } } + if (this->lpeknotholder) { + this->lpeknotholder->setEditTransform(_edit_transform); + this->lpeknotholder->update_knots(); + // setting new listener + repr = this->lpeknotholder->repr; + if (repr != lpeknotholder_listener_attached_for) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &shapeeditor_repr_events, this); + lpeknotholder_listener_attached_for = repr; + } + } } } @@ -145,6 +181,9 @@ void ShapeEditor::reset_item(bool keep_knotholder) if (knotholder) { SPObject *obj = desktop->getDocument()->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. set_item(SP_ITEM(obj), keep_knotholder); + } else if (lpeknotholder) { + SPObject *obj = desktop->getDocument()->getObjectByRepr(lpeknotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + set_item(SP_ITEM(obj), keep_knotholder); } } @@ -155,7 +194,9 @@ bool ShapeEditor::knot_mouseover() const { if (this->knotholder) { return knotholder->knot_mouseover(); } - + if (this->lpeknotholder) { + return lpeknotholder->knot_mouseover(); + } return false; } diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h index e30b2d60b9..c8222eddb0 100644 --- a/src/ui/shape-editor.h +++ b/src/ui/shape-editor.h @@ -36,6 +36,7 @@ public: bool knot_mouseover() const; KnotHolder *knotholder; + KnotHolder *lpeknotholder; bool has_knotholder(); static void blockSetItem(bool b) { _blockSetItem = b; } // kludge static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, @@ -46,6 +47,7 @@ private: SPDesktop *desktop; Inkscape::XML::Node *knotholder_listener_attached_for; + Inkscape::XML::Node *lpegit knotholder_listener_attached_for; Geom::Affine _edit_transform; }; -- GitLab From 0b6fd6d36f956ff2e05cbb1e47cc5d99e4a712ff Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Thu, 22 Feb 2018 21:31:04 +0100 Subject: [PATCH 54/57] Fix compiling bug --- src/ui/shape-editor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h index c8222eddb0..67bce1c98d 100644 --- a/src/ui/shape-editor.h +++ b/src/ui/shape-editor.h @@ -47,7 +47,7 @@ private: SPDesktop *desktop; Inkscape::XML::Node *knotholder_listener_attached_for; - Inkscape::XML::Node *lpegit knotholder_listener_attached_for; + Inkscape::XML::Node *lpeknotholder_listener_attached_for; Geom::Affine _edit_transform; }; -- GitLab From 52583aa1ee15d4ea46fd8b4aaf8886e7de9fa456 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 2 Mar 2018 23:09:39 +0100 Subject: [PATCH 55/57] Add defaults to powerstroke --- src/live_effects/lpe-powerstroke.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 6d63ffa81c..1d64e90420 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -170,13 +170,13 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this), sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve"), "sort_points", &wr, this, true), - interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER), + interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM), interpolator_beta(_("Smoothness:"), _("Sets the smoothness for the CubicBezierJohan interpolator; 0 = linear interpolation, 1 = smooth"), "interpolator_beta", &wr, this, 0.2), scale_width(_("Width scale:"), _("Width scale all points"), "scale_width", &wr, this, 1.0), - start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT), - linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_EXTRP_MITER_ARC), + start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_ROUND), miter_limit(_("Miter limit:"), _("Maximum length of the miter (in units of stroke width)"), "miter_limit", &wr, this, 4.), - end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT) + end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH) { show_orig_path = true; -- GitLab From 379c20c4d7615cf47428deecb64c2883213425cf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 3 Mar 2018 00:09:58 +0100 Subject: [PATCH 56/57] removing merges --- src/live_effects/effect.cpp | 93 +-- src/live_effects/effect.h | 16 +- src/live_effects/lpe-bendpath.cpp | 10 +- src/live_effects/lpe-bspline.cpp | 5 +- src/live_effects/lpe-clone-original.cpp | 18 +- src/live_effects/lpe-copy_rotate.cpp | 136 ++--- src/live_effects/lpe-copy_rotate.h | 3 +- src/live_effects/lpe-envelope.cpp | 4 +- src/live_effects/lpe-fillet-chamfer.cpp | 19 +- src/live_effects/lpe-interpolate.cpp | 2 +- src/live_effects/lpe-lattice.cpp | 4 +- src/live_effects/lpe-lattice2.cpp | 7 +- src/live_effects/lpe-measure-segments.cpp | 576 +++++++----------- src/live_effects/lpe-measure-segments.h | 28 +- src/live_effects/lpe-mirror_symmetry.cpp | 250 ++++---- src/live_effects/lpe-mirror_symmetry.h | 12 +- src/live_effects/lpe-patternalongpath.cpp | 4 +- src/live_effects/lpe-perp_bisector.cpp | 4 +- src/live_effects/lpe-perspective-envelope.cpp | 7 +- src/live_effects/lpe-perspective_path.cpp | 3 - src/live_effects/lpe-powerclip.cpp | 58 +- src/live_effects/lpe-powerclip.h | 1 - src/live_effects/lpe-powermask.cpp | 14 +- src/live_effects/lpe-powerstroke.cpp | 8 +- src/live_effects/lpe-roughen.cpp | 3 - src/live_effects/lpe-show_handles.cpp | 2 +- src/live_effects/lpe-simplify.cpp | 3 - src/live_effects/lpe-transform_2pts.cpp | 13 +- src/live_effects/lpe-vonkoch.cpp | 4 +- src/live_effects/lpegroupbbox.cpp | 40 +- src/live_effects/lpegroupbbox.h | 7 +- src/live_effects/parameter/array.h | 3 +- src/live_effects/parameter/bool.cpp | 6 +- src/live_effects/parameter/enum.h | 6 +- src/live_effects/parameter/hidden.cpp | 6 +- src/live_effects/parameter/message.cpp | 12 +- src/live_effects/parameter/message.h | 4 +- .../parameter/originalitemarray.cpp | 3 +- src/live_effects/parameter/originalpath.cpp | 2 +- .../parameter/originalpatharray.cpp | 9 +- src/live_effects/parameter/parameter.cpp | 9 +- src/live_effects/parameter/path.cpp | 2 +- src/live_effects/parameter/point.cpp | 19 +- src/live_effects/parameter/random.cpp | 6 +- src/live_effects/parameter/text.cpp | 6 +- src/live_effects/parameter/togglebutton.cpp | 6 +- .../parameter/transformedpoint.cpp | 6 +- src/live_effects/parameter/vector.cpp | 6 +- src/object/box3d-side.cpp | 25 +- src/object/sp-clippath.cpp | 6 +- src/object/sp-conn-end-pair.cpp | 4 +- src/object/sp-ellipse.cpp | 66 +- src/object/sp-ellipse.h | 4 +- src/object/sp-item-group.cpp | 72 +-- src/object/sp-item.cpp | 18 +- src/object/sp-item.h | 4 - src/object/sp-line.cpp | 2 +- src/object/sp-lpe-item.cpp | 524 +++++++--------- src/object/sp-lpe-item.h | 15 +- src/object/sp-mask.cpp | 27 - src/object/sp-mask.h | 4 - src/object/sp-object.cpp | 1 + src/object/sp-offset.cpp | 4 +- src/object/sp-path.cpp | 135 +++- src/object/sp-path.h | 33 +- src/object/sp-polygon.cpp | 2 +- src/object/sp-polyline.cpp | 2 +- src/object/sp-rect.cpp | 6 +- src/object/sp-shape.cpp | 111 +--- src/object/sp-shape.h | 13 +- src/object/sp-spiral.cpp | 52 +- src/object/sp-spiral.h | 3 +- src/object/sp-star.cpp | 51 +- src/object/sp-star.h | 3 +- src/path-chemistry.cpp | 6 +- src/selection-chemistry.cpp | 14 +- src/splivarot.cpp | 4 +- src/style-internal.h | 2 +- src/ui/dialog/livepatheffect-editor.cpp | 43 +- src/ui/shape-editor-knotholders.cpp | 22 +- src/ui/shape-editor.cpp | 47 +- src/ui/shape-editor.h | 2 - src/ui/tool/path-manipulator.cpp | 38 +- src/ui/tools/connector-tool.cpp | 10 +- src/ui/tools/freehand-base.cpp | 2 +- src/ui/tools/node-tool.cpp | 2 +- src/ui/widget/selected-style.cpp | 2 +- src/widgets/pencil-toolbar.cpp | 8 +- 88 files changed, 1285 insertions(+), 1569 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index bfc280ce6c..44b737ad11 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -394,9 +394,9 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - current_shape(NULL), + sp_shape(NULL), + sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden - defaultsopen(false), is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { registerParameter( dynamic_cast(&is_visible) ); @@ -469,14 +469,14 @@ Effect::processObjects(LpeAction lpe_action) if (!document) { return; } - for (std::vector::iterator el_it = items.begin(); + for (std::vector::iterator el_it = items.begin(); el_it != items.end(); ++el_it) { - Glib::ustring id = *el_it; - if (id.empty()) { + const char * id = *el_it; + if (!id) { return; } SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id.c_str()))) { + if ((elemref = document->getObjectById(id))) { Inkscape::XML::Node * elemnode = elemref->getRepr(); std::vector item_list; item_list.push_back(SP_ITEM(elemref)); @@ -527,6 +527,17 @@ Effect::processObjects(LpeAction lpe_action) } } +void Effect::setCurrentShape(SPShape * shape){ + if(shape){ + sp_shape = shape; + if (!(sp_curve = sp_shape->getCurveBeforeLPE())) { + // oops + return; + } + pathvector_before_effect = sp_curve->get_pathvector(); + } +} + /** * Is performed each time before the effect is updated. */ @@ -551,13 +562,21 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); + SPShape * shape = dynamic_cast(sp_lpe_item); + setCurrentShape(shape); doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); + SPShape * shape = dynamic_cast(sp_lpe_item); + setCurrentShape(shape); doBeforeEffect(lpeitem); + if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { + sp_lpe_item->applyToClipPath(sp_lpe_item); + sp_lpe_item->applyToMask(sp_lpe_item); + } update_helperpath(); } @@ -794,9 +813,6 @@ Effect::newWidget() ++it; } - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -808,6 +824,7 @@ Effect::defaultParamSet() { // use manage here, because after deletion of Effect object, others might still be pointing to this widget. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() ); Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType()); Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType()); @@ -819,28 +836,27 @@ Effect::defaultParamSet() has_params = true; Parameter * param = *it; Glib::ustring * tip = param->param_getTooltip(); - const gchar * key = param->param_key.c_str(); - const gchar * label = param->param_label.c_str(); - Glib::ustring value = param->param_getSVGValue(); - Glib::ustring defvalue = param->param_getDefaultSVGValue(); - Glib::ustring pref_path = "/live_effects/"; - pref_path += effectkey; - pref_path +="/"; - pref_path += key; + const gchar * key = param->param_key.c_str(); + const gchar * value = param->param_label.c_str(); + + Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + + effectkey + + (Glib::ustring)"/" + + (Glib::ustring)key; bool valid = prefs->getEntry(pref_path).isValid(); const gchar * set_or_upd; - Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); if (valid) { set_or_upd = _("Update"); - def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); + def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); } else { set_or_upd = _("Set"); ove = Glib::ustring(_("Default value overridden: None\n")); } - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(param->param_getSVGValue()); Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) ); - Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START)); + Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START)); parameter_label->set_use_markup(true); parameter_label->set_use_underline(true); Glib::ustring tooltip = Glib::ustring("") + parameter_label->get_text () + Glib::ustring("\n") + param->param_tooltip + Glib::ustring("\n\n"); @@ -849,9 +865,9 @@ Effect::defaultParamSet() vbox_param->pack_start(*parameter_label, true, true, 2); Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); - unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); + unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); - set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); + set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); if (!valid) { unset->set_sensitive(false); } @@ -866,12 +882,11 @@ Effect::defaultParamSet() Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip)); expander->set_use_markup(true); expander->add(*vbox_expander); - expander->set_expanded(defaultsopen); - //expander->set_size_request(-1, 90); - expander->property_expanded().signal_changed().connect(sigc::bind<0>(sigc::mem_fun(*this, &Effect::onDefaultsExpanderChanged), expander )); + expander->set_expanded(false); + vbox->pack_start(*dynamic_cast (expander), true, true, 2); if (has_params) { - Gtk::Widget *vboxwidg = dynamic_cast(expander); - vboxwidg->set_margin_bottom(5); + Gtk::Widget *vboxwidg = dynamic_cast(vbox); + vboxwidg->set_margin_bottom(10); vboxwidg->set_margin_top(5); return vboxwidg; } else { @@ -880,36 +895,30 @@ Effect::defaultParamSet() } void -Effect::onDefaultsExpanderChanged(Gtk::Expander * expander) -{ - defaultsopen = expander->get_expanded(); -} - -void -Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(pref_path, value); + prefs->setString(pref_path, (Glib::ustring)value); gchar * label = _("Update"); set->set_label((Glib::ustring)label); unset->set_sensitive(true); - Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + value + Glib::ustring("\n"); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(value) + Glib::ustring("\n"); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } void -Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->remove(pref_path); gchar * label = _("Set"); set->set_label((Glib::ustring)label); unset->set_sensitive(false); - Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: None\n")); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) +value; + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index d162b8bb4d..d0024f8772 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -10,7 +10,6 @@ #include #include <2geom/forward.h> #include "ui/widget/registry.h" -#include #include "parameter/bool.h" #include "effect-enum.h" @@ -80,8 +79,8 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape() const { return current_shape; }; - void setCurrentShape(SPShape * shape) { current_shape = shape; } + SPShape * getCurrentShape(){ return sp_shape; }; + void setCurrentShape(SPShape * shape); void processObjects(LpeAction lpe_action); /* @@ -137,6 +136,7 @@ public: bool is_load; bool upd_params; BoolParam is_visible; + SPCurve * sp_curve; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; protected: @@ -175,19 +175,17 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - SPShape * current_shape; // these get stored in performPathEffects. - std::vector items; + SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. + std::vector items; double current_zoom; std::vector selectedNodesPoints; private: - void onDefaultsExpanderChanged(Gtk::Expander * expander); - void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); - void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); bool provides_own_flash_paths; // if true, the standard flash path is suppressed bool is_ready; - bool defaultsopen; Effect(const Effect&); Effect& operator=(const Effect&); diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 11694249a3..314ddc84c5 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -86,8 +86,9 @@ void LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (_knot_entity) { if (hide_knot) { helper_path.clear(); @@ -151,7 +152,8 @@ void LPEBendPath::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + + original_bbox(SP_LPE_ITEM(item)); Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); @@ -169,7 +171,9 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - //block parameters be transformed because shapes with bend store transform in the element + if (sp_lpe_item) { + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); + } } void diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 7834ff108b..f007599215 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -139,9 +139,6 @@ Gtk::Widget *LPEBSpline::newWidget() ++it; } - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -167,7 +164,7 @@ void LPEBSpline::changeWeight(double weight_ammount) { SPPath *path = dynamic_cast(sp_lpe_item); if(path) { - SPCurve *curve = path->getCurveForEdit(); + SPCurve *curve = path->get_curve_for_edit(); doBSplineFromWidget(curve, weight_ammount/100.0); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index d0ff805002..413c188930 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -124,7 +124,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * if ( shape_dest && shape_origin && (std::strcmp(attribute, "d") == 0)) { SPCurve *c = NULL; if (method == CLM_BSPLINESPIRO) { - c = shape_origin->getCurveForEdit(); + c = shape_origin->getCurveBeforeLPE(); SPLPEItem * lpe_item = SP_LPE_ITEM(origin); if (lpe_item) { PathEffectList lpelist = lpe_item->getEffectList(); @@ -142,7 +142,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * } } } else if(method == CLM_ORIGINALD) { - c = shape_origin->getCurveForEdit(); + c = shape_origin->getCurveBeforeLPE(); } else { c = shape_origin->getCurve(); } @@ -200,17 +200,15 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ if (method != CLM_NONE) { attr += Glib::ustring("d,"); } - gchar * attributes_str = attributes.param_getSVGValue(); - attr += Glib::ustring(attributes_str) + Glib::ustring(","); - if (attr.size() && !Glib::ustring(attributes_str).size()) { + attr += Glib::ustring(attributes.param_getSVGValue()) + Glib::ustring(","); + if (attr.size() && !Glib::ustring(attributes.param_getSVGValue()).size()) { attr.erase (attr.size()-1, 1); } - gchar * style_attributes_str = style_attributes.param_getSVGValue(); Glib::ustring style_attr = ""; - if (style_attr.size() && !Glib::ustring( style_attributes_str).size()) { + if (style_attr.size() && !Glib::ustring(style_attributes.param_getSVGValue()).size()) { style_attr.erase (style_attr.size()-1, 1); } - style_attr += Glib::ustring( style_attributes_str) + Glib::ustring(","); + style_attr += Glib::ustring(style_attributes.param_getSVGValue()) + Glib::ustring(","); SPItem * orig = SP_ITEM(linkeditem.getObject()); SPItem * dest = SP_ITEM(sp_lpe_item); @@ -259,8 +257,6 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } linked = g_strdup(id); - g_free(style_attributes_str); - g_free(attributes_str); g_free(id); } else { linked = g_strdup(""); @@ -340,7 +336,7 @@ LPECloneOriginal::doEffect (SPCurve * curve) // if (linkeditem.linksToItem()) { // SPShape * shape = getCurrentShape(); // if(shape){ -// curve->set_pathvector(shape->getCurveForEdit()->get_pathvector()); +// curve->set_pathvector(shape->getCurveBeforeLPE()->get_pathvector()); // } // } } diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 6bf2a78bd3..ebcb95f0da 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,7 +17,6 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/intersection-graph.h> #include "live_effects/lpe-copy_rotate.h" -#include "live_effects/lpeobject.h" #include "display/curve.h" #include "svg/path-string.h" #include "svg/svg.h" @@ -56,6 +55,7 @@ pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const & return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; } + LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), method(_("Method:"), _("Rotate methods"), "method", RMConverter, &wr, this, RM_NORMAL), @@ -66,7 +66,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), gap(_("Gap"), _("Gap"), "gap", &wr, this, -0.0001), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, true), + mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, false), split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), dist_angle_handle(100.0) { @@ -129,15 +129,12 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) if (numcopies_gap > 0 && num_copies != 0) { guint counter = num_copies - 1; while (numcopies_gap > 0) { - Glib::ustring id = Glib::ustring("rotated-"); - id += std::to_string(counter); - id += "-"; - id += this->lpeobj->getId(); - if (id.empty()) { + const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + if (!id || strlen(id) == 0) { return; } SPObject *elemref = NULL; - if (elemref = document->getObjectById(id.c_str())) { + if ((elemref = document->getObjectById(id))) { SP_ITEM(elemref)->setHidden(true); } counter++; @@ -147,14 +144,10 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) previous_num_copies = num_copies; } SPObject *elemref = NULL; + const char * id = g_strdup(Glib::ustring("rotated-").append("0").append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); guint counter = 0; - Glib::ustring id = "rotated-0-"; - id += this->lpeobj->getId(); - while((elemref = document->getObjectById(id.c_str()))) { - id = Glib::ustring("rotated-"); - id += std::to_string(counter); - id += "-"; - id += this->lpeobj->getId(); + while((elemref = document->getObjectById(id))) { + id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); if (SP_ITEM(elemref)->isHidden()) { items.push_back(id); } @@ -191,7 +184,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } void -LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset) +LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -204,29 +197,30 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, transform, reset); + cloneD(*obj_it, dest_child, transform, false, reset); index++; } - return; } SPShape * shape = SP_SHAPE(orig); - SPPath * path = SP_PATH(dest); - if (shape && !path) { + if (shape && !SP_IS_PATH(dest)) { const char * id = dest->getId(); Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); dest->getRepr()->setAttribute("d", id); - path = SP_PATH(dest); } - if (path && shape) { - SPCurve *c = shape->getCurve(); + if (SP_IS_PATH(dest) && shape) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_after_effect); + } else { + c = shape->getCurve(); + } if (c) { - gchar *str = sp_svg_write_path(c->get_pathvector()); - path->getRepr()->setAttribute("d", str); - g_free(str); + SP_PATH(dest)->setCurve(c, TRUE); c->unref(); } else { - path->getRepr()->setAttribute("d", NULL); + dest->getRepr()->setAttribute("d", NULL); } if (reset) { dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); @@ -234,33 +228,6 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } } -Inkscape::XML::Node * -LPECopyRotate::createPathBase(SPObject *elemref) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return NULL; - } - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::XML::Node *prev = elemref->getRepr(); - SPGroup *group = dynamic_cast(elemref); - if (group) { - Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); - container->setAttribute("transform", prev->attribute("transform")); - std::vector const item_list = sp_item_group_item_list(group); - Inkscape::XML::Node *previous = NULL; - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *sub_item = *iter; - Inkscape::XML::Node *resultnode = createPathBase(sub_item); - container->addChild(resultnode, previous); - previous = resultnode; - } - return container; - } - Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); - resultnode->setAttribute("transform", prev->attribute("transform")); - return resultnode; -} - void LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) { @@ -269,32 +236,64 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Glib::ustring elemref_id = Glib::ustring("rotated-"); - elemref_id += std::to_string(i); - elemref_id += "-"; - elemref_id += this->lpeobj->getId(); + const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; - if (elemref = document->getObjectById(elemref_id.c_str())) { + if ((elemref = document->getObjectById(elemref_id))) { phantom = elemref->getRepr(); } else { - phantom = createPathBase(sp_lpe_item); - phantom->setAttribute("id", elemref_id.c_str()); - reset = true; + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + std::vector attrs; + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); + phantom->setAttribute("id", elemref_id); + for(const char * attr : attrs) { + phantom->setAttribute(attr, NULL); + } } if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, reset); + cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, true, reset); gchar *str = sp_svg_transform_write(transform); elemref->getRepr()->setAttribute("transform" , str); g_free(str); SP_ITEM(elemref)->setHidden(false); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id.c_str()); + copy->setAttribute("id", elemref_id); container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); @@ -341,9 +340,6 @@ Gtk::Widget * LPECopyRotate::newWidget() reset_button->set_size_request(110,20); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -352,7 +348,7 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); @@ -379,7 +375,7 @@ void LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); if (copies_to_360 && num_copies > 2) { rotation_angle.param_set_value(360.0/(double)num_copies); } @@ -715,7 +711,7 @@ void LPECopyRotate::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item)); } void diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index dcbd1c45eb..a0a3d4dc15 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,8 +48,7 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toItem(Geom::Affine transform, size_t i, bool reset); - void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset); - Inkscape::XML::Node * createPathBase(SPObject *elemref); + void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset); void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index 0dcae51e41..b50efde345 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -42,7 +42,7 @@ void LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); } Geom::Piecewise > @@ -218,7 +218,7 @@ LPEEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item)); Geom::Point Up_Left(boundingbox_X.min(), boundingbox_Y.min()); Geom::Point Up_Right(boundingbox_X.max(), boundingbox_Y.min()); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 59a6324e75..94a43b728a 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -111,9 +111,7 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - gchar * mode_str = mode.param_getSVGValue(); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); - g_free(mode_str); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } @@ -252,9 +250,7 @@ Gtk::Widget *LPEFilletChamfer::newWidget() vbox->pack_start(*fillet_container, true, true, 2); vbox->pack_start(*chamfer_container, true, true, 2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } + return vbox; } @@ -324,14 +320,14 @@ void LPEFilletChamfer::setSelected(PathVectorSatellites *_pathvector_satellites) void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) { - if (!pathvector_before_effect.empty()) { + if (sp_curve) { //fillet chamfer specific calls satellites_param.setUseDistance(use_knot_distance); satellites_param.setCurrentZoom(current_zoom); //mandatory call satellites_param.setEffectType(effectType()); - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); - //if are diferent sizes call to recalculate + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); + //if are different sizes call to recalculate //TODO: Update the satellite data in paths modified, Satellites satellites = satellites_param.data(); if (satellites.empty()) { @@ -342,6 +338,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) size_t number_nodes = pathv.nodes().size(); size_t previous_number_nodes = _pathvector_satellites->getTotalSatellites(); if (number_nodes != previous_number_nodes) { + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); Satellites satellites; double power = radius; if (!flexible) { @@ -353,9 +350,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - gchar * mode_str = mode.param_getSVGValue(); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); - g_free(mode_str); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index 70bc92a27f..f6b42cfb92 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -104,7 +104,7 @@ LPEInterpolate::resetDefaults(SPItem const* item) if (!SP_IS_PATH(item)) return; - SPCurve const *crv = SP_PATH(item)->getCurveForEdit(true); + SPCurve const *crv = SP_PATH(item)->get_curve_reference(); Geom::PathVector const &pathv = crv->get_pathvector(); if ( (pathv.size() < 2) ) return; diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index df4da45905..124a7a9c6a 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -164,7 +164,7 @@ LPELattice::doEffect_pwd2 (Geom::Piecewise > const & pwd2 void LPELattice::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); } void @@ -172,7 +172,7 @@ LPELattice::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item), false); // place the 16 control points grid_point0[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 8c2c3ec317..3eeb6e746a 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -268,9 +268,6 @@ LPELattice2::newWidget() expander->set_expanded(expanded); vbox->pack_start(*expander, true, true, 2); expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPELattice2::onExpanderChanged) ); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -330,7 +327,7 @@ LPELattice2::horizontal(PointParam ¶m_one, PointParam ¶m_two, Geom::Line void LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); setDefaults(); Geom::Line vert(grid_point_8x9.param_get_default(),grid_point_10x11.param_get_default()); Geom::Line horiz(grid_point_24x26.param_get_default(),grid_point_25x27.param_get_default()); @@ -554,7 +551,7 @@ void LPELattice2::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item)); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index cff5aec4b8..9bfa2c52e8 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -8,40 +8,36 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include -#include "2geom/affine.h" -#include "2geom/angle.h" -#include "2geom/point.h" -#include "2geom/ray.h" +#include "live_effects/lpe-measure-segments.h" +#include "live_effects/lpeobject.h" +#include +#include "ui/dialog/livepatheffect-editor.h" +#include +#include "inkscape.h" +#include "xml/node.h" +#include "xml/sp-css-attr.h" +#include "preferences.h" +#include "util/units.h" +#include "svg/svg-length.h" +#include "svg/svg-color.h" +#include "svg/stringstream.h" +#include "svg/svg.h" #include "display/curve.h" #include "helper/geom.h" -#include "live_effects/lpe-measure-segments.h" +#include "2geom/affine.h" +#include "path-chemistry.h" +#include "document.h" +#include "document-undo.h" +#include +#include + +#include "object/sp-root.h" #include "object/sp-defs.h" #include "object/sp-item.h" -#include "object/sp-path.h" -#include "object/sp-root.h" #include "object/sp-shape.h" +#include "object/sp-path.h" #include "object/sp-star.h" #include "object/sp-spiral.h" -#include "svg/stringstream.h" -#include "svg/svg.h" -#include "svg/svg-color.h" -#include "svg/svg-length.h" -#include "util/units.h" -#include "xml/node.h" -#include "xml/sp-css-attr.h" - -#include "document.h" -#include "document-undo.h" -#include "inkscape.h" -#include "preferences.h" -#include "path-chemistry.h" - -#include -#include -#include -#include // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -50,11 +46,10 @@ using namespace Geom; namespace Inkscape { namespace LivePathEffect { - static const Util::EnumData OrientationMethodData[] = { - { OM_HORIZONTAL , N_("Horizontal"), "horizontal" }, - { OM_VERTICAL , N_("Vertical") , "vertical" }, - { OM_PARALLEL , N_("Parallel") , "parallel" } + { OM_HORIZONTAL, N_("Horizontal"), "horizontal" }, + { OM_VERTICAL, N_("Vertical"), "vertical" }, + { OM_PARALLEL, N_("Parallel"), "parallel" } }; static const Util::EnumDataConverter OMConverter(OrientationMethodData, OM_END); @@ -107,6 +102,7 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : registerParameter(&rotate_anotation); registerParameter(&hide_back); registerParameter(&message); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring format_value = prefs->getString("/live_effects/measure-line/format"); @@ -144,26 +140,21 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_increments(1, 1); helpline_overlap.param_set_digits(2); star_ellipse_fix = Geom::identity(); - locale_base = strdup(setlocale(LC_NUMERIC, NULL)); - message.param_set_min_height(85); - previous_size = 0; + message.param_set_min_height(95); } -LPEMeasureSegments::~LPEMeasureSegments() { - doOnRemove(NULL); -} +LPEMeasureSegments::~LPEMeasureSegments() {} void -LPEMeasureSegments::createArrowMarker(Glib::ustring mode) +LPEMeasureSegments::createArrowMarker(const char * mode) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } - Glib::ustring lpobjid = this->lpeobj->getId(); - Glib::ustring itemid = sp_lpe_item->getId(); Glib::ustring style; gchar c[32]; + unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); style = Glib::ustring("fill:") + Glib::ustring(c); Inkscape::SVGOStringStream os; @@ -172,7 +163,7 @@ LPEMeasureSegments::createArrowMarker(Glib::ustring mode) Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref = NULL; Inkscape::XML::Node *arrow = NULL; - if ((elemref = document->getObjectById(mode.c_str()))) { + if ((elemref = document->getObjectById(mode))) { Inkscape::XML::Node *arrow= elemref->getRepr(); if (arrow) { arrow->setAttribute("sodipodi:insensitive", "true"); @@ -185,13 +176,9 @@ LPEMeasureSegments::createArrowMarker(Glib::ustring mode) } } else { arrow = xml_doc->createElement("svg:marker"); - arrow->setAttribute("id", mode.c_str()); - Glib::ustring classarrow = itemid; - classarrow += " "; - classarrow += lpobjid; - classarrow += " measure-arrows-marker"; - arrow->setAttribute("class", classarrow.c_str()); - arrow->setAttribute("inkscape:stockid", mode.c_str()); + arrow->setAttribute("id", mode); + arrow->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows-marker")).c_str()); + arrow->setAttribute("inkscape:stockid", mode); arrow->setAttribute("orient", "auto"); arrow->setAttribute("refX", "0.0"); arrow->setAttribute("refY", "0.0"); @@ -199,22 +186,17 @@ LPEMeasureSegments::createArrowMarker(Glib::ustring mode) arrow->setAttribute("sodipodi:insensitive", "true"); /* Create */ Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path"); - if (std::strcmp(mode.c_str(), "ArrowDIN-start") == 0) { + if (std::strcmp(mode, "ArrowDIN-start") == 0) { arrow_path->setAttribute("d", "M -8,0 8,-2.11 8,2.11 z"); - } else if (std::strcmp(mode.c_str(), "ArrowDIN-end") == 0) { + } else if (std::strcmp(mode, "ArrowDIN-end") == 0) { arrow_path->setAttribute("d", "M 8,0 -8,2.11 -8,-2.11 z"); - } else if (std::strcmp(mode.c_str(), "ArrowDINout-start") == 0) { + } else if (std::strcmp(mode, "ArrowDINout-start") == 0) { arrow_path->setAttribute("d", "M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z"); } else { arrow_path->setAttribute("d", "M 0,0 16,-2.11 16,-0.5 26,-0.5 26,0.5 16,0.5 16,2.11 z"); } - Glib::ustring classarrowpath = itemid; - classarrowpath += " "; - classarrowpath += lpobjid; - classarrowpath += " measure-arrows"; - arrow_path->setAttribute("class", classarrowpath.c_str()); - Glib::ustring arrowpath = mode + Glib::ustring("_path"); - arrow_path->setAttribute("id", arrowpath.c_str()); + arrow_path->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows")).c_str()); + arrow_path->setAttribute("id", Glib::ustring(mode).append("_path").c_str()); arrow_path->setAttribute("style", style.c_str()); arrow->addChild(arrow_path, NULL); Inkscape::GC::release(arrow_path); @@ -234,48 +216,72 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *rtext = NULL; double doc_w = document->getRoot()->width.value; - - Glib::ustring lpobjid = this->lpeobj->getId(); - Glib::ustring itemid = sp_lpe_item->getId(); - Glib::ustring id = Glib::ustring("text-on-"); - id += Glib::ustring::format(counter); - id += "-"; - id += lpobjid; + Geom::Scale scale = document->getDocumentScale(); + SPNamedView *nv = sp_document_namedview(document, NULL); + Glib::ustring display_unit = nv->display_units->abbr; + if (display_unit.empty()) { + display_unit = "px"; + } + //only check constrain viewbox on X + doc_scale = Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units ); + if( doc_scale > 0 ) { + doc_scale= 1.0/doc_scale; + } else { + doc_scale = 1.0; + } + const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; - elemref = document->getObjectById(id.c_str()); - - if (elemref) { + if ((elemref = document->getObjectById(id))) { + if (remove) { + elemref->deleteObject(); + return; + } rtext = elemref->getRepr(); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtext->setAttribute("sodipodi:insensitive", "true"); rtext->setAttribute("transform", NULL); } else { + if (remove) { + return; + } rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); - rtext->setAttribute("id", id.c_str()); - Glib::ustring classlabel = itemid; - classlabel += " "; - classlabel += lpobjid; - classlabel += " measure-labels"; - rtext->setAttribute("class", classlabel.c_str()); + rtext->setAttribute("id", id); + rtext->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-labels")).c_str()); rtext->setAttribute("sodipodi:insensitive", "true"); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtspan = xml_doc->createElement("svg:tspan"); rtspan->setAttribute("sodipodi:role", "line"); } + gchar * transform; + Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); + angle = std::fmod(angle, 2*M_PI); + if (angle < 0) angle += 2*M_PI; + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { + angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); + if (angle < 0) angle += 2*M_PI; + } + affine *= Geom::Rotate(angle); + affine *= Geom::Translate(pos); + if (rotate_anotation) { + transform = sp_svg_transform_write(affine); + } else { + transform = NULL; + } + rtext->setAttribute("transform", transform); + g_free(transform); SPCSSAttr *css = sp_repr_css_attr_new(); Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); - gchar * fontbutton_str = fontbutton.param_getSVGValue(); - fontlister->fill_css(css, Glib::ustring(fontbutton_str)); - g_free(fontbutton_str); + fontlister->fill_css(css, Glib::ustring(fontbutton.param_getSVGValue())); std::stringstream font_size; - setlocale (LC_NUMERIC, "C"); + font_size.imbue(std::locale::classic()); font_size << fontsize << "pt"; - setlocale (LC_NUMERIC, locale_base); + gchar c[32]; + unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); sp_repr_css_set_property (css, "fill",c); Inkscape::SVGOStringStream os; @@ -285,14 +291,10 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtspan = rtext->firstChild(); } sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); - if (remove) { - sp_repr_css_set_property (css, "display","hidden"); - } - sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); Glib::ustring css_str; sp_repr_css_write_string(css,css_str); rtext->setAttribute("style", css_str.c_str()); - rtspan->setAttribute("style", css_str.c_str()); + rtspan->setAttribute("style", NULL); rtspan->setAttribute("transform", NULL); sp_repr_css_attr_unref (css); if (!elemref) { @@ -300,6 +302,7 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::GC::release(rtspan); } length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation()); + char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); if (local_locale) { setlocale (LC_NUMERIC, ""); } else { @@ -307,10 +310,9 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng } gchar length_str[64]; g_snprintf(length_str, 64, "%.*f", (int)precision, length); - setlocale (LC_NUMERIC, locale_base); - gchar * format_str = format.param_getSVGValue(); - Glib::ustring label_value(format_str); - g_free(format_str); + setlocale (LC_NUMERIC, oldlocale); + g_free (oldlocale); + Glib::ustring label_value(format.param_getSVGValue()); size_t s = label_value.find(Glib::ustring("{measure}"),0); if(s < label_value.length()) { label_value.replace(s,s+9,length_str); @@ -339,53 +341,26 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - sp_object_ref(elemref, 0 ); - elemref->deleteObject(true); - sp_object_unref(elemref); - copy->setAttribute("id", id.c_str()); + elemref->deleteObject(); + copy->setAttribute("id", id); elemref = elemref_copy; } - SP_ITEM(elemref)->updateRepr(); + items.push_back(id); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.15; - rtspan->setAttribute("style", NULL); } - gchar * transform; - if (rotate_anotation) { - Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); - angle = std::fmod(angle, 2*M_PI); - if (angle < 0) angle += 2*M_PI; - if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); - if (angle < 0) angle += 2*M_PI; - } - affine *= Geom::Rotate(angle); - affine *= Geom::Translate(pos); - transform = sp_svg_transform_write(affine); - } else { - transform = NULL; - } - rtext->setAttribute("transform", transform); - g_free(transform); } void -LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows) +LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } - Glib::ustring lpobjid = this->lpeobj->getId(); - Glib::ustring itemid = sp_lpe_item->getId(); - Glib::ustring id = name; - id += Glib::ustring::format(counter); - id += "-"; - id += lpobjid; - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - SPObject *elemref = document->getObjectById(id.c_str()); + SPObject *elemref = NULL; Inkscape::XML::Node *line = NULL; if (!main) { Geom::Ray ray(start, end); @@ -394,13 +369,25 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring end = end + Point::polar(angle, helpline_overlap ); } Geom::PathVector line_pathv; - - double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); + if (main && std::abs(text_top_bottom) < fontsize/1.5 && - hide_back && - k > 0) + hide_back) { + double k = 0; + if (flip_side) { + k = (Geom::distance(start,end)/2.0) + arrow_gap - (anotation_width/2.0); + } else { + k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0); + } + if (Geom::distance(start,end) < anotation_width){ + if ((elemref = document->getObjectById(id))) { + if (remove) { + elemref->deleteObject(); + } + return; + } + } //k = std::max(k , arrow_gap -1); Geom::Ray ray(end, start); Geom::Coord angle = ray.angle(); @@ -416,7 +403,11 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring line_path.appendNew(end); line_pathv.push_back(line_path); } - if (elemref) { + if ((elemref = document->getObjectById(id))) { + if (remove) { + elemref->deleteObject(); + return; + } line = elemref->getRepr(); gchar * line_str = sp_svg_write_path( line_pathv ); @@ -424,59 +415,46 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring line->setAttribute("transform", NULL); g_free(line_str); } else { + if (remove) { + return; + } line = xml_doc->createElement("svg:path"); - line->setAttribute("id", id.c_str()); + line->setAttribute("id", id); if (main) { - Glib::ustring classlinedim = itemid; - classlinedim += " "; - classlinedim += lpobjid; - classlinedim += " measure-DIM-lines measure-lines"; - line->setAttribute("class", classlinedim.c_str()); + line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-DIM-lines measure-lines")).c_str()); } else { - Glib::ustring classlinehelper = itemid; - classlinehelper += " "; - classlinehelper += lpobjid; - classlinehelper += " measure-helper-lines measure-lines"; - line->setAttribute("class", classlinehelper.c_str()); + line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-helper-lines measure-lines")).c_str()); } gchar * line_str = sp_svg_write_path( line_pathv ); line->setAttribute("d" , line_str); g_free(line_str); } - line->setAttribute("sodipodi:insensitive", "true"); line_pathv.clear(); Glib::ustring style; - if (remove) { - style ="display:none;"; - } if (main) { line->setAttribute("inkscape:label", "dinline"); if (arrows_outside) { - style += "marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"; + style = style + Glib::ustring("marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"); } else { - style += "marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"; + style = style + Glib::ustring("marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"); } } else { line->setAttribute("inkscape:label", "dinhelpline"); } std::stringstream stroke_w; - setlocale (LC_NUMERIC, "C"); - + stroke_w.imbue(std::locale::classic()); double stroke_width = Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); stroke_w << stroke_width; - setlocale (LC_NUMERIC, locale_base); - style += "stroke-width:"; - style += stroke_w.str(); + style = style + Glib::ustring("stroke-width:" + stroke_w.str()); gchar c[32]; + unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); - style += ";stroke:"; - style += Glib::ustring(c); + style = style + Glib::ustring(";stroke:") + Glib::ustring(c); Inkscape::SVGOStringStream os; os << SP_RGBA32_A_F(coloropacity.get_value()); - style += ";stroke-opacity:"; - style += os.str(); + style = style + Glib::ustring(";stroke-opacity:") + Glib::ustring(os.str()); SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, style.c_str()); Glib::ustring css_str; @@ -490,11 +468,10 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - sp_object_ref(elemref, 0 ); - elemref->deleteObject(true); - sp_object_unref(elemref); - copy->setAttribute("id", id.c_str()); + elemref->deleteObject(); + copy->setAttribute("id", id); } + items.push_back(id); } void @@ -557,9 +534,7 @@ LPEMeasureSegments::doOnApply(SPLPEItem const* lpeitem) bool LPEMeasureSegments::hasMeassure (size_t i) { - gchar * blacklist_str = blacklist.param_getSVGValue(); - std::string listsegments(std::string(blacklist_str) + std::string(",")); - g_free(blacklist_str); + std::string listsegments(std::string(blacklist.param_getSVGValue()) + std::string(",")); listsegments.erase(std::remove(listsegments.begin(), listsegments.end(), ' '), listsegments.end()); size_t s = listsegments.find(std::to_string(i) + std::string(","),0); if(s < listsegments.length()) { @@ -596,6 +571,7 @@ void LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) { SPLPEItem * splpeitem = const_cast(lpeitem); + SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; @@ -608,38 +584,16 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) SPShape *shape = dynamic_cast(splpeitem); if (shape) { - //only check constrain viewbox on X - Geom::Scale scaledoc = document->getDocumentScale(); - SPNamedView *nv = sp_document_namedview(document, NULL); - display_unit = nv->display_units->abbr; - if (display_unit.empty()) { - display_unit = "px"; - } - doc_scale = Inkscape::Util::Quantity::convert( scaledoc[Geom::X], "px", display_unit.c_str() ); - if( doc_scale > 0 ) { - doc_scale= 1.0/doc_scale; + SPCurve * c = NULL; + + SPPath *path = dynamic_cast(shape); + if (path) { + c = path->get_original_curve(); } else { - doc_scale = 1.0; - } - unsigned const color = coloropacity.get_value() >> 8; - bool colorchanged = false; - if (color != rgb24) { - colorchanged = true; + c = shape->getCurve(); } - rgb24 = color; - SPCurve * c = NULL; - gchar * fontbutton_str = fontbutton.param_getSVGValue(); - Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); - Pango::FontDescription fontdesc(fontdesc_ustring); - fontsize = fontdesc.get_size()/(double)Pango::SCALE; - fontsize *= document->getRoot()->c2p.inverse().expansionX(); - g_free(fontbutton_str); - fontsize *= document->getRoot()->c2p.inverse().expansionX(); - c = shape->getCurve(); - Geom::Point prev_stored = Geom::Point(0,0); - Geom::Point start_stored = Geom::Point(0,0); - Geom::Point end_stored = Geom::Point(0,0); - Geom::Point next_stored = Geom::Point(0,0); + Geom::Point start_stored; + Geom::Point end_stored; Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem->parent), SP_OBJECT(document->getRoot())); Geom::PathVector pathvector = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); c->unref(); @@ -651,137 +605,55 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { pathvector *= writed_transform; } - gchar * format_str = format.param_getSVGValue(); - if (Glib::ustring(format_str).empty()) { + if ((Glib::ustring(format.param_getSVGValue()).empty())) { format.param_setValue(Glib::ustring("{measure}{unit}")); } - g_free(format_str); size_t ncurves = pathvector.curveCount(); items.clear(); double start_angle_cross = 0; double end_angle_cross = 0; - gint counter = -1; - Glib::ustring lpobjid = this->lpeobj->getId(); - bool previous_fix_overlaps = true; + size_t counter = -1; for (size_t i = 0; i < pathvector.size(); i++) { for (size_t j = 0; j < pathvector[i].size(); j++) { counter++; - gint fix_overlaps_degree = fix_overlaps; - Geom::Point prev = Geom::Point(0,0); - if (j == 0 && pathvector[i].closed()) { - prev = pathvector.pointAt(pathvector[i].size() - 1); - } else if (j != 0) { - prev = pathvector[i].pointAt(j - 1); - } - Geom::Point start = pathvector[i].pointAt(j); - Geom::Point end = pathvector[i].pointAt(j + 1); - Geom::Point next = Geom::Point(0,0); - if(pathvector[i].closed() && pathvector[i].size() == j+1){ - end = pathvector[i].pointAt(0); - next = pathvector[i].pointAt(1); - } else if (pathvector[i].size() > j + 1) { - next = pathvector[i].pointAt(j+2); - } - if(hasMeassure(counter) && !Geom::are_near(start, end)) { - Glib::ustring idprev = Glib::ustring("infoline-on-start-"); - idprev += Glib::ustring::format(counter-1); - idprev += "-"; - idprev += lpobjid; - SPObject *elemref = NULL; - if (elemref = document->getObjectById(idprev.c_str())) { - SPPath* path = dynamic_cast(elemref); - if (path) { - SPCurve* prevcurve = path->getCurve(); - if (prevcurve) { - prev_stored = *prevcurve->first_point(); - } - prevcurve->unref(); - } + if(hasMeassure(counter + 1)) { + Geom::Point prev = Geom::Point(0,0); + if (j == 0 && pathvector[i].closed()) { + prev = pathvector.pointAt(pathvector[i].size() - 1); + } else if (j != 0) { + prev = pathvector[i].pointAt(j - 1); } - Glib::ustring idstart = Glib::ustring("infoline-on-start-"); - idstart += Glib::ustring::format(counter); - idstart += "-"; - idstart += lpobjid; - elemref = NULL; - if (elemref = document->getObjectById(idstart.c_str())) { - SPPath* path = dynamic_cast(elemref); - if (path) { - SPCurve* startcurve = path->getCurve(); - if (startcurve) { - start_stored = *startcurve->first_point(); - } - startcurve->unref(); - } + Geom::Point start = pathvector[i].pointAt(j); + Geom::Point end = pathvector[i].pointAt(j + 1); + Geom::Point next = Geom::Point(0,0); + if(pathvector[i].closed() && pathvector[i].size() == j+1){ + end = pathvector[i].pointAt(0); + next = pathvector[i].pointAt(1); + } else if (pathvector[i].size() > j + 1) { + next = pathvector[i].pointAt(j+2); } - Glib::ustring idend = Glib::ustring("infoline-on-end-"); - idend += Glib::ustring::format(counter); - idend += "-"; - idend += lpobjid; - elemref = NULL; - if (elemref = document->getObjectById(idend.c_str())) { - SPPath* path = dynamic_cast(elemref); - if (path) { - SPCurve* endcurve = path->getCurve(); - if (endcurve) { - end_stored = *endcurve->first_point(); - } - endcurve->unref(); - } + const char * idstart = Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); + SPObject *elemref = NULL; + if ((elemref = document->getObjectById(idstart))) { + start_stored = *SP_PATH(elemref)->get_curve()->first_point(); } - Glib::ustring idnext = Glib::ustring("infoline-on-start-"); - idnext += Glib::ustring::format(counter+1); - idnext += "-"; - idnext += lpobjid; + const char * idend = Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); elemref = NULL; - if (elemref = document->getObjectById(idnext.c_str())) { - SPPath* path = dynamic_cast(elemref); - if (path) { - SPCurve* nextcurve = path->getCurve(); - if (nextcurve) { - next_stored = *nextcurve->first_point(); - } - nextcurve->unref(); - } + if ((elemref = document->getObjectById(idend))) { + end_stored = *SP_PATH(elemref)->get_curve()->first_point(); } - Glib::ustring infoline_on_start = "infoline-on-start-"; - infoline_on_start += Glib::ustring::format(counter); - infoline_on_start += "-"; - infoline_on_start += lpobjid; - items.push_back(infoline_on_start); - Glib::ustring infoline_on_end = "infoline-on-end-"; - infoline_on_end += Glib::ustring::format(counter); - infoline_on_end += "-"; - infoline_on_end += lpobjid; - items.push_back(infoline_on_end); - Glib::ustring infoline = "infoline-"; - infoline += Glib::ustring::format(counter); - infoline += "-"; - infoline += lpobjid; - items.push_back(infoline); - Glib::ustring texton = "text-on-"; - texton += Glib::ustring::format(counter); - texton += "-"; - texton += lpobjid; - items.push_back(texton); - if (arrows_outside) { - items.push_back(Glib::ustring("ArrowDINout-start")); - items.push_back(Glib::ustring("ArrowDINout-end")); - } else { - items.push_back(Glib::ustring("ArrowDIN-start")); - items.push_back(Glib::ustring("ArrowDIN-end")); - } - if ((Geom::are_near(prev, prev_stored, 0.01) && Geom::are_near(next, next_stored, 0.01) || - fix_overlaps_degree == 180) && - Geom::are_near(start, start_stored, 0.01) && - Geom::are_near(end, end_stored, 0.01) && - !this->upd_params && - !colorchanged) + if (Geom::are_near(start, start_stored, 0.01) && + Geom::are_near(end, end_stored, 0.01)) { continue; } Geom::Point hstart = start; Geom::Point hend = end; bool remove = false; + if (Geom::are_near(hstart, hend)) { + remove = true; + } + if (orientation == OM_VERTICAL) { Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]); if (flip_side) { @@ -810,23 +682,16 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (Geom::are_near(hstart[Geom::X], hend[Geom::X])) { remove = true; } - } else if (fix_overlaps_degree != 180) { - start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps_degree); + } else if (fix_overlaps != 180) { + start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps); if (prev == Geom::Point(0,0)) { start_angle_cross = 0; } - end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps_degree); + end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps); if (next == Geom::Point(0,0)) { end_angle_cross = 0; } } - if (remove) { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); - continue; - } Geom::Ray ray(hstart,hend); Geom::Coord angle = ray.angle(); if (flip_side) { @@ -843,42 +708,36 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) start_angle_cross *= -1; //turn *= -1; } - double position_turned_start = position / sin(start_angle_cross/2.0); - double length = Geom::distance(start,end); - if (fix_overlaps_degree != 180 && - start_angle_cross != 0 && - position_turned_start < length && - previous_fix_overlaps) - { - hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned_start); + if (fix_overlaps != 180 && start_angle_cross != 0) { + double position_turned = position / sin(start_angle_cross/2.0); + hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned); } else { hstart = hstart - Point::polar(angle_cross, position); } - createLine(start, hstart, Glib::ustring("infoline-on-start-"), counter, false, false); - double position_turned_end = position / sin(end_angle_cross/2.0); - double endlength = Geom::distance(end,next); - if (fix_overlaps_degree != 180 && - end_angle_cross != 0 && - position_turned_end < length && - position_turned_end < endlength) - { - hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned_end); - previous_fix_overlaps = true; + createLine(start, hstart, g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); + + if (fix_overlaps != 180 && end_angle_cross != 0) { + double position_turned = position / sin(end_angle_cross/2.0); + hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned); } else { hend = hend - Point::polar(angle_cross, position); - previous_fix_overlaps = false; } - length = Geom::distance(start,end) * scale; + double length = Geom::distance(hstart,hend) * scale; Geom::Point pos = Geom::middle_point(hstart,hend); if (arrows_outside) { - createArrowMarker(Glib::ustring("ArrowDINout-start")); - createArrowMarker(Glib::ustring("ArrowDINout-end")); + createArrowMarker("ArrowDINout-start"); + createArrowMarker("ArrowDINout-end"); } else { - createArrowMarker(Glib::ustring("ArrowDIN-start")); - createArrowMarker(Glib::ustring("ArrowDIN-end")); + createArrowMarker("ArrowDIN-start"); + createArrowMarker("ArrowDIN-end"); } + //We get the font size to offset the text to the middle + Pango::FontDescription fontdesc(Glib::ustring(fontbutton.param_getSVGValue())); + fontsize = fontdesc.get_size()/(double)Pango::SCALE; + fontsize *= document->getRoot()->c2p.inverse().expansionX(); + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); + pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } else { pos = pos + Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } @@ -894,42 +753,55 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { createTextLabel(pos, counter, length, angle, remove, true); } + const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); + char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); setlocale (LC_NUMERIC, "C"); double width_line = atof(sp_repr_css_property(css,"stroke-width","-1")); - setlocale (LC_NUMERIC, locale_base); + setlocale (LC_NUMERIC, oldlocale); + g_free (oldlocale); if (width_line > -0.0001) { arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str()); } if(flip_side) { arrow_gap *= -1; } - createLine(end, hend, Glib::ustring("infoline-on-end-"), counter, false, false); + createLine(end, hend, g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); if (!arrows_outside) { hstart = hstart + Point::polar(angle, arrow_gap); hend = hend - Point::polar(angle, arrow_gap ); } - if ((anotation_width/2.0) + arrow_gap < Geom::distance(hstart,hend)/2.0) { - createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, false, true); + if ((anotation_width/2) < Geom::distance(hstart,hend)/2.0) { + createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, remove, true); } else { - createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, true, true); + createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); } } else { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); + const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + createLine(Geom::Point(),Geom::Point(), downline, true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + SPObject *elemref = NULL; + if ((elemref = document->getObjectById(id))) { + elemref->deleteObject(); + } } } } - if (previous_size) { - for (size_t counter = ncurves; counter < previous_size; counter++) { - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); - createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); - createTextLabel(Geom::Point(), counter, 0, 0, true, true); + for (size_t k = ncurves; k <= previous_size; k++) { + const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + createLine(Geom::Point(),Geom::Point(), downline, true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + SPObject *elemref = NULL; + if ((elemref = document->getObjectById(id))) { + elemref->deleteObject(); } } previous_size = ncurves; @@ -965,6 +837,12 @@ LPEMeasureSegments::transform_multiply(Geom::Affine const& postmul, bool set) } } +Geom::PathVector +LPEMeasureSegments::doEffect_path(Geom::PathVector const &path_in) +{ + return path_in; +} + }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index 1b6a5a81d7..903a5cbd27 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -11,16 +11,19 @@ */ #include "live_effects/effect.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" -#include "live_effects/parameter/bool.h" -#include "live_effects/parameter/colorpicker.h" +#include "ui/dialog/styledialog.h" + #include "live_effects/parameter/enum.h" #include "live_effects/parameter/fontbutton.h" -#include "live_effects/parameter/message.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/unit.h" - +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/colorpicker.h" +#include "live_effects/parameter/message.h" +#include +#include <2geom/angle.h> +#include <2geom/ray.h> +#include <2geom/point.h> namespace Inkscape { namespace LivePathEffect { @@ -36,15 +39,16 @@ class LPEMeasureSegments : public Effect { public: LPEMeasureSegments(LivePathEffectObject *lpeobject); virtual ~LPEMeasureSegments(); - virtual void doOnApply(SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void doOnRemove(SPLPEItem const* /*lpeitem*/); - virtual void doEffect(SPCurve * curve){}; //stop the chain + virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doEffect (SPCurve * curve){}; //stop the chain virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual void transform_multiply(Geom::Affine const& postmul, bool set); - void createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows = false); + virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); + void createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows = false); void createTextLabel(Geom::Point pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid); - void createArrowMarker(Glib::ustring mode); + void createArrowMarker(const char * mode); bool hasMeassure (size_t i); private: UnitParam unit; @@ -74,9 +78,7 @@ private: double fontsize; double anotation_width; double previous_size; - unsigned rgb24; double arrow_gap; - gchar const* locale_base; Geom::Affine star_ellipse_fix; LPEMeasureSegments(const LPEMeasureSegments &); LPEMeasureSegments &operator=(const LPEMeasureSegments &); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 1e62a98d51..926977a07b 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -15,6 +15,8 @@ */ #include +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -39,7 +41,7 @@ namespace Inkscape { namespace LivePathEffect { -static const Util::EnumData ModeTypeData[] = { +static const Util::EnumData ModeTypeData[MT_END] = { { MT_V, N_("Vertical Page Center"), "vertical" }, { MT_H, N_("Horizontal Page Center"), "horizontal" }, { MT_FREE, N_("Free from reflection line"), "free" }, @@ -49,7 +51,6 @@ static const Util::EnumData ModeTypeData[] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); - LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -60,7 +61,8 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), + id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") { show_orig_path = true; registerParameter(&mode); @@ -72,13 +74,15 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); + registerParameter(&id_origin); + id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(5); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); + id_origin.param_widget_is_visible(false); center_point.param_widget_is_visible(false); - reset = false; } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -93,71 +97,30 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) if (!document) { return; } - container = dynamic_cast(sp_lpe_item->parent); - Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); - Inkscape::XML::Node *root_origin = document->getReprRoot(); - if (root_origin != root) { - return; - } - if (split_items && !discard_orig_path) { + container = dynamic_cast(sp_lpe_item->parent); + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = document->getReprRoot(); + if (root_origin != root) { + return; + } Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); m = m * sp_lpe_item->transform; - toMirror(m, reset); - reset = false; + toMirror(m); } else { processObjects(LPE_ERASE); items.clear(); } } -Gtk::Widget * -LPEMirrorSymmetry::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - vbox->set_homogeneous(false); - vbox->set_spacing(2); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - ++it; - } - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); - Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles")))); - reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEMirrorSymmetry::resetStyles)); - reset_button->set_size_request(110,20); - vbox->pack_start(*hbox, true,true,2); - hbox->pack_start(*reset_button, false, false,2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } - return dynamic_cast(vbox); -} - void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { + using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); + //center_point->param_set_liveupdate(false); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); if (mode == MT_Y) { @@ -177,7 +140,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } if ( mode == MT_X || mode == MT_Y ) { if (!are_near(previous_center, (Geom::Point)center_point, 0.01)) { - center_point.param_setValue(Geom::middle_point(point_a, point_b)); + center_point.param_setValue(Geom::middle_point(point_a, point_b), true); end_point.param_setValue(point_b); start_point.param_setValue(point_a); } else { @@ -200,12 +163,10 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } else if ( mode == MT_FREE) { if (are_near(previous_center, (Geom::Point)center_point, 0.01)) { center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); - } else { Geom::Point trans = center_point - Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); start_point.param_setValue(start_point * trans); end_point.param_setValue(end_point * trans); - } } else if ( mode == MT_V){ SPDocument * document = SP_ACTIVE_DOCUMENT; @@ -232,7 +193,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } void -LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool reset) +LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool live, bool root) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -245,101 +206,110 @@ LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool reset) for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, reset); + cloneD(*obj_it, dest_child, live, false); index++; } - return; } SPShape * shape = SP_SHAPE(orig); SPPath * path = SP_PATH(dest); + if (shape && !path) { + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); + path = SP_PATH(dest); + } if (path && shape) { - SPCurve *c = shape->getCurve(); - if (c) { - gchar *str = sp_svg_write_path(c->get_pathvector()); - dest->getRepr()->setAttribute("d", str); - g_free(str); - c->unref(); + if ( live) { + SPCurve *c = NULL; + if (root) { + c = new SPCurve(); + c->set_pathvector(pathvector_after_effect); + } else { + c = shape->getCurve(); + } + if (c) { + path->setCurve(c, TRUE); + c->unref(); + } else { + dest->getRepr()->setAttribute("d", NULL); + } } else { - dest->getRepr()->setAttribute("d", NULL); - } - if (reset) { - dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); - } - } -} - -Inkscape::XML::Node * -LPEMirrorSymmetry::createPathBase(SPObject *elemref) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return NULL; - } - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::XML::Node *prev = elemref->getRepr(); - SPGroup *group = dynamic_cast(elemref); - if (group) { - Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); - container->setAttribute("transform", prev->attribute("transform")); - std::vector const item_list = sp_item_group_item_list(group); - Inkscape::XML::Node *previous = NULL; - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *sub_item = *iter; - Inkscape::XML::Node *resultnode = createPathBase(sub_item); - container->addChild(resultnode, previous); - previous = resultnode; + dest->getRepr()->setAttribute("d", orig->getRepr()->attribute("d")); } - return container; } - Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); - resultnode->setAttribute("transform", prev->attribute("transform")); - return resultnode; } void -LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) +LPEMirrorSymmetry::toMirror(Geom::Affine transform) { SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return; - } - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Glib::ustring elemref_id = Glib::ustring("mirror-"); - elemref_id += this->lpeobj->getId(); - items.clear(); - items.push_back(elemref_id); - SPObject *elemref = NULL; - Inkscape::XML::Node *phantom = NULL; - if (elemref = document->getObjectById(elemref_id.c_str())) { - phantom = elemref->getRepr(); - } else { - phantom = createPathBase(sp_lpe_item); - phantom->setAttribute("id", elemref_id.c_str()); - reset = true; - } - if (!elemref) { - elemref = container->appendChildRepr(phantom); - Inkscape::GC::release(phantom); - } - cloneD(SP_OBJECT(sp_lpe_item), elemref, reset); - gchar *str = sp_svg_transform_write(transform); - elemref->getRepr()->setAttribute("transform" , str); - g_free(str); - if (elemref->parent != container) { - Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id); - container->appendChildRepr(copy); - Inkscape::GC::release(copy); - elemref->deleteObject(); + if (document) { + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + const char * id_origin_char = id_origin.param_getSVGValue(); + const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); + items.clear(); + items.push_back(elemref_id); + SPObject *elemref= NULL; + Inkscape::XML::Node *phantom = NULL; + if ((elemref = document->getObjectById(elemref_id))) { + phantom = elemref->getRepr(); + } else { + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); + std::vector attrs; + attrs.push_back("inkscape:path-effect"); + attrs.push_back("inkscape:original-d"); + attrs.push_back("sodipodi:type"); + attrs.push_back("sodipodi:rx"); + attrs.push_back("sodipodi:ry"); + attrs.push_back("sodipodi:cx"); + attrs.push_back("sodipodi:cy"); + attrs.push_back("sodipodi:end"); + attrs.push_back("sodipodi:start"); + attrs.push_back("inkscape:flatsided"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:rounded"); + attrs.push_back("sodipodi:arg1"); + attrs.push_back("sodipodi:arg2"); + attrs.push_back("sodipodi:r1"); + attrs.push_back("sodipodi:r2"); + attrs.push_back("sodipodi:sides"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("sodipodi:argument"); + attrs.push_back("sodipodi:expansion"); + attrs.push_back("sodipodi:radius"); + attrs.push_back("sodipodi:revolution"); + attrs.push_back("sodipodi:t0"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("inkscape:randomized"); + attrs.push_back("x"); + attrs.push_back("y"); + attrs.push_back("rx"); + attrs.push_back("ry"); + attrs.push_back("width"); + attrs.push_back("height"); + for(const char * attr : attrs) { + phantom->setAttribute(attr, NULL); + } + } + phantom->setAttribute("id", elemref_id); + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); + } + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); + gchar *str = sp_svg_transform_write(transform); + elemref->getRepr()->setAttribute("transform" , str); + g_free(str); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } } } - -void -LPEMirrorSymmetry::resetStyles(){ - reset = true; - doAfterEffect(sp_lpe_item); -} - //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -375,7 +345,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); @@ -387,6 +357,10 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) center_point.param_setValue(point_c); previous_center = center_point; SPLPEItem * splpeitem = const_cast(lpeitem); + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet + id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); + id_origin.write_to_SVG(); + } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index d2d04c2059..e98c83f2b8 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,8 +17,6 @@ */ #include "live_effects/effect.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" @@ -48,11 +46,9 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); - virtual Gtk::Widget * newWidget(); - void toMirror(Geom::Affine transform, bool reset); - void cloneD(SPObject *orig, SPObject *dest, bool reset); - Inkscape::XML::Node * createPathBase(SPObject *elemref); - void resetStyles(); + void toMirror(Geom::Affine transform); + // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); + void cloneD(SPObject *orig, SPObject *dest, bool live, bool root); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -67,9 +63,9 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; + TextParam id_origin; Geom::Point previous_center; SPObject * container; - bool reset; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 115c777d0c..6e6f35f7dd 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -316,7 +316,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Poin Geom::Point const s = snap_knot_position(p, state); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveForEdit(); + SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); @@ -349,7 +349,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const LPEPatternAlongPath *lpe = dynamic_cast (_effect); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveForEdit(); + SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index afaa6b9ca5..2819094e7d 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -113,7 +113,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) { /* make the path a straight line */ /** - SPCurve* curve = sp_path_getCurveForEdit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? + SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? Geom::Point A(curve->first_point()); Geom::Point B(curve->last_point()); @@ -121,7 +121,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) SPCurve *c = new SPCurve(); c->moveto(A); c->lineto(B); - // TODO: Why doesn't sp_path_set_curve_before_LPE(SP_PATH(lpeitem), c, TRUE, true) work? + // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work? SP_PATH(lpeitem)->original_curve = c->ref(); c->unref(); **/ diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index e95cdfd4bb..3cff83fedc 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -414,9 +414,6 @@ LPEPerspectiveEnvelope::newWidget() reset_button->set_size_request(140,30); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -465,7 +462,7 @@ LPEPerspectiveEnvelope::horizontal(PointParam ¶m_one, PointParam ¶m_two, void LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); Geom::Line vert(Geom::Point(boundingbox_X.middle(),boundingbox_Y.max()), Geom::Point(boundingbox_X.middle(), boundingbox_Y.min())); Geom::Line horiz(Geom::Point(boundingbox_X.min(),boundingbox_Y.middle()), Geom::Point(boundingbox_X.max(), boundingbox_Y.middle())); if(vertical_mirror) { @@ -506,7 +503,7 @@ void LPEPerspectiveEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item)); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index deed40bde7..3484d00a58 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -255,9 +255,6 @@ LPEPerspectivePath::newWidget() Gtk::Widget* apply3DWidget = dynamic_cast(apply3D); apply3DWidget->set_tooltip_text("Refresh perspective"); vbox->pack_start(*apply3DWidget, true, true,2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 60237b54ef..2e90abfeb5 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -44,12 +44,11 @@ LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ SPObject * clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); - gchar * uri_str = uri.param_getSVGValue(); if(hide_clip && clip_path) { SP_ITEM(sp_lpe_item)->clip_ref->detach(); - } else if (!hide_clip && !clip_path && uri_str) { + } else if (!hide_clip && !clip_path && uri.param_getSVGValue()) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -63,10 +62,9 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ if(!bbox) { return; } - uri_str = uri.param_getSVGValue(); - if (uri_str) { + if (uri.param_getSVGValue()) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -74,7 +72,6 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ } else { SP_ITEM(sp_lpe_item)->clip_ref->detach(); } - g_free(uri_str); Geom::Rect bboxrect = (*bbox); bboxrect.expandBy(1); Geom::Point topleft = bboxrect.corner(0); @@ -128,7 +125,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Geom::PathVector c_pv = c->get_pathvector(); c_pv *= affine; c->set_pathvector(c_pv); - SP_SHAPE(clip_to_path)->setCurve(c); + SP_SHAPE(clip_to_path)->setCurve(c, TRUE); c->unref(); } @@ -147,38 +144,28 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Inkscape::GC::release(clip_path_node); clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); } - gchar * is_inverse_str = is_inverse.param_getSVGValue(); - if(!strcmp(is_inverse_str,"false") && inverse && isVisible()) { + if( is_inverse.param_getSVGValue() == (Glib::ustring)"false" && inverse && isVisible()) { if (clip_to_path) { addInverse(SP_ITEM(clip_to_path)); } else { addInverse(SP_ITEM(clip_data)); } - } else if(!strcmp(is_inverse_str,"true") && !inverse && isVisible()) { + } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { if (clip_to_path) { removeInverse(SP_ITEM(clip_to_path)); } else { removeInverse(SP_ITEM(clip_data)); } - } else if (inverse && !is_visible && is_inverse_str == (Glib::ustring)"true"){ + } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ removeInverse(SP_ITEM(clip_data)); } - g_free(is_inverse_str); } } } -void -LPEPowerClip::doAfterEffect (SPLPEItem const* lpeitem){ - if (!hide_clip && flatten && isVisible()) { - SP_ITEM(sp_lpe_item)->clip_ref->detach(); - } -} - void LPEPowerClip::addInverse (SPItem * clip_data){ - gchar * is_inverse_str = is_inverse.param_getSVGValue(); - if(!strcmp(is_inverse_str,"false")) { + if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -198,12 +185,9 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } c_pv.push_back(clip_box); c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c); + SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); - gchar * is_inverse_str = is_inverse.param_getSVGValue(); - if (strcmp(is_inverse_str, "true") != 0) { - is_inverse.param_setValue((Glib::ustring)"true", true); - } + is_inverse.param_setValue((Glib::ustring)"true", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -218,13 +202,11 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } } } - g_free(is_inverse_str); } void LPEPowerClip::removeInverse (SPItem * clip_data){ - gchar * is_inverse_str = is_inverse.param_getSVGValue(); - if(!strcmp(is_inverse_str,"true")) { + if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -240,12 +222,9 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ c_pv.pop_back(); } c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c); + SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); - gchar * is_inverse_str = is_inverse.param_getSVGValue(); - if (strcmp(is_inverse_str, "false") != 0) { - is_inverse.param_setValue((Glib::ustring)"false", true); - } + is_inverse.param_setValue((Glib::ustring)"false", true); SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -260,7 +239,6 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ } } } - g_free(is_inverse_str); } void @@ -303,9 +281,6 @@ LPEPowerClip::newWidget() topaths_button->set_size_request(220,30); hbox->pack_start(*topaths_button, false, false,2); vbox->pack_start(*hbox, true,true,2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } @@ -315,15 +290,13 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); if(!keep_paths) { if(clip_path) { - gchar * is_inverse_str = is_inverse.param_getSVGValue(); std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - if(!strcmp(is_inverse_str,"true")) { + if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { removeInverse(SP_ITEM(clip_data)); } } - g_free(is_inverse_str); } } else { if (flatten && clip_path) { @@ -344,6 +317,7 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ flattenClip(SP_ITEM(clip_data), path_out); } } + SP_ITEM(sp_lpe_item)->clip_ref->detach(); } return path_out; } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 240a1809b3..6f99d220f6 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -23,7 +23,6 @@ public: virtual Gtk::Widget * newWidget(); //virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); - virtual void doAfterEffect (SPLPEItem const* lpeitem); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 202c972594..947482c24d 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -50,14 +50,13 @@ LPEPowerMask::~LPEPowerMask() {} void LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ - //To avoid close of color dialog and better performance on change color + //To avoid close of color dialog and better performance on change color SPObject * mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); - gchar * uri_str = uri.param_getSVGValue(); if(hide_mask && mask) { SP_ITEM(sp_lpe_item)->mask_ref->detach(); - } else if (!hide_mask && !mask && uri_str) { + } else if (!hide_mask && !mask && uri.param_getSVGValue()) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -73,13 +72,11 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ SP_ITEM(sp_lpe_item)->mask_ref->detach(); Geom::OptRect bbox = sp_lpe_item->visualBounds(); if(!bbox) { - g_free(uri_str); return; } - uri_str = uri.param_getSVGValue(); - if (uri_str) { + if (uri.param_getSVGValue()) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -102,7 +99,6 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ setMask(); } } - g_free(uri_str); } void diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 1d64e90420..6d63ffa81c 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -170,13 +170,13 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this), sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve"), "sort_points", &wr, this, true), - interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM), + interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER), interpolator_beta(_("Smoothness:"), _("Sets the smoothness for the CubicBezierJohan interpolator; 0 = linear interpolation, 1 = smooth"), "interpolator_beta", &wr, this, 0.2), scale_width(_("Width scale:"), _("Width scale all points"), "scale_width", &wr, this, 1.0), - start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH), - linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_ROUND), + start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_EXTRP_MITER_ARC), miter_limit(_("Miter limit:"), _("Maximum length of the miter (in units of stroke width)"), "miter_limit", &wr, this, 4.), - end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH) + end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT) { show_orig_path = true; diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index e78ab99fda..e847494a2f 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -163,9 +163,6 @@ Gtk::Widget *LPERoughen::newWidget() } ++it; } - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 35da722d0f..149425112b 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -95,7 +95,7 @@ Geom::PathVector LPEShowHandles::doEffect_path (Geom::PathVector const & path_in outline_path.clear(); } if (original_d) { - SPCurve * shape_curve = current_shape->getCurveForEdit(); + SPCurve * shape_curve = sp_shape->getCurveBeforeLPE(); if (shape_curve) { Geom::PathVector original_curve = shape_curve->get_pathvector(); if(original_path) { diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index e676f37a08..5de9816bb9 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -115,9 +115,6 @@ LPESimplify::newWidget() ++it; } vbox->pack_start(*buttons,true, true, 2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 47f8864ce3..914d23e4bc 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -89,13 +89,13 @@ void LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->getCurveForEdit()->get_pathvector(); + pathvector = sp_path->get_original_curve()->get_pathvector(); } if(!pathvector.empty()) { point_a = pathvector.initialPoint(); @@ -120,14 +120,14 @@ void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->getCurveForEdit()->get_pathvector(); + pathvector = sp_path->get_original_curve()->get_pathvector(); } if(from_original_width_toggler != from_original_width) { from_original_width_toggler = from_original_width; @@ -183,7 +183,7 @@ LPETransform2Pts::updateIndex() SPLPEItem * splpeitem = const_cast(sp_lpe_item); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->getCurveForEdit()->get_pathvector(); + pathvector = sp_path->get_original_curve()->get_pathvector(); } if(pathvector.empty()) { return; @@ -362,9 +362,6 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->pack_start(*button2, true, true, 2); vbox->pack_start(*button3, true, true, 2); vbox->pack_start(*button4, true, true, 2); - if(Gtk::Widget* widg = defaultParamSet()) { - vbox->pack_start(*widg, true, true, 2); - } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index 33460aa2d7..f04c243f63 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -239,7 +239,7 @@ void LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem, false, true); + original_bbox(lpeitem); Geom::PathVector paths = ref_path.get_pathvector(); Geom::Point A,B; @@ -269,7 +269,7 @@ LPEVonKoch::resetDefaults(SPItem const* item) Effect::resetDefaults(item); using namespace Geom; - original_bbox(SP_LPE_ITEM(item), false, true); + original_bbox(SP_LPE_ITEM(item)); Point A,B; A[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 6df6278b11..8a42fc8b67 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -5,13 +5,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "document.h" #include "live_effects/lpegroupbbox.h" -#include "object/sp-clippath.h" -#include "object/sp-mask.h" -#include "object/sp-root.h" -#include "object/sp-shape.h" -#include "object/sp-item-group.h" + #include "object/sp-lpe-item.h" namespace Inkscape { @@ -27,32 +22,7 @@ namespace LivePathEffect { * or of the transformed lpeitem (\c absolute = \c true) using sp_item_i2doc_affine. * @post Updated values of boundingbox_X and boundingbox_Y. These intervals are set to empty intervals when the precondition is not met. */ - -Geom::OptRect -GroupBBoxEffect::clip_mask_bbox(SPLPEItem *item, Geom::Affine transform) -{ - Geom::OptRect bbox; - Geom::Affine affine = transform * item->transform; - SPClipPath * clip_path = item->clip_ref->getObject(); - if(clip_path) { - bbox.unionWith(clip_path->geometricBounds(affine)); - } - SPMask * mask_path = item->mask_ref->getObject(); - if(mask_path) { - bbox.unionWith(mask_path->visualBounds(affine)); - } - SPGroup * group = dynamic_cast(item); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPLPEItem * subitem = dynamic_cast(*iter); - bbox.unionWith(clip_mask_bbox(subitem, affine)); - } - } - return bbox; -} - -void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, bool clip_mask) +void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) { // Get item bounding box Geom::Affine transform; @@ -62,12 +32,8 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, boo else { transform = Geom::identity(); } - + Geom::OptRect bbox = lpeitem->geometricBounds(transform); - if (clip_mask) { - SPLPEItem * item = const_cast(lpeitem); - bbox.unionWith(clip_mask_bbox(item, transform * item->transform.inverse())); - } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/live_effects/lpegroupbbox.h b/src/live_effects/lpegroupbbox.h index de20138c93..7d4ac3e78c 100644 --- a/src/live_effects/lpegroupbbox.h +++ b/src/live_effects/lpegroupbbox.h @@ -18,13 +18,12 @@ namespace LivePathEffect { class GroupBBoxEffect { protected: - // Bounding box of the item the path effect is applied on + // Bounding box of the item the path effect is applied on Geom::Interval boundingbox_X; Geom::Interval boundingbox_Y; - //This sets boundingbox_X and boundingbox_Y - Geom::OptRect clip_mask_bbox(SPLPEItem * item, Geom::Affine transform); - void original_bbox(SPLPEItem const* lpeitem, bool absolute = false, bool clip_mask = false); + //This sets boundingbox_X and boundingbox_Y + void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); }; }; //namespace LivePathEffect diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index b5ee8b5cf5..c66d53266e 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -64,7 +64,8 @@ public: virtual gchar * param_getSVGValue() const { Inkscape::SVGOStringStream os; writesvg(os, _vector); - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } virtual gchar * param_getDefaultSVGValue() const { diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index bfbda2bfd2..1a01f269be 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -57,13 +57,15 @@ BoolParam::param_readSVGValue(const gchar * strvalue) gchar * BoolParam::param_getSVGValue() const { - return g_strdup(value ? "true" : "false"); + gchar * str = g_strdup(value ? "true" : "false"); + return str; } gchar * BoolParam::param_getDefaultSVGValue() const { - return g_strdup(defvalue ? "true" : "false"); + gchar * str = g_strdup(defvalue ? "true" : "false"); + return str; } Gtk::Widget * diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h index 82eaa6d433..ca237c0f74 100644 --- a/src/live_effects/parameter/enum.h +++ b/src/live_effects/parameter/enum.h @@ -61,11 +61,13 @@ public: return true; }; gchar * param_getSVGValue() const { - return g_strdup( enumdataconv->get_key(value).c_str() ); + gchar * str = g_strdup( enumdataconv->get_key(value).c_str() ); + return str; }; gchar * param_getDefaultSVGValue() const { - return g_strdup( enumdataconv->get_key(defvalue).c_str() ); + gchar * str = g_strdup( enumdataconv->get_key(defvalue).c_str() ); + return str; }; E get_value() const { diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 5a21f572b5..e08881f6d4 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -55,7 +55,8 @@ HiddenParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -63,7 +64,8 @@ HiddenParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } Gtk::Widget * diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 03eb2219f5..1e2c9ec50f 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -17,8 +17,8 @@ MessageParam::MessageParam( const Glib::ustring& label, const Glib::ustring& tip const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, const gchar * default_message ) : Parameter(label, tip, key, wr, effect), - message(default_message), - defmessage(default_message) + message(g_strdup(default_message)), + defmessage(g_strdup(default_message)) { _label = NULL; _min_height = -1; @@ -33,7 +33,7 @@ MessageParam::param_set_default() void MessageParam::param_update_default(const gchar * default_message) { - defmessage = default_message; + defmessage = g_strdup(default_message); } bool @@ -46,13 +46,13 @@ MessageParam::param_readSVGValue(const gchar * strvalue) gchar * MessageParam::param_getSVGValue() const { - return g_strdup(message); + return message; } gchar * MessageParam::param_getDefaultSVGValue() const { - return g_strdup(defmessage); + return defmessage; } void @@ -106,7 +106,7 @@ MessageParam::param_setValue(const gchar * strvalue) if (strcmp(strvalue, message) != 0) { param_effect->upd_params = true; } - message = strvalue; + message = g_strdup(strvalue); } diff --git a/src/live_effects/parameter/message.h b/src/live_effects/parameter/message.h index fd850a7675..2ac2c791a6 100644 --- a/src/live_effects/parameter/message.h +++ b/src/live_effects/parameter/message.h @@ -41,8 +41,8 @@ private: int _min_height; MessageParam(const MessageParam&); MessageParam& operator=(const MessageParam&); - const gchar * message; - const gchar * defmessage; + gchar * message; + gchar * defmessage; }; } //namespace LivePathEffect diff --git a/src/live_effects/parameter/originalitemarray.cpp b/src/live_effects/parameter/originalitemarray.cpp index b89485e2db..fe2dc0c8d6 100644 --- a/src/live_effects/parameter/originalitemarray.cpp +++ b/src/live_effects/parameter/originalitemarray.cpp @@ -438,7 +438,8 @@ gchar * OriginalItemArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->actived ? "1" : "0"); } - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * OriginalItemArrayParam::param_getDefaultSVGValue() const diff --git a/src/live_effects/parameter/originalpath.cpp b/src/live_effects/parameter/originalpath.cpp index 018e1e69e9..b6a90671e0 100644 --- a/src/live_effects/parameter/originalpath.cpp +++ b/src/live_effects/parameter/originalpath.cpp @@ -93,7 +93,7 @@ OriginalPathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags* SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveForEdit(); + curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 928bf29766..caec74a8ba 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -428,9 +428,9 @@ void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/ if (SP_IS_SHAPE(linked_obj)) { SPLPEItem * lpe_item = SP_LPE_ITEM(linked_obj); if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveForEdit(); + curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); } else if (_allow_only_bspline_spiro && lpe_item && lpe_item->hasPathEffect()){ - curve = SP_SHAPE(linked_obj)->getCurveForEdit(); + curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); PathEffectList lpelist = lpe_item->getEffectList(); PathEffectList::iterator i; for (i = lpelist.begin(); i != lpelist.end(); ++i) { @@ -524,12 +524,13 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0") << "," << ((*iter)->visibled ? "1" : "0"); } - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * OriginalPathArrayParam::param_getDefaultSVGValue() const { - return g_strdup(""); + return ""; } void OriginalPathArrayParam::update() diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a175359f09..497113e032 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -91,7 +91,8 @@ ScalarParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -99,7 +100,8 @@ ScalarParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } void @@ -127,9 +129,6 @@ ScalarParam::param_update_default(const gchar * default_value) void ScalarParam::param_set_value(gdouble val) { - if (value != val) { - param_effect->upd_params = true; - } value = val; if (integer) value = round(value); diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index ab385daa64..02075ee8e1 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -460,7 +460,7 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveForEdit(); + curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index b811b7f2b9..9b4723da3e 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -128,7 +128,8 @@ PointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << *dynamic_cast( this ); - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -136,7 +137,8 @@ PointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } void @@ -210,10 +212,10 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or s = A; } } - if(this->pparam->liveupdate){ - pparam->param_setValue(s, true); - } else { - pparam->param_setValue(s); + pparam->param_setValue(s); + SPLPEItem * splpeitem = dynamic_cast(item); + if(splpeitem && this->pparam->liveupdate){ + sp_lpe_item_update_patheffect(splpeitem, true, true); } } @@ -229,7 +231,10 @@ PointParamKnotHolderEntity::knot_click(guint state) if (state & GDK_CONTROL_MASK) { if (state & GDK_MOD1_MASK) { this->pparam->param_set_default(); - pparam->param_setValue(*pparam,true); + SPLPEItem * splpeitem = dynamic_cast(item); + if(splpeitem){ + sp_lpe_item_update_patheffect(splpeitem, true, true); + } } } } diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index 23912bedbe..4afa43c6ea 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -67,7 +67,8 @@ RandomParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value << ';' << startseed; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -75,7 +76,8 @@ RandomParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue << ';' << defseed; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } void diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 37ae3a1d7c..7e56b2c758 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -112,7 +112,8 @@ TextParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -120,7 +121,8 @@ TextParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } void diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index bb9d9a90e0..e26884d6ad 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -55,13 +55,15 @@ ToggleButtonParam::param_readSVGValue(const gchar * strvalue) gchar * ToggleButtonParam::param_getSVGValue() const { - return g_strdup(value ? "true" : "false"); + gchar * str = g_strdup(value ? "true" : "false"); + return str; } gchar * ToggleButtonParam::param_getDefaultSVGValue() const { - return g_strdup(defvalue ? "true" : "false"); + gchar * str = g_strdup(defvalue ? "true" : "false"); + return str; } void diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index ab66e72569..a010faf27c 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -78,7 +78,8 @@ TransformedPointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -86,7 +87,8 @@ TransformedPointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } void diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp index 1207a05da2..ced93ef0de 100644 --- a/src/live_effects/parameter/vector.cpp +++ b/src/live_effects/parameter/vector.cpp @@ -97,7 +97,8 @@ VectorParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } gchar * @@ -105,7 +106,8 @@ VectorParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - return g_strdup(os.str().c_str()); + gchar * str = g_strdup(os.str().c_str()); + return str; } Gtk::Widget * diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index 6ecd3a1fae..3eea8855ca 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -192,22 +192,21 @@ void Box3DSide::set_shape() { c->lineto(box3d_get_corner_screen(box, corners[3])); c->closepath(); - /* Reset the shape's curve to the "original_curve" + /* Reset the this'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)*/ - SPCurve * before = this->getCurveBeforeLPE(); - if (before || this->hasPathEffectRecursive()) { - if (!before || before->get_pathvector() != c->get_pathvector()){ - this->setCurveBeforeLPE(c); - this->update_patheffect(false); - } else { - this->setCurveBeforeLPE(c); + this->setCurveInsync( c, TRUE); + + if (hasPathEffect() && pathEffectsEnabled()) { + SPCurve *c_lpe = c->copy(); + bool success = this->performPathEffect(c_lpe); + + if (success) { + this->setCurveInsync(c_lpe, TRUE); } - } else { - this->setCurveInsync(c); - } - if (before) { - before->unref(); + + c_lpe->unref(); } + c->unref(); } diff --git a/src/object/sp-clippath.cpp b/src/object/sp-clippath.cpp index 4afbf7e510..4f69bd0262 100644 --- a/src/object/sp-clippath.cpp +++ b/src/object/sp-clippath.cpp @@ -238,12 +238,14 @@ void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox) { Geom::OptRect SPClipPath::geometricBounds(Geom::Affine const &transform) { Geom::OptRect bbox; + for (auto& i: children) { if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(transform); - bbox.unionWith(tmp); + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); + bbox.unionWith(tmp); } } + return bbox; } diff --git a/src/object/sp-conn-end-pair.cpp b/src/object/sp-conn-end-pair.cpp index 1a0ec5d705..daadd0cddc 100644 --- a/src/object/sp-conn-end-pair.cpp +++ b/src/object/sp-conn-end-pair.cpp @@ -175,7 +175,7 @@ void SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const { void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { - SPCurve const *curve = _path->getCurveForEdit(true); + SPCurve const *curve = _path->get_curve_reference(); SPItem *h2attItem[2] = {0}; getAttachedItems(h2attItem); Geom::Affine i2d = _path->i2doc_affine(); @@ -322,7 +322,7 @@ bool SPConnEndPair::reroutePathFromLibavoid() return false; } - SPCurve *curve = _path->getCurve(true); + SPCurve *curve = _path->get_curve(); recreateCurve(curve, _connRef, _connCurvature); diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 95bfd61606..c32e3012c6 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -18,8 +18,6 @@ #include #include "live_effects/effect.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" #include <2geom/angle.h> #include <2geom/circle.h> @@ -412,7 +410,7 @@ const char *SPGenericEllipse::displayName() const } // Create path for rendering shape on screen -void SPGenericEllipse::set_shape() +void SPGenericEllipse::set_shape(bool force) { // std::cout << "SPGenericEllipse::set_shape: Entrance" << std::endl; if (hasBrokenPathEffect()) { @@ -422,7 +420,7 @@ void SPGenericEllipse::set_shape() // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync(cold); + this->setCurveInsync(cold, TRUE); cold->unref(); } @@ -434,7 +432,7 @@ void SPGenericEllipse::set_shape() this->normalize(); - SPCurve *c = NULL; + SPCurve *curve = NULL; // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. Geom::Circle circle(0, 0, 1); @@ -467,7 +465,7 @@ void SPGenericEllipse::set_shape() } else { pb.flush(); } - c = new SPCurve(pb.peek()); + curve = new SPCurve(pb.peek()); // gchar *str = sp_svg_write_path(curve->get_pathvector()); // std::cout << " path: " << str << std::endl; @@ -475,25 +473,32 @@ void SPGenericEllipse::set_shape() // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); - c->transform(aff); - + curve->transform(aff); + /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - SPCurve * before = this->getCurveBeforeLPE(); - if (before || this->hasPathEffectRecursive()) { - if (!before || before->get_pathvector() != c->get_pathvector()){ - this->setCurveBeforeLPE(c); - this->update_patheffect(false); - } else { - this->setCurveBeforeLPE(c); + if(this->getCurveBeforeLPE()) { + if(!force && this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { + curve->unref(); + return; } - } else { - this->setCurveInsync(c); } - if (before) { - before->unref(); + this->setCurveInsync(curve, TRUE); + this->setCurveBeforeLPE(curve); + + if (hasPathEffect() && pathEffectsEnabled()) { + SPCurve *c_lpe = curve->copy(); + bool success = this->performPathEffect(c_lpe); + + if (success) { + this->setCurveInsync(c_lpe, TRUE); + } + + c_lpe->unref(); } - c->unref(); + + curve->unref(); + // std::cout << "SPGenericEllipse::set_shape: Exit" << std::endl; } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) @@ -628,6 +633,25 @@ void SPGenericEllipse::modified(guint flags) SPShape::modified(flags); } +void SPGenericEllipse::update_patheffect(bool write) +{ + this->set_shape(true); + + if (write) { + Inkscape::XML::Node *repr = this->getRepr(); + + if (this->_curve != NULL && type == SP_GENERIC_ELLIPSE_ARC) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + void SPGenericEllipse::normalize() { Geom::AngleInterval a(this->start, this->end, true); @@ -674,7 +698,7 @@ void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry this->rx = rx; this->ry = ry; - Inkscape::Preferences * prefs = Inkscape::Preferences::get(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // those pref values are in degrees, while we want radians if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) { diff --git a/src/object/sp-ellipse.h b/src/object/sp-ellipse.h index 0aa3dd1c62..a31b571d85 100644 --- a/src/object/sp-ellipse.h +++ b/src/object/sp-ellipse.h @@ -64,13 +64,15 @@ public: virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char *displayName() const; - virtual void set_shape(); + virtual void set_shape(bool force = false); virtual Geom::Affine set_transform(Geom::Affine const &xform); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void modified(unsigned int flags); + virtual void update_patheffect(bool write); + /** * @brief Makes sure that start and end lie between 0 and 2 * PI. */ diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index a3fa6c6e87..73c1dcb6c6 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -58,7 +58,7 @@ using Inkscape::DocumentUndo; -static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write); +static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write); SPGroup::SPGroup() : SPLPEItem(), _expanded(false), @@ -88,6 +88,7 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) SPLPEItem::child_added(child, ref); SPObject *last_child = this->lastChild(); + if (last_child && last_child->getRepr() == child) { // optimization for the common special case where the child is being added at the end SPItem *item = dynamic_cast(last_child); @@ -120,6 +121,7 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } @@ -640,13 +642,13 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d if (item) { item->doWriteTransform(item->transform, NULL, false); children.insert(children.begin(),item); - item->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { g_assert_not_reached(); } Inkscape::GC::release(repr); } + if (do_done) { DocumentUndo::done(doc, SP_VERB_NONE, _("Ungroup")); } @@ -898,52 +900,54 @@ void SPGroup::update_patheffect(bool write) { #ifdef GROUP_VERBOSE g_message("sp_group_update_patheffect: %p\n", lpeitem); #endif + std::vector const item_list = sp_item_group_item_list(this); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; - if (sub_item) { - SPLPEItem *lpe_item = dynamic_cast(sub_item); - if (lpe_item) { - lpe_item->update_patheffect(write); - } + + SPLPEItem *lpe_item = dynamic_cast(sub_item); + if (lpe_item) { + lpe_item->update_patheffect(write); } } - this->resetClipPathAndMaskLPE(); if (hasPathEffect() && pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (lpe) { - lpeobj->get_lpe()->doBeforeEffect_impl(this); - sp_group_perform_patheffect(this, this, lpe, write); - lpeobj->get_lpe()->doAfterEffect(this); - } + + if (lpeobj && lpeobj->get_lpe()) { + lpeobj->get_lpe()->doBeforeEffect_impl(this); + } + } + + sp_group_perform_patheffect(this, this, write); + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + + if (lpeobj && lpeobj->get_lpe()) { + lpeobj->get_lpe()->doAfterEffect(this); } } } } static void -sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write) +sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) { std::vector const item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; + SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { - sp_group_perform_patheffect(sub_group, top_group, lpe, write); + sp_group_perform_patheffect(sub_group, top_group, write); } else { - SPShape* sub_shape = dynamic_cast(sub_item); - SPPath* sub_path = dynamic_cast(sub_item); - SPItem* clipmaskto = dynamic_cast(sub_item); - if (clipmaskto) { - top_group->applyToClipPath(clipmaskto, lpe); - top_group->applyToMask(clipmaskto, lpe); - } + SPShape *sub_shape = dynamic_cast(sub_item); if (sub_shape) { SPCurve * c = NULL; // If item is a SPRect, convert it to path first: @@ -969,16 +973,19 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa bool success = false; // only run LPEs when the shape has a curve defined if (c) { - lpe->pathvector_before_effect = c->get_pathvector(); c->transform(i2anc_affine(sub_item, top_group)); - success = top_group->performOnePathEffect(c, sub_shape, lpe); + success = top_group->performPathEffect(c, sub_shape); c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - sub_shape->setCurveInsync(c); - lpe->pathvector_after_effect = c->get_pathvector(); + SPPath *sub_path = dynamic_cast(sub_item); + if (!sub_path) { + sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); + sub_shape->setCurve(c, TRUE); + sub_shape->setCurveInsync( c, TRUE); + } if (write) { - gchar *str = sp_svg_write_path(lpe->pathvector_after_effect); + gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE g_message("sp_group_perform_patheffect writes 'd' attribute"); @@ -992,7 +999,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - sub_shape->setCurve(oldcurve); + sub_shape->setCurve(oldcurve, TRUE); oldcurve->unref(); } } @@ -1001,11 +1008,6 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePa } } } - SPItem* clipmaskto = dynamic_cast(group); - if (clipmaskto) { - top_group->applyToClipPath(clipmaskto, lpe); - top_group->applyToMask(clipmaskto, lpe); - } } /* diff --git a/src/object/sp-item.cpp b/src/object/sp-item.cpp index a228d9313d..f7a4ff6720 100644 --- a/src/object/sp-item.cpp +++ b/src/object/sp-item.cpp @@ -29,6 +29,7 @@ #include "inkscape.h" #include "desktop.h" + #include "gradient-chemistry.h" #include "conn-avoid-ref.h" #include "conditions.h" @@ -1078,23 +1079,6 @@ bool SPItem::isFiltered() const { return (style && style->filter.href && style->filter.href->getObject()); } - -SPObject* SPItem::isInMask() const { - SPObject* parent = this->parent; - while (parent && !dynamic_cast(parent)) { - parent = parent->parent; - } - return parent; -} - -SPObject* SPItem::isInClipPath() const { - SPObject* parent = this->parent; - while (parent && !dynamic_cast(parent)) { - parent = parent->parent; - } - return parent; -} - unsigned SPItem::display_key_new(unsigned numkeys) { static unsigned dkey = 0; diff --git a/src/object/sp-item.h b/src/object/sp-item.h index 88fca97799..36af02edc7 100644 --- a/src/object/sp-item.h +++ b/src/object/sp-item.h @@ -290,10 +290,6 @@ public: */ bool isFiltered() const; - SPObject* isInMask() const; - - SPObject* isInClipPath() const; - void invoke_print(SPPrintContext *ctx); /** diff --git a/src/object/sp-line.cpp b/src/object/sp-line.cpp index 2ba6339728..09ffd1f17d 100644 --- a/src/object/sp-line.cpp +++ b/src/object/sp-line.cpp @@ -150,7 +150,7 @@ void SPLine::set_shape() { c->moveto(this->x1.computed, this->y1.computed); c->lineto(this->x2.computed, this->y2.computed); - this->setCurveInsync(c); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update + this->setCurveInsync(c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update this->setCurveBeforeLPE(c); // LPE's cannot be applied to lines. (the result can (generally) not be represented as SPLine) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index e0ef848af0..f3cc841fb8 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -41,7 +41,6 @@ #include "svg/svg.h" #include "sp-clippath.h" #include "sp-mask.h" -#include "sp-rect.h" #include "ui/tools-switch.h" #include "ui/tools/node-tool.h" @@ -49,8 +48,9 @@ static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); + static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); -static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); +static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths); typedef std::list HRefList; static std::string patheffectlist_svg_string(PathEffectList const & list); @@ -179,11 +179,11 @@ void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { } void SPLPEItem::modified(unsigned int flags) { - //TODO: remove if no regressions - //stop update when modified and make the effect update on the LPE transform method if the effect require it - //if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { - // sp_lpe_item_update_patheffect(this, true, true); - //} + if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + sp_lpe_item_update_patheffect(this, true, true); + } + +// SPItem::onModified(flags); } Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { @@ -200,86 +200,114 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape return repr; } - /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { - - if (!curve) { - return false; - } - +bool SPLPEItem::hasPathEffectOnClipOrMask() const +{ + bool has_clipormask_lpe = false; if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (!lpeobj) { - /** \todo Investigate the cause of this. - * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. - */ - g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); return false; } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if(!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { + if (!lpe) { return false; } + if (lpe->isVisible()) { + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { + return false; + } + if (lpe->apply_to_clippath_and_mask) { + has_clipormask_lpe = true; + } + } } } - return true; + return has_clipormask_lpe; +} + +bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive() const +{ + if (parent && SP_IS_LPE_ITEM(parent)) { + return hasPathEffectOnClipOrMask() || SP_LPE_ITEM(parent)->hasPathEffectOnClipOrMaskRecursive(); + } + else { + return hasPathEffectOnClipOrMask(); + } } /** * returns true when LPE was successful. */ -bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { - if (!lpe) { - /** \todo Investigate the cause of this. - * Not sure, but I think this can happen when an unknown effect type is specified... - */ - g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { + + if (!curve) { return false; } - if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - // if the effect expects mouse input before being applied and the input is not finished - // yet, we don't alter the path - return false; - } - //if is not clip or mask or LPE apply to clip and mask - if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { - lpe->setCurrentShape(current); - if (!SP_IS_GROUP(this)) { - lpe->pathvector_before_effect = curve->get_pathvector(); - } - // To Calculate BBox on shapes and nested LPE - current->setCurveInsync(curve); - // Groups have their doBeforeEffect called elsewhere - if (!SP_IS_GROUP(this) && !is_clip_or_mask) { - lpe->doBeforeEffect_impl(this); + bool has_clipormask_lpe = false; + if (this->hasPathEffect() && this->pathEffectsEnabled()) { + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj) { + /** \todo Investigate the cause of this. + * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. + */ + g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); + return false; } - - try { - lpe->doEffect(curve); + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (!lpe) { + /** \todo Investigate the cause of this. + * Not sure, but I think this can happen when an unknown effect type is specified... + */ + g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); + return false; } + if (lpe->isVisible()) { + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { + // if the effect expects mouse input before being applied and the input is not finished + // yet, we don't alter the path + return false; + } + if (lpe->apply_to_clippath_and_mask) { + has_clipormask_lpe = true; + } + if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { + // Groups have their doBeforeEffect called elsewhere + if (current) { + lpe->setCurrentShape(current); + } + if (!SP_IS_GROUP(this)) { + lpe->doBeforeEffect_impl(this); + } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); + try { + lpe->doEffect(curve); + } + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); + } + return false; + } + if (!SP_IS_GROUP(this)) { + lpe->pathvector_after_effect = curve->get_pathvector(); + lpe->doAfterEffect(this); + } } - return false; - } - - - if (!SP_IS_GROUP(this)) { - // To have processed the shape to doAfterEffect - lpe->pathvector_after_effect = curve->get_pathvector(); - lpe->doAfterEffect(this); } } + if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_clipormask_lpe){ + this->applyToClipPath(this); + this->applyToMask(this); + } } return true; } @@ -299,7 +327,6 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); #endif g_return_if_fail (lpeitem != NULL); - g_return_if_fail (SP_IS_OBJECT (lpeitem)); g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); if (!lpeitem->pathEffectsEnabled()) @@ -319,6 +346,7 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) else { top = lpeitem; } + top->update_patheffect(write); } @@ -339,98 +367,95 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPLPEItem * clip_data = dynamic_cast(*iter); - sp_lpe_item_create_original_path_recursive(clip_data); - } + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); } - - SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); - if(mask_path) { - std::vector mask_path_list = mask_path->childList(true); - for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { - SPLPEItem * mask_data = dynamic_cast(*iter); - sp_lpe_item_create_original_path_recursive(mask_data); - } + SPClipPath * clip_path = lpeitem->clip_ref->getObject(); + if(clip_path) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); } if (SP_IS_GROUP(lpeitem)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); + std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); } } - } else if (SPPath * path = dynamic_cast(lpeitem)) { - Inkscape::XML::Node *pathrepr = path->getRepr(); + } + else if (SP_IS_PATH(lpeitem)) { + Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); if ( !pathrepr->attribute("inkscape:original-d") ) { pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); - path->setCurveBeforeLPE(path->getCurve()); - } - } else if (SPShape * shape = dynamic_cast(lpeitem)) { - if (SPCurve * c_lpe = shape->getCurveBeforeLPE()) { - c_lpe->unref(); - } else { - shape->setCurveBeforeLPE(shape->getCurve()); } } } static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) { g_return_if_fail(lpeitem != NULL); - SPItem *item = dynamic_cast(lpeitem); - if (!item) { - return; - } - SPGroup *group = dynamic_cast(lpeitem); - SPShape *shape = dynamic_cast(lpeitem); - SPPath *path = dynamic_cast(lpeitem); - SPClipPath *clip_path = item->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPLPEItem* clip_data = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, shape && !shape->hasPathEffectRecursive()); - } - } - - SPMask *mask_path = item->mask_ref->getObject(); - if(mask_path) { - std::vector mask_path_list = mask_path->childList(true); - for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { - SPLPEItem* mask_data = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, shape && !shape->hasPathEffectRecursive()); + if (SP_IS_GROUP(lpeitem)) { + if (!lpeitem->hasPathEffectOnClipOrMaskRecursive()) { + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); + } + SPClipPath * clip_path = lpeitem->clip_ref->getObject(); + if(clip_path) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); + } } - } - - if (group) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPLPEItem* subitem = dynamic_cast(*iter); - sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths, false); + SPObject *subitem = *iter; + if (SP_IS_LPE_ITEM(subitem)) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths); + } } - } else if (path) { + } else if (SP_IS_PATH(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); + } + SPClipPath * clip_path = lpeitem->clip_ref->getObject(); + if(clip_path) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); + } + mask = dynamic_cast(lpeitem->parent); + clip_path = dynamic_cast(lpeitem->parent); + if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("inkscape:original-d")) || + ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("inkscape:original-d"))) { if (!keep_paths) { repr->setAttribute("d", repr->attribute("inkscape:original-d")); } repr->setAttribute("inkscape:original-d", NULL); - path->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); } } - } else if (shape) { + } else if (SP_IS_SHAPE(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); + } + SPClipPath * clip_path = lpeitem->clip_ref->getObject(); + if(clip_path) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); + } + mask = dynamic_cast(lpeitem->parent); + clip_path = dynamic_cast(lpeitem->parent); + if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("d")) || + ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("d"))) { if (!keep_paths) { repr->setAttribute("d", NULL); @@ -444,7 +469,6 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, sp_item_list_to_curves(items, selected, to_select, true); } } - shape->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); @@ -491,7 +515,7 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) } // perform this once when the effect is applied - lpe->doOnApply_impl(this); + lpe->doOnApply(this); // indicate that all necessary preparations are done and the effect can be performed lpe->setReady(); @@ -502,6 +526,16 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); + SPMask * mask = mask_ref->getObject(); + if(mask && !hasPathEffectOnClipOrMaskRecursive()) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), false); + } + SPClipPath * clip_path = clip_ref->getObject(); + if(clip_path && !hasPathEffectOnClipOrMaskRecursive()) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), false); + } //fix bug 1219324 if (SP_ACTIVE_DESKTOP ) { Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; @@ -644,92 +678,50 @@ bool SPLPEItem::hasBrokenPathEffect() const } - -bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const +bool SPLPEItem::hasPathEffect() const { - if (path_effect_list->empty()) { + if (!path_effect_list || path_effect_list->empty()) { return false; } + // go through the list; if some are unknown or invalid, we are not an LPE item! for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject const *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); - if (lpe && (lpe->effectType() == type)) { - if (is_ready || lpe->isReady()) { - return true; - } - } - } - } - - return false; -} - -/** - * returns true when any LPE apply to clip or mask. - */ -bool SPLPEItem::hasPathEffectOnClipOrMask(SPLPEItem * shape) const -{ - if (shape->hasPathEffectRecursive()) { - return true; - } - if (!path_effect_list || path_effect_list->empty()) { - return false; - } - - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj) { - continue; - } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (lpe->apply_to_clippath_and_mask) { - return true; + if (!lpeobj || !lpeobj->get_lpe()) { + return false; } } - return false; -} -/** - * returns true when any LPE apply to clip or mask. - */ -bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const -{ - SPLPEItem * parent_lpe_item = dynamic_cast(parent); - if (parent_lpe_item) { - return hasPathEffectOnClipOrMask(shape) || parent_lpe_item->hasPathEffectOnClipOrMaskRecursive(shape); - } - else { - return hasPathEffectOnClipOrMask(shape); - } + return true; } -bool SPLPEItem::hasPathEffect() const +bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { - if (!path_effect_list || path_effect_list->empty()) { + if (path_effect_list->empty()) { return false; } - // go through the list; if some are unknown or invalid, we are not an LPE item! for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj || !lpeobj->get_lpe()) { - return false; + LivePathEffectObject const *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect const* lpe = lpeobj->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + if (is_ready || lpe->isReady()) { + return true; + } + } } } - return true; + return false; } bool SPLPEItem::hasPathEffectRecursive() const { - SPLPEItem * parent_lpe_item = dynamic_cast(parent); - if (parent_lpe_item) { - return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); + if (parent && SP_IS_LPE_ITEM(parent)) { + return hasPathEffect() || SP_LPE_ITEM(parent)->hasPathEffectRecursive(); } else { return hasPathEffect(); @@ -737,172 +729,71 @@ bool SPLPEItem::hasPathEffectRecursive() const } void -SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) +SPLPEItem::applyToClipPath(SPItem *item) { - if (fromrecurse) { - SPGroup* group = dynamic_cast(this); - SPShape* shape = dynamic_cast(this); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { - SPLPEItem * subitem = dynamic_cast(*iter2); - if (subitem) { - subitem->resetClipPathAndMaskLPE(true); - } - } - } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit()); - if (!hasPathEffectOnClipOrMaskRecursive(shape)) { - shape->getRepr()->setAttribute("inkscape:original-d", NULL); - shape->setCurveBeforeLPE(NULL); - } else { - // make sure there is an original-d for paths!!! - sp_lpe_item_create_original_path_recursive(shape); - } - } - return; - } - SPClipPath *clip_path = this->clip_ref->getObject(); + SPClipPath *clip_path = item->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPGroup* group = dynamic_cast(*iter); - SPShape* shape = dynamic_cast(*iter); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { - SPLPEItem * subitem = dynamic_cast(*iter2); - if (subitem) { - subitem->resetClipPathAndMaskLPE(true); - } - } - } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit()); - if (!hasPathEffectOnClipOrMaskRecursive(shape)) { - shape->getRepr()->setAttribute("inkscape:original-d", NULL); - shape->setCurveBeforeLPE(NULL); - } else { - // make sure there is an original-d for paths!!! - sp_lpe_item_create_original_path_recursive(shape); - } - } - } - } - SPMask *mask = this->mask_ref->getObject(); - if(mask) { - std::vector mask_list = mask->childList(true); - for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { - SPGroup* group = dynamic_cast(*iter); - SPShape* shape = dynamic_cast(*iter); - if (group) { - std::vector item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { - SPLPEItem * subitem = dynamic_cast(*iter2); - if (subitem) { - subitem->resetClipPathAndMaskLPE(true); - } - } - } else if (shape) { - shape->setCurveInsync( shape->getCurveForEdit()); - if (!hasPathEffectOnClipOrMaskRecursive(shape)) { - shape->getRepr()->setAttribute("inkscape:original-d", NULL); - shape->setCurveBeforeLPE(NULL); - } else { - // make sure there is an original-d for paths!!! - sp_lpe_item_create_original_path_recursive(shape); - } - } + SPObject * clip_data = *iter; + applyToClipPathOrMask(SP_ITEM(clip_data), item); } } -} - -void -SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) -{ - if (lpe && !lpe->apply_to_clippath_and_mask) { - return; - } - SPClipPath *clip_path = to->clip_ref->getObject(); - if(clip_path) { - std::vector clip_path_list = clip_path->childList(true); - for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data), to, lpe); + if(SP_IS_GROUP(item)){ + std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *subitem = *iter; + applyToClipPath(SP_ITEM(subitem)); } } } void -SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +SPLPEItem::applyToMask(SPItem *item) { - if (lpe && !lpe->apply_to_clippath_and_mask) { - return; - } - SPMask *mask = to->mask_ref->getObject(); + SPMask *mask = item->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data), to, lpe); + applyToClipPathOrMask(SP_ITEM(mask_data), item); + } + } + if(SP_IS_GROUP(item)){ + std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *subitem = *iter; + applyToMask(SP_ITEM(subitem)); } } } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) { - SPGroup* group = dynamic_cast(clip_mask); - SPShape* shape = dynamic_cast(clip_mask); - SPLPEItem* tolpe = dynamic_cast(to); - if (group) { - std::vector item_list = sp_item_group_item_list(group); + if (SP_IS_GROUP(clip_mask)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_mask)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; - applyToClipPathOrMask(subitem, to, lpe); + applyToClipPathOrMask(subitem, item); } - } else if (shape) { + } else if (SP_IS_SHAPE(clip_mask)) { SPCurve * c = NULL; - // If item is a SPRect, convert it to path first: - if ( dynamic_cast(shape) ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - Inkscape::Selection *sel = desktop->getSelection(); - if ( sel && !sel->isEmpty() ) { - sel->clear(); - sel->add(SP_ITEM(shape)); - sel->toCurves(); - SPItem* item = sel->singleItem(); - shape = dynamic_cast(item); - if (!shape) { - return; - } - sel->clear(); - sel->add(this); - } - } - } - if (lpe) { //group - c = shape->getCurve(); + + if (SP_IS_PATH(clip_mask)) { + c = SP_PATH(clip_mask)->get_original_curve(); } else { - c = shape->getCurveForEdit(); + c = SP_SHAPE(clip_mask)->getCurve(); } if (c) { bool success = false; try { if(SP_IS_GROUP(this)){ - c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); - if (lpe) { - success = this->performOnePathEffect(c, shape, lpe, true); - } else { - success = this->performPathEffect(c, shape, true); - } - c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); + c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - if (lpe) { - success = this->performOnePathEffect(c, shape, lpe, true); - } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - } + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -913,8 +804,8 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); + // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE if (success && c) { - shape->setCurveInsync(c); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); @@ -924,7 +815,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - SP_SHAPE(clip_mask)->setCurve(oldcurve); + SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); oldcurve->unref(); } } @@ -932,7 +823,6 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa if (c) { c->unref(); } - shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 0e6049d4e6..82f3940c10 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -70,14 +70,14 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); - bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask = false); + bool hasPathEffectOnClipOrMask() const; + bool hasPathEffectOnClipOrMaskRecursive() const; + bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); + bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; - bool hasPathEffectOnClipOrMask(SPLPEItem * shape) const; - bool hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; @@ -94,10 +94,9 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void resetClipPathAndMaskLPE(bool fromrecurse = false); - void applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); - void applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); - void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); + void applyToMask(SPItem * item); + void applyToClipPath(SPItem * item); + void applyToClipPathOrMask(SPItem * clip_mask, SPItem * item); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/object/sp-mask.cpp b/src/object/sp-mask.cpp index 2e764131c2..b65c145fc2 100644 --- a/src/object/sp-mask.cpp +++ b/src/object/sp-mask.cpp @@ -115,33 +115,6 @@ void SPMask::set(unsigned int key, const gchar* value) { } } -Geom::OptRect -SPMask::geometricBounds(Geom::Affine const &transform) { - Geom::OptRect bbox; - - for (auto& i: children) { - if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); - bbox.unionWith(tmp); - } - } - - return bbox; -} - -Geom::OptRect -SPMask::visualBounds(Geom::Affine const &transform) { - Geom::OptRect bbox; - for (auto& i: children) { - if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->visualBounds(transform); - bbox.unionWith(tmp); - } - } - - return bbox; -} - void SPMask::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { /* Invoke SPObjectGroup implementation */ SPObjectGroup::child_added(child, ref); diff --git a/src/object/sp-mask.h b/src/object/sp-mask.h index 26e5108300..02d37b82b0 100644 --- a/src/object/sp-mask.h +++ b/src/object/sp-mask.h @@ -47,10 +47,6 @@ public: Inkscape::DrawingItem *sp_mask_show(Inkscape::Drawing &drawing, unsigned int key); void sp_mask_hide(unsigned int key); - Geom::OptRect geometricBounds(Geom::Affine const &transform); - - Geom::OptRect visualBounds(Geom::Affine const &transform) ; - void sp_mask_set_bbox(unsigned int key, Geom::OptRect const &bbox); protected: diff --git a/src/object/sp-object.cpp b/src/object/sp-object.cpp index d3c429c2a9..bc930a4304 100644 --- a/src/object/sp-object.cpp +++ b/src/object/sp-object.cpp @@ -413,6 +413,7 @@ std::vector SPObject::childList(bool add_ref, Action) { l.push_back(&child); } return l; + } gchar const *SPObject::label() const { diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index 2864e88cb9..82e0b49476 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -361,7 +361,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c); + this->setCurveInsync (c, TRUE); this->setCurveBeforeLPE(c); c->unref(); @@ -669,7 +669,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c); + this->setCurveInsync (c, TRUE); this->setCurveBeforeLPE(c); c->unref(); diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index d6a06498cd..a0c7f098d9 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -191,14 +191,13 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->setCurveBeforeLPE(curve); + this->set_original_curve(curve, TRUE, true); curve->unref(); } } else { - this->setCurveBeforeLPE(NULL); - + this->set_original_curve(NULL, TRUE, true); } - sp_lpe_item_update_patheffect(this, true, true); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -208,11 +207,11 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->setCurve(curve); + this->setCurve(curve, TRUE); curve->unref(); } } else { - this->setCurve(NULL); + this->setCurve(NULL, TRUE); } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -326,6 +325,130 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { return Geom::identity(); } + +void SPPath::update_patheffect(bool write) { + Inkscape::XML::Node *repr = this->getRepr(); + +#ifdef PATH_VERBOSE +g_message("sp_path_update_patheffect"); +#endif + + if (_curve_before_lpe && hasPathEffectRecursive()) { + SPCurve *curve = _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)*/ + this->setCurveInsync(curve, TRUE); + + bool success = this->performPathEffect(curve); + + if (success && write) { + // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. +#ifdef PATH_VERBOSE +g_message("sp_path_update_patheffect writes 'd' attribute"); +#endif + if (_curve) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } else if (!success) { + // LPE was unsuccessful. 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) { + this->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + curve->unref(); + } +} + + +/** + * Adds a original_curve to the path. If owner is specified, a reference + * will be made, otherwise the curve will be copied into the path. + * Any existing curve in the path will be unreferenced first. + * This routine triggers reapplication of an effect if present + * and also triggers a request to update the display. Does not write + * result to XML when write=false. + */ +void SPPath::set_original_curve (SPCurve *new_curve, unsigned int owner, bool write) +{ + if (_curve_before_lpe) { + _curve_before_lpe = _curve_before_lpe->unref(); + } + + if (new_curve) { + if (owner) { + _curve_before_lpe = new_curve->ref(); + } else { + _curve_before_lpe = new_curve->copy(); + } + } + + sp_lpe_item_update_patheffect(this, true, write); + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Return duplicate of _curve_before_lpe (if any exists) or NULL if there is no curve + */ +SPCurve * SPPath::get_original_curve () const +{ + if (_curve_before_lpe) { + return _curve_before_lpe->copy(); + } + + return NULL; +} + +/** + * 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 && hasPathEffectRecursive()) { + return get_original_curve(); + } else { + return getCurve(); + } +} + +/** + * 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 && hasPathEffectRecursive()) { + return _curve_before_lpe; + } else { + return _curve; + } +} + +/** + * Returns \c _curve_before_lpe if it is not NULL and a valid LPE is applied or \c curve if not. + * \todo should only be available to class friends! + */ +SPCurve* SPPath::get_curve () +{ + if (_curve_before_lpe && hasPathEffectRecursive()) { + return _curve_before_lpe; + } else { + return _curve; + } +} + /* Local Variables: mode:c++ diff --git a/src/object/sp-path.h b/src/object/sp-path.h index 2d7ab4e94b..572fd648d1 100644 --- a/src/object/sp-path.h +++ b/src/object/sp-path.h @@ -29,24 +29,37 @@ class SPCurve; */ class SPPath : public SPShape { public: - SPPath(); - virtual ~SPPath(); + SPPath(); + virtual ~SPPath(); int nodesInPath() const; + + // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. + void set_original_curve (SPCurve *curve, unsigned int owner, bool write); + SPCurve* get_original_curve () const; + SPCurve* get_curve_for_edit () const; + const SPCurve* get_curve_reference() const; + +public: // should be made protected + SPCurve* get_curve(); friend class SPConnEndPair; + +public: SPConnEndPair connEndPair; - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void release(); - virtual void update(SPCtx* ctx, unsigned int flags); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual void release(); + virtual void update(SPCtx* ctx, unsigned int flags); - virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); - virtual const char* displayName() const; - virtual char* description() const; - virtual Geom::Affine set_transform(Geom::Affine const &transform); + virtual const char* displayName() const; + virtual char* description() const; + virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; + + virtual void update_patheffect(bool write); }; #endif // SEEN_SP_PATH_H diff --git a/src/object/sp-polygon.cpp b/src/object/sp-polygon.cpp index b2a0c14808..14fd104b33 100644 --- a/src/object/sp-polygon.cpp +++ b/src/object/sp-polygon.cpp @@ -157,7 +157,7 @@ void SPPolygon::set(unsigned int key, const gchar* value) { curve->closepath(); } - this->setCurve(curve); + this->setCurve(curve, TRUE); curve->unref(); break; } diff --git a/src/object/sp-polyline.cpp b/src/object/sp-polyline.cpp index 3be4700eb8..29054f934a 100644 --- a/src/object/sp-polyline.cpp +++ b/src/object/sp-polyline.cpp @@ -91,7 +91,7 @@ void SPPolyLine::set(unsigned int key, const gchar* value) { } } - this->setCurve(curve); + this->setCurve(curve, TRUE); curve->unref(); break; } diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index f21dafd54f..88dad5354f 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -198,8 +198,8 @@ const char* SPRect::displayName() const { void SPRect::set_shape() { if ((this->height.computed < 1e-18) || (this->width.computed < 1e-18)) { - this->setCurveInsync(NULL); - this->setCurveBeforeLPE(NULL); + this->setCurveInsync( NULL, TRUE); + this->setCurveBeforeLPE( NULL ); return; } @@ -265,7 +265,7 @@ void SPRect::set_shape() { } c->closepath(); - this->setCurveInsync(c); + this->setCurveInsync(c, true); this->setCurveBeforeLPE(c); // LPE is not applied because result can generally not be represented as SPRect diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 07416650ea..9edf03cbfc 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -37,8 +37,7 @@ #include "sp-path.h" #include "preferences.h" #include "attributes.h" -#include "svg/svg.h" -#include "svg/path-string.h" + #include "live_effects/lpeobject.h" #include "helper/mathfns.h" // for triangle_area() @@ -417,7 +416,7 @@ void SPShape::modified(unsigned int flags) { Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const { Geom::OptRect bbox; - if (!this->_curve || this->_curve->get_pathvector().empty()) { + if (!this->_curve) { return bbox; } @@ -739,38 +738,6 @@ void SPShape::print(SPPrintContext* ctx) { } } -void SPShape::update_patheffect(bool write) -{ - if (SPCurve *c_lpe = this->getCurveForEdit()) { - /* 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)*/ - this->setCurveInsync(c_lpe); - this->resetClipPathAndMaskLPE(); - bool success = false; - if (hasPathEffect() && pathEffectsEnabled()) { - success = this->performPathEffect(c_lpe, SP_SHAPE(this)); - if (success) { - this->setCurveInsync(c_lpe); - this->applyToClipPath(this); - this->applyToMask(this); - } - } - - if (write && success) { - Inkscape::XML::Node *repr = this->getRepr(); - if (c_lpe != NULL) { - gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - c_lpe->unref(); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} - Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); @@ -1028,93 +995,67 @@ void SPShape::setCurve(SPCurve *new_curve, unsigned int owner) this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - /** * Sets _curve_before_lpe to refer to the curve. */ void -SPShape::setCurveBeforeLPE(SPCurve *new_curve, unsigned int owner) +SPShape::setCurveBeforeLPE (SPCurve *new_curve) { if (_curve_before_lpe) { _curve_before_lpe = _curve_before_lpe->unref(); } if (new_curve) { - if (owner) { - _curve_before_lpe = new_curve->ref(); - } else { - _curve_before_lpe = new_curve->copy(); - } + _curve_before_lpe = new_curve->ref(); } } /** - * Same as sp_shape_set_curve but without updating the display + * Return duplicate of curve (if any exists) or NULL if there is no curve */ -void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) +SPCurve * SPShape::getCurve() const { if (_curve) { - _curve = _curve->unref(); + return _curve->copy(); } - if (new_curve) { - if (owner) { - _curve = new_curve->ref(); - } else { - _curve = new_curve->copy(); - } - } + return NULL; } - /** - * Return curve (if any exists) or NULL if there is no curve -* if owner == 0 return a copy + * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve */ -SPCurve * SPShape::getCurve(unsigned int owner) const +SPCurve * SPShape::getCurveBeforeLPE() const { - if (_curve) { - if(owner) { - return _curve; + if (hasPathEffectRecursive()) { + if (_curve_before_lpe) { + return this->_curve_before_lpe->copy(); + } + } else { + if (_curve) { + return _curve->copy(); } - return _curve->copy(); } return NULL; } /** - * Return curve *before* LPE (if any exists) or NULL if there is no curve - * If force is set allow return curve_before_lpe even if not - * has path effect like in clips and mask - * if owner == 0 return a copy + * Same as sp_shape_set_curve but without updating the display */ -SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner) const +void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) { - if (_curve_before_lpe) { - if (owner) { - return _curve_before_lpe; - } - return _curve_before_lpe->copy(); - } - return NULL; -} + if (_curve) { + _curve = _curve->unref(); + } -/** - * Return curve for edit - * If force is set allow return curve_before_lpe even if not - * has path effect like in clips and mask - * if owner == 0 return a copy - */ -SPCurve * SPShape::getCurveForEdit(unsigned int owner) const -{ - if (_curve_before_lpe) { + if (new_curve) { if (owner) { - return _curve_before_lpe; + _curve = new_curve->ref(); + } else { + _curve = new_curve->copy(); } - return _curve_before_lpe->copy(); } - return getCurve(owner); } void SPShape::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const { diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index be097e390a..fe9d032755 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -39,16 +39,14 @@ public: SPShape(); virtual ~SPShape(); - SPCurve * getCurve (unsigned int owner = FALSE) const; - SPCurve * getCurveBeforeLPE (unsigned int owner = FALSE) const; - SPCurve * getCurveForEdit (unsigned int owner = FALSE) const; - void setCurve (SPCurve *curve, unsigned int owner = TRUE); - void setCurveBeforeLPE (SPCurve *new_curve, unsigned int owner = TRUE); - void setCurveInsync (SPCurve *curve, unsigned int owner = TRUE); + SPCurve * getCurve () const; + SPCurve * getCurveBeforeLPE () const; + void setCurve (SPCurve *curve, unsigned int owner); + void setCurveInsync (SPCurve *curve, unsigned int owner); + void setCurveBeforeLPE (SPCurve *curve); int hasMarkers () const; int numberOfMarkers (int type) const; - public: // temporarily public, until SPPath is properly classed, etc. SPCurve *_curve_before_lpe; SPCurve *_curve; @@ -75,7 +73,6 @@ public: virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void set_shape(); - virtual void update_patheffect(bool write); }; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index 7a449807df..a84fc60412 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -196,6 +196,24 @@ void SPSpiral::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } +void SPSpiral::update_patheffect(bool write) { + this->set_shape(true); + + if (write) { + Inkscape::XML::Node *repr = this->getRepr(); + + if ( this->_curve != NULL ) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + const char* SPSpiral::displayName() const { return _("Spiral"); } @@ -292,7 +310,7 @@ void SPSpiral::fitAndDraw(SPCurve* c, double dstep, Geom::Point darray[], Geom:: g_assert (is_unit_vector (hat2)); } -void SPSpiral::set_shape() { +void SPSpiral::set_shape(bool force) { if (hasBrokenPathEffect()) { 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"); @@ -300,7 +318,7 @@ void SPSpiral::set_shape() { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync(cold); + this->setCurveInsync( cold, TRUE); this->setCurveBeforeLPE( cold ); cold->unref(); } @@ -345,22 +363,28 @@ void SPSpiral::set_shape() { this->fitAndDraw(c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); } - /* Reset the shape's curve to the "original_curve" + /* 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)*/ - SPCurve * before = this->getCurveBeforeLPE(); - if (before || this->hasPathEffectRecursive()) { - if (!before || before->get_pathvector() != c->get_pathvector()){ - this->setCurveBeforeLPE(c); - this->update_patheffect(false); - } else { - this->setCurveBeforeLPE(c); + if(this->getCurveBeforeLPE()) { + if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { + c->unref(); + return; } - } else { - this->setCurveInsync(c); } - if (before) { - before->unref(); + setCurveInsync( c, TRUE); + setCurveBeforeLPE( c ); + + if (hasPathEffect() && pathEffectsEnabled()) { + SPCurve *c_lpe = c->copy(); + bool success = this->performPathEffect(c_lpe); + + if (success) { + this->setCurveInsync( c_lpe, TRUE); + } + + c_lpe->unref(); } + c->unref(); } diff --git a/src/object/sp-spiral.h b/src/object/sp-spiral.h index 138eae9149..ebf4c9e280 100644 --- a/src/object/sp-spiral.h +++ b/src/object/sp-spiral.h @@ -70,7 +70,8 @@ public: virtual const char* displayName() const; virtual char* description() const; - virtual void set_shape(); + virtual void set_shape(bool force = false); + virtual void update_patheffect(bool write); private: Geom::Point getTangent(double t) const; diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 097b5d9893..9844df98af 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -223,6 +223,23 @@ void SPStar::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } +void SPStar::update_patheffect(bool write) { + this->set_shape(true); + + if (write) { + Inkscape::XML::Node *repr = this->getRepr(); + + if ( this->_curve != NULL ) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} const char* SPStar::displayName() const { if (this->flatsided == false) @@ -347,7 +364,7 @@ sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ) #define NEXT false #define PREV true -void SPStar::set_shape() { +void SPStar::set_shape(bool force) { // perhaps we should convert all our shapes into LPEs without source path // and with knotholders for parameters, then this situation will be handled automatically // by disabling the entire stack (including the shape LPE) @@ -358,7 +375,7 @@ void SPStar::set_shape() { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync(cold); + this->setCurveInsync( cold, TRUE); this->setCurveBeforeLPE(cold); cold->unref(); } @@ -428,22 +445,28 @@ void SPStar::set_shape() { c->closepath(); - /* Reset the shape's curve to the "original_curve" + /* 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)*/ - SPCurve * before = this->getCurveBeforeLPE(); - if (before || this->hasPathEffectRecursive()) { - if (!before || before->get_pathvector() != c->get_pathvector()){ - this->setCurveBeforeLPE(c); - this->update_patheffect(false); - } else { - this->setCurveBeforeLPE(c); + if(this->getCurveBeforeLPE()) { + if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { + c->unref(); + return; } - } else { - this->setCurveInsync(c); } - if (before) { - before->unref(); + this->setCurveInsync( c, TRUE); + this->setCurveBeforeLPE( c ); + + if (hasPathEffect() && pathEffectsEnabled()) { + SPCurve *c_lpe = c->copy(); + bool success = this->performPathEffect(c_lpe); + + if (success) { + this->setCurveInsync( c_lpe, TRUE); + } + + c_lpe->unref(); } + c->unref(); } diff --git a/src/object/sp-star.h b/src/object/sp-star.h index 86f3e8ef91..4519de8694 100644 --- a/src/object/sp-star.h +++ b/src/object/sp-star.h @@ -54,7 +54,8 @@ public: virtual char* description() const; virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; - virtual void set_shape(); + virtual void update_patheffect(bool write); + virtual void set_shape(bool force = false); virtual Geom::Affine set_transform(Geom::Affine const& xform); }; diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 7d5346f317..2eb471bb39 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -123,7 +123,7 @@ ObjectSet::combine(bool skip_undo) did = true; } - SPCurve *c = path->getCurveForEdit(); + SPCurve *c = path->get_curve_for_edit(); if (first == NULL) { // this is the topmost path first = item; parent = first->getRepr()->parent(); @@ -225,7 +225,7 @@ ObjectSet::breakApart(bool skip_undo) continue; } - SPCurve *curve = path->getCurveForEdit(); + SPCurve *curve = path->get_curve_for_edit(); if (curve == NULL) { continue; } @@ -650,7 +650,7 @@ ObjectSet::pathReverse() did = true; - SPCurve *rcurve = path->getCurveForEdit(true)->create_reverse(); + SPCurve *rcurve = path->get_curve_reference()->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 622a843e4c..ae2f63f970 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -771,6 +771,10 @@ Inkscape::XML::Node* ObjectSet::group() { group->setPosition(topmost + 1); set(doc->getObjectByRepr(group)); + SPLPEItem *lpeitem = dynamic_cast(*(items().begin())); + if (lpeitem) { + sp_lpe_item_update_patheffect(lpeitem, true, true); + } DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); @@ -4151,14 +4155,9 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { for (auto& child: obj->children) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); - if (copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { - copy->setAttribute("d", copy->attribute("inkscape:original-d")); - } else if (copy->attribute("inkscape:original-d")) { + if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) + { copy->setAttribute("d", copy->attribute("inkscape:original-d")); - copy->setAttribute("inkscape:original-d", NULL); - } else if (!copy->attribute("inkscape:path-effect") && !SP_IS_PATH(&child)) { - copy->setAttribute("d", NULL); - copy->setAttribute("inkscape:original-d", NULL); } items_to_move.push_back(copy); } @@ -4205,6 +4204,7 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { // rebuild selection addList(items_to_select); + if (!skip_undo) { if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 1c0cc8cb13..cbb51f3122 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2538,7 +2538,7 @@ SPCurve* curve_for_item(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { if (SP_IS_PATH(item)) { - curve = SP_PATH(item)->getCurveForEdit(); + curve = SP_PATH(item)->get_curve_for_edit(); } else { curve = SP_SHAPE(item)->getCurve(); } @@ -2566,7 +2566,7 @@ SPCurve* curve_for_item_before_LPE(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { - curve = SP_SHAPE(item)->getCurveForEdit(); + curve = SP_SHAPE(item)->getCurveBeforeLPE(); } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { diff --git a/src/style-internal.h b/src/style-internal.h index 68b67531dd..7a6c51a3bf 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -872,7 +872,7 @@ public: } bool isNone() const { - return !colorSet && !isPaintserver() && (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL); + return (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL) && !colorSet && !isPaintserver(); } // TODO refine bool isColor() const { diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 6cf7f807a6..ec8ae4f31b 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -42,7 +42,6 @@ #include "object/sp-text.h" #include "ui/icon-names.h" -#include "ui/tools/node-tool.h" #include "ui/widget/imagetoggler.h" namespace Inkscape { @@ -206,16 +205,42 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect) lpe_changed = false; return; } + bool expanderopen = false; + Gtk::Widget * defaultswidget = effect.defaultParamSet(); + if (effectwidget) { + if (defaultswidget) { + Gtk::Expander * expander = NULL; + std::vector childs = dynamic_cast (effectwidget)->get_children(); + if (childs.size()) { + std::vector childs_default = dynamic_cast (childs[childs.size()-1])->get_children(); + if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ + expanderopen = expander->get_expanded(); + } + } + } effectcontrol_vbox.remove(*effectwidget); delete effectwidget; effectwidget = NULL; } - effectwidget = effect.newWidget(); + effectcontrol_frame.set_label(effect.getName()); - effectcontrol_vbox.pack_start(*effectwidget, true, true); + effectwidget = effect.newWidget(); + if (effectwidget) { + + if (defaultswidget) { + Gtk::Expander * expander = NULL; + std::vector childs_default = dynamic_cast (defaultswidget)->get_children(); + if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ + expander->set_expanded(expanderopen); + } + dynamic_cast (effectwidget)->pack_start(*defaultswidget, true, true); + } + effectcontrol_vbox.pack_start(*effectwidget, true, true); + } button_remove.show(); + status_label.hide(); effectcontrol_frame.show(); effectcontrol_vbox.show_all_children(); @@ -229,7 +254,7 @@ LivePathEffectEditor::selectInList(LivePathEffect::Effect* effect) { Gtk::TreeNodeChildren chi = effectlist_view.get_model()->children(); for (Gtk::TreeIter ci = chi.begin() ; ci != chi.end(); ci++) { - if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect && effectlist_view.get_selection()) + if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect) effectlist_view.get_selection()->select(ci); } } @@ -555,16 +580,6 @@ void LivePathEffectEditor::on_effect_selection_changed() if (effect) { lpe_changed = true; showParams(*effect); - //To reload knots and helper paths - Inkscape::Selection *sel = _getSelection(); - if ( sel && !sel->isEmpty() ) { - SPItem *item = sel->singleItem(); - if (item) { - sel->clear(); - sel->add(item); - Inkscape::UI::Tools::sp_update_helperpath(); - } - } } } } diff --git a/src/ui/shape-editor-knotholders.cpp b/src/ui/shape-editor-knotholders.cpp index 885f3ef40d..5fb677f27a 100644 --- a/src/ui/shape-editor-knotholders.cpp +++ b/src/ui/shape-editor-knotholders.cpp @@ -107,7 +107,13 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) { KnotHolder *knotholder = NULL; - if (dynamic_cast(item)) { + SPLPEItem *lpe = dynamic_cast(item); + if (lpe && + lpe->getCurrentLPE() && + lpe->getCurrentLPE()->isVisible() && + lpe->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(lpe, desktop); + } else if (dynamic_cast(item)) { knotholder = new RectKnotHolder(desktop, item, NULL); } else if (dynamic_cast(item)) { knotholder = new Box3DKnotHolder(desktop, item, NULL); @@ -133,20 +139,6 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) return knotholder; } -KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop) -{ - KnotHolder *knotholder = NULL; - - SPLPEItem *lpe = dynamic_cast(item); - if (lpe && - lpe->getCurrentLPE() && - lpe->getCurrentLPE()->isVisible() && - lpe->getCurrentLPE()->providesKnotholder()) { - knotholder = sp_lpe_knot_holder(lpe, desktop); - } - return knotholder; -} - } } // namespace Inkscape diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp index b40bec86f7..3a5aec056d 100644 --- a/src/ui/shape-editor.cpp +++ b/src/ui/shape-editor.cpp @@ -29,16 +29,13 @@ namespace Inkscape { namespace UI { KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); -KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop); bool ShapeEditor::_blockSetItem = false; ShapeEditor::ShapeEditor(SPDesktop *dt, Geom::Affine edit_transform) : desktop(dt), knotholder(nullptr), - lpeknotholder(nullptr), knotholder_listener_attached_for(nullptr), - lpeknotholder_listener_attached_for(nullptr), _edit_transform(edit_transform) { } @@ -61,43 +58,25 @@ void ShapeEditor::unset_item(bool keep_knotholder) { this->knotholder = NULL; } } - if (this->lpeknotholder) { - Inkscape::XML::Node *old_repr = this->lpeknotholder->repr; - if (old_repr && old_repr == lpeknotholder_listener_attached_for) { - sp_repr_remove_listener_by_data(old_repr, this); - Inkscape::GC::release(old_repr); - lpeknotholder_listener_attached_for = NULL; - } - - if (!keep_knotholder) { - delete this->lpeknotholder; - this->lpeknotholder = NULL; - } - } } bool ShapeEditor::has_knotholder() { - return this->knotholder != NULL || this->lpeknotholder != NULL; + return this->knotholder != NULL; } void ShapeEditor::update_knotholder() { if (this->knotholder) this->knotholder->update_knots(); - if (this->lpeknotholder) - this->lpeknotholder->update_knots(); } bool ShapeEditor::has_local_change() { - return (this->knotholder && this->knotholder->local_change != 0) || (this->lpeknotholder && this->lpeknotholder->local_change != 0); + return (this->knotholder && this->knotholder->local_change != 0); } void ShapeEditor::decrement_local_change() { if (this->knotholder) { this->knotholder->local_change = FALSE; } - if (this->lpeknotholder) { - this->lpeknotholder->local_change = FALSE; - } } void ShapeEditor::event_attr_changed(Inkscape::XML::Node * node, gchar const *name, gchar const *, gchar const *, bool, void *data) @@ -144,10 +123,6 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { // only recreate knotholder if none is present this->knotholder = createKnotHolder(item, desktop); } - if (!this->lpeknotholder) { - // only recreate knotholder if none is present - this->lpeknotholder = createLPEKnotHolder(item, desktop); - } if (this->knotholder) { this->knotholder->setEditTransform(_edit_transform); this->knotholder->update_knots(); @@ -159,17 +134,6 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { knotholder_listener_attached_for = repr; } } - if (this->lpeknotholder) { - this->lpeknotholder->setEditTransform(_edit_transform); - this->lpeknotholder->update_knots(); - // setting new listener - repr = this->lpeknotholder->repr; - if (repr != lpeknotholder_listener_attached_for) { - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &shapeeditor_repr_events, this); - lpeknotholder_listener_attached_for = repr; - } - } } } @@ -181,9 +145,6 @@ void ShapeEditor::reset_item(bool keep_knotholder) if (knotholder) { SPObject *obj = desktop->getDocument()->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. set_item(SP_ITEM(obj), keep_knotholder); - } else if (lpeknotholder) { - SPObject *obj = desktop->getDocument()->getObjectByRepr(lpeknotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. - set_item(SP_ITEM(obj), keep_knotholder); } } @@ -194,9 +155,7 @@ bool ShapeEditor::knot_mouseover() const { if (this->knotholder) { return knotholder->knot_mouseover(); } - if (this->lpeknotholder) { - return lpeknotholder->knot_mouseover(); - } + return false; } diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h index 67bce1c98d..e30b2d60b9 100644 --- a/src/ui/shape-editor.h +++ b/src/ui/shape-editor.h @@ -36,7 +36,6 @@ public: bool knot_mouseover() const; KnotHolder *knotholder; - KnotHolder *lpeknotholder; bool has_knotholder(); static void blockSetItem(bool b) { _blockSetItem = b; } // kludge static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, @@ -47,7 +46,6 @@ private: SPDesktop *desktop; Inkscape::XML::Node *knotholder_listener_attached_for; - Inkscape::XML::Node *lpeknotholder_listener_attached_for; Geom::Affine _edit_transform; }; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index dcf0a4d4b7..55e1714201 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -190,7 +190,7 @@ void PathManipulator::writeXML() { if (!_live_outline) _updateOutline(); - if (_live_objects) + if (!_live_objects) _setGeometry(); if (!_path) return; @@ -1152,9 +1152,6 @@ void PathManipulator::_createControlPointsFromGeometry() ++i; } } - if (pathv.empty()) { - return; - } _spcurve->set_pathvector(pathv); pathv *= (_edit_transform * _i2d_transform); @@ -1361,23 +1358,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } builder.flush(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); - for (Geom::PathVector::iterator i = pathv.begin(); i != pathv.end(); ) { - // NOTE: this utilizes the fact that Geom::PathVector is an std::vector. - // When we erase an element, the next one slides into position, - // so we do not increment the iterator even though it is theoretically invalidated. - if (i->empty()) { - i = pathv.erase(i); - } else { - ++i; - } - } - if (pathv.empty()) { - return; - } - - if (_spcurve->get_pathvector() == pathv) { - return; - } _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? @@ -1391,6 +1371,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } } } + if (_live_outline) _updateOutline(); if (_live_objects) @@ -1484,7 +1465,7 @@ void PathManipulator::_getGeometry() } } else { _spcurve->unref(); - _spcurve = _path->getCurveForEdit(); + _spcurve = _path->get_curve_for_edit(); // never allow NULL to sneak in here! if (_spcurve == NULL) { _spcurve = new SPCurve(); @@ -1496,6 +1477,7 @@ void PathManipulator::_getGeometry() void PathManipulator::_setGeometry() { using namespace Inkscape::LivePathEffect; + if (!_lpe_key.empty()) { // copied from nodepath.cpp // NOTE: if we are editing an LPE param, _path is not actually an SPPath, it is @@ -1503,22 +1485,17 @@ void PathManipulator::_setGeometry() Effect *lpe = LIVEPATHEFFECT(_path)->get_lpe(); if (lpe) { PathParam *pathparam = dynamic_cast(lpe->getParameter(_lpe_key.data())); - if (pathparam->get_pathvector() == _spcurve->get_pathvector()) { - return; //False we dont update LPE - } pathparam->set_new_value(_spcurve->get_pathvector(), false); LIVEPATHEFFECT(_path)->requestModified(SP_OBJECT_MODIFIED_FLAG); } } else { - // return true to leave the decission on empty to the caller. - // Maybe the path become empty and we want to update to empty if (empty()) return; - if (SPCurve * original = _path->getCurveBeforeLPE()){ + if (SPCurve * original = _path->get_original_curve()){ if(!_spcurve->is_equal(original)) { - _path->setCurveBeforeLPE(_spcurve); + _path->set_original_curve(_spcurve, false, false); delete original; } - } else if(!_spcurve->is_equal(_path->getCurve(true))) { + } else if(!_spcurve->is_equal(_path->get_curve())) { _path->setCurve(_spcurve, false); } } @@ -1681,6 +1658,7 @@ Geom::Coord PathManipulator::_updateDragPoint(Geom::Point const &evp) Geom::Affine to_desktop = _edit_transform * _i2d_transform; Geom::PathVector pv = _spcurve->get_pathvector(); + boost::optional pvp = pv.nearestTime(_desktop->w2d(evp) * to_desktop.inverse()); if (!pvp) return dist; diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index 20b309a98f..ec55ab80b2 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -617,7 +617,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) Geom::Affine i2d ( (this->clickeditem)->i2dt_affine() ); Geom::Affine d2i = i2d.inverse(); SPPath *path = SP_PATH(this->clickeditem); - SPCurve *curve = path->getCurve(true); + SPCurve *curve = path->get_curve(); if (this->clickedhandle == this->endpt_handle[0]) { Geom::Point o = this->endpt_handle[1]->pos; curve->stretch_endpoints(p * d2i, o * d2i); @@ -628,7 +628,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) sp_conn_reroute_path_immediate(path); // Copy this to the temporary visible path - this->red_curve = path->getCurveForEdit(); + this->red_curve = path->get_curve_for_edit(); this->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve, true); @@ -1041,7 +1041,7 @@ static gboolean endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool * } // Show the red path for dragging. - cc->red_curve = SP_PATH(cc->clickeditem)->getCurveForEdit(); + cc->red_curve = SP_PATH(cc->clickeditem)->get_curve_for_edit(); Geom::Affine i2d = (cc->clickeditem)->i2dt_affine(); cc->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve, true); @@ -1135,7 +1135,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { g_assert( SP_IS_PATH(item) ); - const SPCurve *curve = SP_PATH(item)->getCurveForEdit(true); + const SPCurve *curve = SP_PATH(item)->get_curve_reference(); Geom::Affine i2dt = item->i2dt_affine(); if (this->active_conn == item) { @@ -1275,7 +1275,7 @@ static bool cc_item_is_shape(SPItem *item) bool cc_item_is_connector(SPItem *item) { if (SP_IS_PATH(item)) { - bool closed = SP_PATH(item)->getCurveForEdit(true)->is_closed(); + bool closed = SP_PATH(item)->get_curve_reference()->is_closed(); if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) { // To be considered a connector, an object must be a non-closed // path that is marked with a "inkscape:connector-type" attribute. diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index b57aa2fb03..26d8123940 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -645,7 +645,7 @@ static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/ // Curve list // We keep it in desktop coordinates to eliminate calculation errors - SPCurve *norm = SP_PATH(item)->getCurveForEdit(); + SPCurve *norm = SP_PATH(item)->get_curve_for_edit(); norm->transform((dc->white_item)->i2dt_affine()); g_return_if_fail( norm != NULL ); dc->white_curves = norm->split(); diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index d54adba89a..6e586b0e99 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -533,7 +533,7 @@ bool NodeTool::root_handler(GdkEvent* event) { } this->flashed_item = over_item; - SPCurve *c = SP_SHAPE(over_item)->getCurveForEdit(); + SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE(); if (!c) { break; // break out when curve doesn't exist diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 3988ca544f..d317fa216e 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -109,7 +109,7 @@ typedef enum { // code, those warnings are actually desired. They say "Hey! Fix this". We // definitely don't want to hide/ignore them. --JonCruz static const GtkTargetEntry ui_drop_target_entries [] = { - {g_strdup("application/x-color"), 0, APP_X_COLOR} + {"application/x-color", 0, APP_X_COLOR} }; static guint nui_drop_target_entries = G_N_ELEMENTS(ui_drop_target_entries); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index d2939c7209..fb9afb8daa 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -320,7 +320,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveForEdit(); + SPCurve * c = shape->getCurveBeforeLPE(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ @@ -328,7 +328,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c, false); + shape->setCurve(c,0); } break; } @@ -361,7 +361,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) if (dynamic_cast(lpe)) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveForEdit(); + SPCurve * c = shape->getCurveBeforeLPE(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ @@ -369,7 +369,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c, false); + shape->setCurve(c,0); } break; } -- GitLab From bb056ceef7e89bdaee16e640a021a51c220a0ca4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 3 Mar 2018 00:10:45 +0100 Subject: [PATCH 57/57] Add base of code --- src/live_effects/effect.cpp | 93 ++- src/live_effects/effect.h | 16 +- src/live_effects/lpe-bendpath.cpp | 10 +- src/live_effects/lpe-bspline.cpp | 5 +- src/live_effects/lpe-clone-original.cpp | 18 +- src/live_effects/lpe-copy_rotate.cpp | 136 +++-- src/live_effects/lpe-copy_rotate.h | 3 +- src/live_effects/lpe-envelope.cpp | 4 +- src/live_effects/lpe-fillet-chamfer.cpp | 19 +- src/live_effects/lpe-interpolate.cpp | 2 +- src/live_effects/lpe-lattice.cpp | 4 +- src/live_effects/lpe-lattice2.cpp | 7 +- src/live_effects/lpe-measure-segments.cpp | 576 +++++++++++------- src/live_effects/lpe-measure-segments.h | 28 +- src/live_effects/lpe-mirror_symmetry.cpp | 250 ++++---- src/live_effects/lpe-mirror_symmetry.h | 12 +- src/live_effects/lpe-patternalongpath.cpp | 4 +- src/live_effects/lpe-perp_bisector.cpp | 4 +- src/live_effects/lpe-perspective-envelope.cpp | 7 +- src/live_effects/lpe-perspective_path.cpp | 3 + src/live_effects/lpe-powerclip.cpp | 58 +- src/live_effects/lpe-powerclip.h | 1 + src/live_effects/lpe-powermask.cpp | 14 +- src/live_effects/lpe-powerstroke.cpp | 8 +- src/live_effects/lpe-roughen.cpp | 3 + src/live_effects/lpe-show_handles.cpp | 2 +- src/live_effects/lpe-simplify.cpp | 3 + src/live_effects/lpe-transform_2pts.cpp | 13 +- src/live_effects/lpe-vonkoch.cpp | 4 +- src/live_effects/lpegroupbbox.cpp | 40 +- src/live_effects/lpegroupbbox.h | 7 +- src/live_effects/parameter/array.h | 3 +- src/live_effects/parameter/bool.cpp | 6 +- src/live_effects/parameter/enum.h | 6 +- src/live_effects/parameter/hidden.cpp | 6 +- src/live_effects/parameter/message.cpp | 12 +- src/live_effects/parameter/message.h | 4 +- .../parameter/originalitemarray.cpp | 3 +- src/live_effects/parameter/originalpath.cpp | 2 +- .../parameter/originalpatharray.cpp | 9 +- src/live_effects/parameter/parameter.cpp | 9 +- src/live_effects/parameter/path.cpp | 2 +- src/live_effects/parameter/point.cpp | 19 +- src/live_effects/parameter/random.cpp | 6 +- src/live_effects/parameter/text.cpp | 6 +- src/live_effects/parameter/togglebutton.cpp | 6 +- .../parameter/transformedpoint.cpp | 6 +- src/live_effects/parameter/vector.cpp | 6 +- src/object/box3d-side.cpp | 25 +- src/object/sp-clippath.cpp | 6 +- src/object/sp-conn-end-pair.cpp | 4 +- src/object/sp-ellipse.cpp | 66 +- src/object/sp-ellipse.h | 4 +- src/object/sp-item-group.cpp | 72 ++- src/object/sp-item.cpp | 18 +- src/object/sp-item.h | 4 + src/object/sp-line.cpp | 2 +- src/object/sp-lpe-item.cpp | 524 +++++++++------- src/object/sp-lpe-item.h | 15 +- src/object/sp-mask.cpp | 27 + src/object/sp-mask.h | 4 + src/object/sp-object.cpp | 1 - src/object/sp-offset.cpp | 4 +- src/object/sp-path.cpp | 135 +--- src/object/sp-path.h | 33 +- src/object/sp-polygon.cpp | 2 +- src/object/sp-polyline.cpp | 2 +- src/object/sp-rect.cpp | 6 +- src/object/sp-shape.cpp | 111 +++- src/object/sp-shape.h | 13 +- src/object/sp-spiral.cpp | 52 +- src/object/sp-spiral.h | 3 +- src/object/sp-star.cpp | 51 +- src/object/sp-star.h | 3 +- src/path-chemistry.cpp | 6 +- src/selection-chemistry.cpp | 14 +- src/splivarot.cpp | 4 +- src/style-internal.h | 2 +- src/ui/dialog/livepatheffect-editor.cpp | 43 +- src/ui/shape-editor-knotholders.cpp | 22 +- src/ui/shape-editor.cpp | 47 +- src/ui/shape-editor.h | 2 + src/ui/tool/path-manipulator.cpp | 38 +- src/ui/tools/connector-tool.cpp | 10 +- src/ui/tools/freehand-base.cpp | 2 +- src/ui/tools/node-tool.cpp | 2 +- src/ui/widget/selected-style.cpp | 2 +- src/widgets/pencil-toolbar.cpp | 8 +- 88 files changed, 1569 insertions(+), 1285 deletions(-) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 44b737ad11..bfc280ce6c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -394,9 +394,9 @@ Effect::Effect(LivePathEffectObject *lpeobject) sp_lpe_item(NULL), current_zoom(1), upd_params(true), - sp_shape(NULL), - sp_curve(NULL), + current_shape(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden + defaultsopen(false), is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { registerParameter( dynamic_cast(&is_visible) ); @@ -469,14 +469,14 @@ Effect::processObjects(LpeAction lpe_action) if (!document) { return; } - for (std::vector::iterator el_it = items.begin(); + for (std::vector::iterator el_it = items.begin(); el_it != items.end(); ++el_it) { - const char * id = *el_it; - if (!id) { + Glib::ustring id = *el_it; + if (id.empty()) { return; } SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { + if ((elemref = document->getObjectById(id.c_str()))) { Inkscape::XML::Node * elemnode = elemref->getRepr(); std::vector item_list; item_list.push_back(SP_ITEM(elemref)); @@ -527,17 +527,6 @@ Effect::processObjects(LpeAction lpe_action) } } -void Effect::setCurrentShape(SPShape * shape){ - if(shape){ - sp_shape = shape; - if (!(sp_curve = sp_shape->getCurveBeforeLPE())) { - // oops - return; - } - pathvector_before_effect = sp_curve->get_pathvector(); - } -} - /** * Is performed each time before the effect is updated. */ @@ -562,21 +551,13 @@ void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - setCurrentShape(shape); doOnApply(lpeitem); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - SPShape * shape = dynamic_cast(sp_lpe_item); - setCurrentShape(shape); doBeforeEffect(lpeitem); - if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { - sp_lpe_item->applyToClipPath(sp_lpe_item); - sp_lpe_item->applyToMask(sp_lpe_item); - } update_helperpath(); } @@ -813,6 +794,9 @@ Effect::newWidget() ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -824,7 +808,6 @@ Effect::defaultParamSet() { // use manage here, because after deletion of Effect object, others might still be pointing to this widget. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() ); Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() ); Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType()); Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType()); @@ -836,27 +819,28 @@ Effect::defaultParamSet() has_params = true; Parameter * param = *it; Glib::ustring * tip = param->param_getTooltip(); - const gchar * key = param->param_key.c_str(); - const gchar * value = param->param_label.c_str(); - - Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + - effectkey + - (Glib::ustring)"/" + - (Glib::ustring)key; + const gchar * key = param->param_key.c_str(); + const gchar * label = param->param_label.c_str(); + Glib::ustring value = param->param_getSVGValue(); + Glib::ustring defvalue = param->param_getDefaultSVGValue(); + Glib::ustring pref_path = "/live_effects/"; + pref_path += effectkey; + pref_path +="/"; + pref_path += key; bool valid = prefs->getEntry(pref_path).isValid(); const gchar * set_or_upd; - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(prefs->getString(pref_path)) + Glib::ustring("\n"); if (valid) { set_or_upd = _("Update"); - def = Glib::ustring(_("Default value: ")) + Glib::ustring(param->param_getDefaultSVGValue()) + Glib::ustring("\n"); + def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); } else { set_or_upd = _("Set"); ove = Glib::ustring(_("Default value overridden: None\n")); } - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(param->param_getSVGValue()); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) ); - Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START)); + Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START)); parameter_label->set_use_markup(true); parameter_label->set_use_underline(true); Glib::ustring tooltip = Glib::ustring("") + parameter_label->get_text () + Glib::ustring("\n") + param->param_tooltip + Glib::ustring("\n\n"); @@ -865,9 +849,9 @@ Effect::defaultParamSet() vbox_param->pack_start(*parameter_label, true, true, 2); Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd)); Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset")))); - unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + unset->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); - set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, param->param_getSVGValue(), param->param_getDefaultSVGValue(), parameter_label, set, unset)); + set->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, tooltip, value, defvalue, parameter_label, set, unset)); if (!valid) { unset->set_sensitive(false); } @@ -882,11 +866,12 @@ Effect::defaultParamSet() Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip)); expander->set_use_markup(true); expander->add(*vbox_expander); - expander->set_expanded(false); - vbox->pack_start(*dynamic_cast (expander), true, true, 2); + expander->set_expanded(defaultsopen); + //expander->set_size_request(-1, 90); + expander->property_expanded().signal_changed().connect(sigc::bind<0>(sigc::mem_fun(*this, &Effect::onDefaultsExpanderChanged), expander )); if (has_params) { - Gtk::Widget *vboxwidg = dynamic_cast(vbox); - vboxwidg->set_margin_bottom(10); + Gtk::Widget *vboxwidg = dynamic_cast(expander); + vboxwidg->set_margin_bottom(5); vboxwidg->set_margin_top(5); return vboxwidg; } else { @@ -895,30 +880,36 @@ Effect::defaultParamSet() } void -Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::onDefaultsExpanderChanged(Gtk::Expander * expander) +{ + defaultsopen = expander->get_expanded(); +} + +void +Effect::setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(pref_path, (Glib::ustring)value); + prefs->setString(pref_path, value); gchar * label = _("Update"); set->set_label((Glib::ustring)label); unset->set_sensitive(true); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); - Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + Glib::ustring(value) + Glib::ustring("\n"); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); + Glib::ustring ove = Glib::ustring(_("Default value overridden: ")) + value + Glib::ustring("\n"); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + value; parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } void -Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) +Effect::unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->remove(pref_path); gchar * label = _("Set"); set->set_label((Glib::ustring)label); unset->set_sensitive(false); - Glib::ustring def = Glib::ustring(_("Default value: ")) + Glib::ustring(defvalue) + Glib::ustring("\n"); + Glib::ustring def = Glib::ustring(_("Default value: ")) + defvalue + Glib::ustring("\n"); Glib::ustring ove = Glib::ustring(_("Default value overridden: None\n")); - Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) + Glib::ustring(value); + Glib::ustring cur = Glib::ustring(_("Current parameter value: ")) +value; parameter_label->set_tooltip_markup((tooltip + def + ove + cur).c_str()); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index d0024f8772..d162b8bb4d 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -10,6 +10,7 @@ #include #include <2geom/forward.h> #include "ui/widget/registry.h" +#include #include "parameter/bool.h" #include "effect-enum.h" @@ -79,8 +80,8 @@ public: static int acceptsNumClicks(EffectType type); int acceptsNumClicks() const { return acceptsNumClicks(effectType()); } void doAcceptPathPreparations(SPLPEItem *lpeitem); - SPShape * getCurrentShape(){ return sp_shape; }; - void setCurrentShape(SPShape * shape); + SPShape * getCurrentShape() const { return current_shape; }; + void setCurrentShape(SPShape * shape) { current_shape = shape; } void processObjects(LpeAction lpe_action); /* @@ -136,7 +137,6 @@ public: bool is_load; bool upd_params; BoolParam is_visible; - SPCurve * sp_curve; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; protected: @@ -175,17 +175,19 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them. - std::vector items; + SPShape * current_shape; // these get stored in performPathEffects. + std::vector items; double current_zoom; std::vector selectedNodesPoints; private: - void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); - void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, gchar * value, gchar * defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void onDefaultsExpanderChanged(Gtk::Expander * expander); + void setDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); + void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring par, Glib::ustring value, Glib::ustring defvalue, Gtk::Label *parameter_label, Gtk::Button *set , Gtk::Button *unset); bool provides_own_flash_paths; // if true, the standard flash path is suppressed bool is_ready; + bool defaultsopen; Effect(const Effect&); Effect& operator=(const Effect&); diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 314ddc84c5..11694249a3 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -86,9 +86,8 @@ void LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); original_height = boundingbox_Y.max() - boundingbox_Y.min(); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (_knot_entity) { if (hide_knot) { helper_path.clear(); @@ -152,8 +151,7 @@ void LPEBendPath::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); @@ -171,9 +169,7 @@ LPEBendPath::resetDefaults(SPItem const* item) void LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) { - if (sp_lpe_item) { - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); - } + //block parameters be transformed because shapes with bend store transform in the element } void diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index f007599215..7834ff108b 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -139,6 +139,9 @@ Gtk::Widget *LPEBSpline::newWidget() ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -164,7 +167,7 @@ void LPEBSpline::changeWeight(double weight_ammount) { SPPath *path = dynamic_cast(sp_lpe_item); if(path) { - SPCurve *curve = path->get_curve_for_edit(); + SPCurve *curve = path->getCurveForEdit(); doBSplineFromWidget(curve, weight_ammount/100.0); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp index 413c188930..d0ff805002 100644 --- a/src/live_effects/lpe-clone-original.cpp +++ b/src/live_effects/lpe-clone-original.cpp @@ -124,7 +124,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * if ( shape_dest && shape_origin && (std::strcmp(attribute, "d") == 0)) { SPCurve *c = NULL; if (method == CLM_BSPLINESPIRO) { - c = shape_origin->getCurveBeforeLPE(); + c = shape_origin->getCurveForEdit(); SPLPEItem * lpe_item = SP_LPE_ITEM(origin); if (lpe_item) { PathEffectList lpelist = lpe_item->getEffectList(); @@ -142,7 +142,7 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, const char * } } } else if(method == CLM_ORIGINALD) { - c = shape_origin->getCurveBeforeLPE(); + c = shape_origin->getCurveForEdit(); } else { c = shape_origin->getCurve(); } @@ -200,15 +200,17 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ if (method != CLM_NONE) { attr += Glib::ustring("d,"); } - attr += Glib::ustring(attributes.param_getSVGValue()) + Glib::ustring(","); - if (attr.size() && !Glib::ustring(attributes.param_getSVGValue()).size()) { + gchar * attributes_str = attributes.param_getSVGValue(); + attr += Glib::ustring(attributes_str) + Glib::ustring(","); + if (attr.size() && !Glib::ustring(attributes_str).size()) { attr.erase (attr.size()-1, 1); } + gchar * style_attributes_str = style_attributes.param_getSVGValue(); Glib::ustring style_attr = ""; - if (style_attr.size() && !Glib::ustring(style_attributes.param_getSVGValue()).size()) { + if (style_attr.size() && !Glib::ustring( style_attributes_str).size()) { style_attr.erase (style_attr.size()-1, 1); } - style_attr += Glib::ustring(style_attributes.param_getSVGValue()) + Glib::ustring(","); + style_attr += Glib::ustring( style_attributes_str) + Glib::ustring(","); SPItem * orig = SP_ITEM(linkeditem.getObject()); SPItem * dest = SP_ITEM(sp_lpe_item); @@ -257,6 +259,8 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){ } linked = g_strdup(id); + g_free(style_attributes_str); + g_free(attributes_str); g_free(id); } else { linked = g_strdup(""); @@ -336,7 +340,7 @@ LPECloneOriginal::doEffect (SPCurve * curve) // if (linkeditem.linksToItem()) { // SPShape * shape = getCurrentShape(); // if(shape){ -// curve->set_pathvector(shape->getCurveBeforeLPE()->get_pathvector()); +// curve->set_pathvector(shape->getCurveForEdit()->get_pathvector()); // } // } } diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index ebcb95f0da..6bf2a78bd3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,6 +17,7 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/intersection-graph.h> #include "live_effects/lpe-copy_rotate.h" +#include "live_effects/lpeobject.h" #include "display/curve.h" #include "svg/path-string.h" #include "svg/svg.h" @@ -55,7 +56,6 @@ pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const & return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; } - LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), method(_("Method:"), _("Rotate methods"), "method", RMConverter, &wr, this, RM_NORMAL), @@ -66,7 +66,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), gap(_("Gap"), _("Gap"), "gap", &wr, this, -0.0001), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, false), + mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, true), split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), dist_angle_handle(100.0) { @@ -129,12 +129,15 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) if (numcopies_gap > 0 && num_copies != 0) { guint counter = num_copies - 1; while (numcopies_gap > 0) { - const char * id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); - if (!id || strlen(id) == 0) { + Glib::ustring id = Glib::ustring("rotated-"); + id += std::to_string(counter); + id += "-"; + id += this->lpeobj->getId(); + if (id.empty()) { return; } SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { + if (elemref = document->getObjectById(id.c_str())) { SP_ITEM(elemref)->setHidden(true); } counter++; @@ -144,10 +147,14 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) previous_num_copies = num_copies; } SPObject *elemref = NULL; - const char * id = g_strdup(Glib::ustring("rotated-").append("0").append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); guint counter = 0; - while((elemref = document->getObjectById(id))) { - id = g_strdup(Glib::ustring("rotated-").append(std::to_string(counter)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + Glib::ustring id = "rotated-0-"; + id += this->lpeobj->getId(); + while((elemref = document->getObjectById(id.c_str()))) { + id = Glib::ustring("rotated-"); + id += std::to_string(counter); + id += "-"; + id += this->lpeobj->getId(); if (SP_ITEM(elemref)->isHidden()) { items.push_back(id); } @@ -184,7 +191,7 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) } void -LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset) +LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -197,30 +204,29 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, transform, false, reset); + cloneD(*obj_it, dest_child, transform, reset); index++; } + return; } SPShape * shape = SP_SHAPE(orig); - if (shape && !SP_IS_PATH(dest)) { + SPPath * path = SP_PATH(dest); + if (shape && !path) { const char * id = dest->getId(); Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); dest->getRepr()->setAttribute("d", id); + path = SP_PATH(dest); } - if (SP_IS_PATH(dest) && shape) { - SPCurve *c = NULL; - if (root) { - c = new SPCurve(); - c->set_pathvector(pathvector_after_effect); - } else { - c = shape->getCurve(); - } + if (path && shape) { + SPCurve *c = shape->getCurve(); if (c) { - SP_PATH(dest)->setCurve(c, TRUE); + gchar *str = sp_svg_write_path(c->get_pathvector()); + path->getRepr()->setAttribute("d", str); + g_free(str); c->unref(); } else { - dest->getRepr()->setAttribute("d", NULL); + path->getRepr()->setAttribute("d", NULL); } if (reset) { dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); @@ -228,6 +234,33 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } } +Inkscape::XML::Node * +LPECopyRotate::createPathBase(SPObject *elemref) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return NULL; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Node *prev = elemref->getRepr(); + SPGroup *group = dynamic_cast(elemref); + if (group) { + Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); + container->setAttribute("transform", prev->attribute("transform")); + std::vector const item_list = sp_item_group_item_list(group); + Inkscape::XML::Node *previous = NULL; + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *sub_item = *iter; + Inkscape::XML::Node *resultnode = createPathBase(sub_item); + container->addChild(resultnode, previous); + previous = resultnode; + } + return container; + } + Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); + resultnode->setAttribute("transform", prev->attribute("transform")); + return resultnode; +} + void LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) { @@ -236,64 +269,32 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset) return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * elemref_id = g_strdup(Glib::ustring("rotated-").append(std::to_string(i)).append("-").append(sp_lpe_item->getRepr()->attribute("id")).c_str()); + Glib::ustring elemref_id = Glib::ustring("rotated-"); + elemref_id += std::to_string(i); + elemref_id += "-"; + elemref_id += this->lpeobj->getId(); items.push_back(elemref_id); SPObject *elemref= NULL; Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id))) { + if (elemref = document->getObjectById(elemref_id.c_str())) { phantom = elemref->getRepr(); } else { - phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); - std::vector attrs; - attrs.push_back("inkscape:path-effect"); - attrs.push_back("inkscape:original-d"); - attrs.push_back("sodipodi:type"); - attrs.push_back("sodipodi:rx"); - attrs.push_back("sodipodi:ry"); - attrs.push_back("sodipodi:cx"); - attrs.push_back("sodipodi:cy"); - attrs.push_back("sodipodi:end"); - attrs.push_back("sodipodi:start"); - attrs.push_back("inkscape:flatsided"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:rounded"); - attrs.push_back("sodipodi:arg1"); - attrs.push_back("sodipodi:arg2"); - attrs.push_back("sodipodi:r1"); - attrs.push_back("sodipodi:r2"); - attrs.push_back("sodipodi:sides"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("sodipodi:argument"); - attrs.push_back("sodipodi:expansion"); - attrs.push_back("sodipodi:radius"); - attrs.push_back("sodipodi:revolution"); - attrs.push_back("sodipodi:t0"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("x"); - attrs.push_back("y"); - attrs.push_back("rx"); - attrs.push_back("ry"); - attrs.push_back("width"); - attrs.push_back("height"); - phantom->setAttribute("id", elemref_id); - for(const char * attr : attrs) { - phantom->setAttribute(attr, NULL); - } + phantom = createPathBase(sp_lpe_item); + phantom->setAttribute("id", elemref_id.c_str()); + reset = true; } if (!elemref) { elemref = container->appendChildRepr(phantom); Inkscape::GC::release(phantom); } - cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, true, reset); + cloneD(SP_OBJECT(sp_lpe_item), elemref, transform, reset); gchar *str = sp_svg_transform_write(transform); elemref->getRepr()->setAttribute("transform" , str); g_free(str); SP_ITEM(elemref)->setHidden(false); if (elemref->parent != container) { Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id); + copy->setAttribute("id", elemref_id.c_str()); container->appendChildRepr(copy); Inkscape::GC::release(copy); elemref->deleteObject(); @@ -340,6 +341,9 @@ Gtk::Widget * LPECopyRotate::newWidget() reset_button->set_size_request(110,20); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -348,7 +352,7 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); @@ -375,7 +379,7 @@ void LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); if (copies_to_360 && num_copies > 2) { rotation_angle.param_set_value(360.0/(double)num_copies); } @@ -711,7 +715,7 @@ void LPECopyRotate::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); } void diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index a0a3d4dc15..dcbd1c45eb 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,7 +48,8 @@ public: virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toItem(Geom::Affine transform, size_t i, bool reset); - void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool root, bool reset); + void cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bool reset); + Inkscape::XML::Node * createPathBase(SPObject *elemref); void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index b50efde345..0dcae51e41 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -42,7 +42,7 @@ void LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); } Geom::Piecewise > @@ -218,7 +218,7 @@ LPEEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Geom::Point Up_Left(boundingbox_X.min(), boundingbox_Y.min()); Geom::Point Up_Right(boundingbox_X.max(), boundingbox_Y.min()); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 94a43b728a..59a6324e75 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -111,7 +111,9 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + gchar * mode_str = mode.param_getSVGValue(); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); + g_free(mode_str); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } @@ -250,7 +252,9 @@ Gtk::Widget *LPEFilletChamfer::newWidget() vbox->pack_start(*fillet_container, true, true, 2); vbox->pack_start(*chamfer_container, true, true, 2); - + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return vbox; } @@ -320,14 +324,14 @@ void LPEFilletChamfer::setSelected(PathVectorSatellites *_pathvector_satellites) void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) { - if (sp_curve) { + if (!pathvector_before_effect.empty()) { //fillet chamfer specific calls satellites_param.setUseDistance(use_knot_distance); satellites_param.setCurrentZoom(current_zoom); //mandatory call satellites_param.setEffectType(effectType()); - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); - //if are different sizes call to recalculate + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); + //if are diferent sizes call to recalculate //TODO: Update the satellite data in paths modified, Satellites satellites = satellites_param.data(); if (satellites.empty()) { @@ -338,7 +342,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) size_t number_nodes = pathv.nodes().size(); size_t previous_number_nodes = _pathvector_satellites->getTotalSatellites(); if (number_nodes != previous_number_nodes) { - Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(sp_curve->get_pathvector()); Satellites satellites; double power = radius; if (!flexible) { @@ -350,7 +353,9 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) SatelliteType satellite_type = FILLET; std::map gchar_map_to_satellite_type = boost::assign::map_list_of("F", FILLET)("IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE); - std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode.param_getSVGValue())); + gchar * mode_str = mode.param_getSVGValue(); + std::map::iterator it = gchar_map_to_satellite_type.find(std::string(mode_str)); + g_free(mode_str); if (it != gchar_map_to_satellite_type.end()) { satellite_type = it->second; } diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index f6b42cfb92..70bc92a27f 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -104,7 +104,7 @@ LPEInterpolate::resetDefaults(SPItem const* item) if (!SP_IS_PATH(item)) return; - SPCurve const *crv = SP_PATH(item)->get_curve_reference(); + SPCurve const *crv = SP_PATH(item)->getCurveForEdit(true); Geom::PathVector const &pathv = crv->get_pathvector(); if ( (pathv.size() < 2) ) return; diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index 124a7a9c6a..df4da45905 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -164,7 +164,7 @@ LPELattice::doEffect_pwd2 (Geom::Piecewise > const & pwd2 void LPELattice::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); } void @@ -172,7 +172,7 @@ LPELattice::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item), false); + original_bbox(SP_LPE_ITEM(item), false, true); // place the 16 control points grid_point0[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 3eeb6e746a..8c2c3ec317 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -268,6 +268,9 @@ LPELattice2::newWidget() expander->set_expanded(expanded); vbox->pack_start(*expander, true, true, 2); expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPELattice2::onExpanderChanged) ); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -327,7 +330,7 @@ LPELattice2::horizontal(PointParam ¶m_one, PointParam ¶m_two, Geom::Line void LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); setDefaults(); Geom::Line vert(grid_point_8x9.param_get_default(),grid_point_10x11.param_get_default()); Geom::Line horiz(grid_point_24x26.param_get_default(),grid_point_25x27.param_get_default()); @@ -551,7 +554,7 @@ void LPELattice2::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 9bfa2c52e8..cff5aec4b8 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -8,36 +8,40 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "live_effects/lpe-measure-segments.h" -#include "live_effects/lpeobject.h" -#include -#include "ui/dialog/livepatheffect-editor.h" -#include -#include "inkscape.h" -#include "xml/node.h" -#include "xml/sp-css-attr.h" -#include "preferences.h" -#include "util/units.h" -#include "svg/svg-length.h" -#include "svg/svg-color.h" -#include "svg/stringstream.h" -#include "svg/svg.h" + +#include +#include "2geom/affine.h" +#include "2geom/angle.h" +#include "2geom/point.h" +#include "2geom/ray.h" #include "display/curve.h" #include "helper/geom.h" -#include "2geom/affine.h" -#include "path-chemistry.h" -#include "document.h" -#include "document-undo.h" -#include -#include - -#include "object/sp-root.h" +#include "live_effects/lpe-measure-segments.h" #include "object/sp-defs.h" #include "object/sp-item.h" -#include "object/sp-shape.h" #include "object/sp-path.h" +#include "object/sp-root.h" +#include "object/sp-shape.h" #include "object/sp-star.h" #include "object/sp-spiral.h" +#include "svg/stringstream.h" +#include "svg/svg.h" +#include "svg/svg-color.h" +#include "svg/svg-length.h" +#include "util/units.h" +#include "xml/node.h" +#include "xml/sp-css-attr.h" + +#include "document.h" +#include "document-undo.h" +#include "inkscape.h" +#include "preferences.h" +#include "path-chemistry.h" + +#include +#include +#include +#include // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -46,10 +50,11 @@ using namespace Geom; namespace Inkscape { namespace LivePathEffect { + static const Util::EnumData OrientationMethodData[] = { - { OM_HORIZONTAL, N_("Horizontal"), "horizontal" }, - { OM_VERTICAL, N_("Vertical"), "vertical" }, - { OM_PARALLEL, N_("Parallel"), "parallel" } + { OM_HORIZONTAL , N_("Horizontal"), "horizontal" }, + { OM_VERTICAL , N_("Vertical") , "vertical" }, + { OM_PARALLEL , N_("Parallel") , "parallel" } }; static const Util::EnumDataConverter OMConverter(OrientationMethodData, OM_END); @@ -102,7 +107,6 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : registerParameter(&rotate_anotation); registerParameter(&hide_back); registerParameter(&message); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring format_value = prefs->getString("/live_effects/measure-line/format"); @@ -140,21 +144,26 @@ LPEMeasureSegments::LPEMeasureSegments(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_increments(1, 1); helpline_overlap.param_set_digits(2); star_ellipse_fix = Geom::identity(); - message.param_set_min_height(95); + locale_base = strdup(setlocale(LC_NUMERIC, NULL)); + message.param_set_min_height(85); + previous_size = 0; } -LPEMeasureSegments::~LPEMeasureSegments() {} +LPEMeasureSegments::~LPEMeasureSegments() { + doOnRemove(NULL); +} void -LPEMeasureSegments::createArrowMarker(const char * mode) +LPEMeasureSegments::createArrowMarker(Glib::ustring mode) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); Glib::ustring style; gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); style = Glib::ustring("fill:") + Glib::ustring(c); Inkscape::SVGOStringStream os; @@ -163,7 +172,7 @@ LPEMeasureSegments::createArrowMarker(const char * mode) Inkscape::XML::Document *xml_doc = document->getReprDoc(); SPObject *elemref = NULL; Inkscape::XML::Node *arrow = NULL; - if ((elemref = document->getObjectById(mode))) { + if ((elemref = document->getObjectById(mode.c_str()))) { Inkscape::XML::Node *arrow= elemref->getRepr(); if (arrow) { arrow->setAttribute("sodipodi:insensitive", "true"); @@ -176,9 +185,13 @@ LPEMeasureSegments::createArrowMarker(const char * mode) } } else { arrow = xml_doc->createElement("svg:marker"); - arrow->setAttribute("id", mode); - arrow->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows-marker")).c_str()); - arrow->setAttribute("inkscape:stockid", mode); + arrow->setAttribute("id", mode.c_str()); + Glib::ustring classarrow = itemid; + classarrow += " "; + classarrow += lpobjid; + classarrow += " measure-arrows-marker"; + arrow->setAttribute("class", classarrow.c_str()); + arrow->setAttribute("inkscape:stockid", mode.c_str()); arrow->setAttribute("orient", "auto"); arrow->setAttribute("refX", "0.0"); arrow->setAttribute("refY", "0.0"); @@ -186,17 +199,22 @@ LPEMeasureSegments::createArrowMarker(const char * mode) arrow->setAttribute("sodipodi:insensitive", "true"); /* Create */ Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path"); - if (std::strcmp(mode, "ArrowDIN-start") == 0) { + if (std::strcmp(mode.c_str(), "ArrowDIN-start") == 0) { arrow_path->setAttribute("d", "M -8,0 8,-2.11 8,2.11 z"); - } else if (std::strcmp(mode, "ArrowDIN-end") == 0) { + } else if (std::strcmp(mode.c_str(), "ArrowDIN-end") == 0) { arrow_path->setAttribute("d", "M 8,0 -8,2.11 -8,-2.11 z"); - } else if (std::strcmp(mode, "ArrowDINout-start") == 0) { + } else if (std::strcmp(mode.c_str(), "ArrowDINout-start") == 0) { arrow_path->setAttribute("d", "M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z"); } else { arrow_path->setAttribute("d", "M 0,0 16,-2.11 16,-0.5 26,-0.5 26,0.5 16,0.5 16,2.11 z"); } - arrow_path->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-arrows")).c_str()); - arrow_path->setAttribute("id", Glib::ustring(mode).append("_path").c_str()); + Glib::ustring classarrowpath = itemid; + classarrowpath += " "; + classarrowpath += lpobjid; + classarrowpath += " measure-arrows"; + arrow_path->setAttribute("class", classarrowpath.c_str()); + Glib::ustring arrowpath = mode + Glib::ustring("_path"); + arrow_path->setAttribute("id", arrowpath.c_str()); arrow_path->setAttribute("style", style.c_str()); arrow->addChild(arrow_path, NULL); Inkscape::GC::release(arrow_path); @@ -216,72 +234,48 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *rtext = NULL; double doc_w = document->getRoot()->width.value; - Geom::Scale scale = document->getDocumentScale(); - SPNamedView *nv = sp_document_namedview(document, NULL); - Glib::ustring display_unit = nv->display_units->abbr; - if (display_unit.empty()) { - display_unit = "px"; - } - //only check constrain viewbox on X - doc_scale = Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units ); - if( doc_scale > 0 ) { - doc_scale= 1.0/doc_scale; - } else { - doc_scale = 1.0; - } - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); + + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); + Glib::ustring id = Glib::ustring("text-on-"); + id += Glib::ustring::format(counter); + id += "-"; + id += lpobjid; SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; - if ((elemref = document->getObjectById(id))) { - if (remove) { - elemref->deleteObject(); - return; - } + elemref = document->getObjectById(id.c_str()); + + if (elemref) { rtext = elemref->getRepr(); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtext->setAttribute("sodipodi:insensitive", "true"); rtext->setAttribute("transform", NULL); } else { - if (remove) { - return; - } rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); - rtext->setAttribute("id", id); - rtext->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-labels")).c_str()); + rtext->setAttribute("id", id.c_str()); + Glib::ustring classlabel = itemid; + classlabel += " "; + classlabel += lpobjid; + classlabel += " measure-labels"; + rtext->setAttribute("class", classlabel.c_str()); rtext->setAttribute("sodipodi:insensitive", "true"); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtspan = xml_doc->createElement("svg:tspan"); rtspan->setAttribute("sodipodi:role", "line"); } - gchar * transform; - Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); - angle = std::fmod(angle, 2*M_PI); - if (angle < 0) angle += 2*M_PI; - if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); - if (angle < 0) angle += 2*M_PI; - } - affine *= Geom::Rotate(angle); - affine *= Geom::Translate(pos); - if (rotate_anotation) { - transform = sp_svg_transform_write(affine); - } else { - transform = NULL; - } - rtext->setAttribute("transform", transform); - g_free(transform); SPCSSAttr *css = sp_repr_css_attr_new(); Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); - fontlister->fill_css(css, Glib::ustring(fontbutton.param_getSVGValue())); + gchar * fontbutton_str = fontbutton.param_getSVGValue(); + fontlister->fill_css(css, Glib::ustring(fontbutton_str)); + g_free(fontbutton_str); std::stringstream font_size; - font_size.imbue(std::locale::classic()); + setlocale (LC_NUMERIC, "C"); font_size << fontsize << "pt"; - + setlocale (LC_NUMERIC, locale_base); gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); sp_repr_css_set_property (css, "fill",c); Inkscape::SVGOStringStream os; @@ -291,10 +285,14 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng rtspan = rtext->firstChild(); } sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); + if (remove) { + sp_repr_css_set_property (css, "display","hidden"); + } + sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); Glib::ustring css_str; sp_repr_css_write_string(css,css_str); rtext->setAttribute("style", css_str.c_str()); - rtspan->setAttribute("style", NULL); + rtspan->setAttribute("style", css_str.c_str()); rtspan->setAttribute("transform", NULL); sp_repr_css_attr_unref (css); if (!elemref) { @@ -302,7 +300,6 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::GC::release(rtspan); } length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation()); - char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); if (local_locale) { setlocale (LC_NUMERIC, ""); } else { @@ -310,9 +307,10 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng } gchar length_str[64]; g_snprintf(length_str, 64, "%.*f", (int)precision, length); - setlocale (LC_NUMERIC, oldlocale); - g_free (oldlocale); - Glib::ustring label_value(format.param_getSVGValue()); + setlocale (LC_NUMERIC, locale_base); + gchar * format_str = format.param_getSVGValue(); + Glib::ustring label_value(format_str); + g_free(format_str); size_t s = label_value.find(Glib::ustring("{measure}"),0); if(s < label_value.length()) { label_value.replace(s,s+9,length_str); @@ -341,26 +339,53 @@ LPEMeasureSegments::createTextLabel(Geom::Point pos, size_t counter, double leng Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - elemref->deleteObject(); - copy->setAttribute("id", id); + sp_object_ref(elemref, 0 ); + elemref->deleteObject(true); + sp_object_unref(elemref); + copy->setAttribute("id", id.c_str()); elemref = elemref_copy; } - items.push_back(id); + SP_ITEM(elemref)->updateRepr(); Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX); if (bounds) { anotation_width = bounds->width() * 1.15; + rtspan->setAttribute("style", NULL); } + gchar * transform; + if (rotate_anotation) { + Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); + angle = std::fmod(angle, 2*M_PI); + if (angle < 0) angle += 2*M_PI; + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { + angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); + if (angle < 0) angle += 2*M_PI; + } + affine *= Geom::Rotate(angle); + affine *= Geom::Translate(pos); + transform = sp_svg_transform_write(affine); + } else { + transform = NULL; + } + rtext->setAttribute("transform", transform); + g_free(transform); } void -LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows) +LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; } + Glib::ustring lpobjid = this->lpeobj->getId(); + Glib::ustring itemid = sp_lpe_item->getId(); + Glib::ustring id = name; + id += Glib::ustring::format(counter); + id += "-"; + id += lpobjid; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); - SPObject *elemref = NULL; + SPObject *elemref = document->getObjectById(id.c_str()); Inkscape::XML::Node *line = NULL; if (!main) { Geom::Ray ray(start, end); @@ -369,25 +394,13 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i end = end + Point::polar(angle, helpline_overlap ); } Geom::PathVector line_pathv; - + + double k = (Geom::distance(start,end)/2.0) - (anotation_width/10.0) - (anotation_width/2.0); if (main && std::abs(text_top_bottom) < fontsize/1.5 && - hide_back) + hide_back && + k > 0) { - double k = 0; - if (flip_side) { - k = (Geom::distance(start,end)/2.0) + arrow_gap - (anotation_width/2.0); - } else { - k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0); - } - if (Geom::distance(start,end) < anotation_width){ - if ((elemref = document->getObjectById(id))) { - if (remove) { - elemref->deleteObject(); - } - return; - } - } //k = std::max(k , arrow_gap -1); Geom::Ray ray(end, start); Geom::Coord angle = ray.angle(); @@ -403,11 +416,7 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i line_path.appendNew(end); line_pathv.push_back(line_path); } - if ((elemref = document->getObjectById(id))) { - if (remove) { - elemref->deleteObject(); - return; - } + if (elemref) { line = elemref->getRepr(); gchar * line_str = sp_svg_write_path( line_pathv ); @@ -415,46 +424,59 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i line->setAttribute("transform", NULL); g_free(line_str); } else { - if (remove) { - return; - } line = xml_doc->createElement("svg:path"); - line->setAttribute("id", id); + line->setAttribute("id", id.c_str()); if (main) { - line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-DIM-lines measure-lines")).c_str()); + Glib::ustring classlinedim = itemid; + classlinedim += " "; + classlinedim += lpobjid; + classlinedim += " measure-DIM-lines measure-lines"; + line->setAttribute("class", classlinedim.c_str()); } else { - line->setAttribute("class", (Glib::ustring(sp_lpe_item->getId()) + Glib::ustring(" ") + Glib::ustring(this->lpeobj->getId()) + Glib::ustring(" measure-helper-lines measure-lines")).c_str()); + Glib::ustring classlinehelper = itemid; + classlinehelper += " "; + classlinehelper += lpobjid; + classlinehelper += " measure-helper-lines measure-lines"; + line->setAttribute("class", classlinehelper.c_str()); } gchar * line_str = sp_svg_write_path( line_pathv ); line->setAttribute("d" , line_str); g_free(line_str); } + line->setAttribute("sodipodi:insensitive", "true"); line_pathv.clear(); Glib::ustring style; + if (remove) { + style ="display:none;"; + } if (main) { line->setAttribute("inkscape:label", "dinline"); if (arrows_outside) { - style = style + Glib::ustring("marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"); + style += "marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"; } else { - style = style + Glib::ustring("marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"); + style += "marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"; } } else { line->setAttribute("inkscape:label", "dinhelpline"); } std::stringstream stroke_w; - stroke_w.imbue(std::locale::classic()); + setlocale (LC_NUMERIC, "C"); + double stroke_width = Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); stroke_w << stroke_width; - style = style + Glib::ustring("stroke-width:" + stroke_w.str()); + setlocale (LC_NUMERIC, locale_base); + style += "stroke-width:"; + style += stroke_w.str(); gchar c[32]; - unsigned const rgb24 = coloropacity.get_value() >> 8; sprintf(c, "#%06x", rgb24); - style = style + Glib::ustring(";stroke:") + Glib::ustring(c); + style += ";stroke:"; + style += Glib::ustring(c); Inkscape::SVGOStringStream os; os << SP_RGBA32_A_F(coloropacity.get_value()); - style = style + Glib::ustring(";stroke-opacity:") + Glib::ustring(os.str()); + style += ";stroke-opacity:"; + style += os.str(); SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_attr_add_from_string(css, style.c_str()); Glib::ustring css_str; @@ -468,10 +490,11 @@ LPEMeasureSegments::createLine(Geom::Point start,Geom::Point end, const char * i Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); SPObject * elemref_copy = sp_lpe_item->parent->appendChildRepr(copy); Inkscape::GC::release(copy); - elemref->deleteObject(); - copy->setAttribute("id", id); + sp_object_ref(elemref, 0 ); + elemref->deleteObject(true); + sp_object_unref(elemref); + copy->setAttribute("id", id.c_str()); } - items.push_back(id); } void @@ -534,7 +557,9 @@ LPEMeasureSegments::doOnApply(SPLPEItem const* lpeitem) bool LPEMeasureSegments::hasMeassure (size_t i) { - std::string listsegments(std::string(blacklist.param_getSVGValue()) + std::string(",")); + gchar * blacklist_str = blacklist.param_getSVGValue(); + std::string listsegments(std::string(blacklist_str) + std::string(",")); + g_free(blacklist_str); listsegments.erase(std::remove(listsegments.begin(), listsegments.end(), ' '), listsegments.end()); size_t s = listsegments.find(std::to_string(i) + std::string(","),0); if(s < listsegments.length()) { @@ -571,7 +596,6 @@ void LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) { SPLPEItem * splpeitem = const_cast(lpeitem); - SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; @@ -584,16 +608,38 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) SPShape *shape = dynamic_cast(splpeitem); if (shape) { - SPCurve * c = NULL; - - SPPath *path = dynamic_cast(shape); - if (path) { - c = path->get_original_curve(); + //only check constrain viewbox on X + Geom::Scale scaledoc = document->getDocumentScale(); + SPNamedView *nv = sp_document_namedview(document, NULL); + display_unit = nv->display_units->abbr; + if (display_unit.empty()) { + display_unit = "px"; + } + doc_scale = Inkscape::Util::Quantity::convert( scaledoc[Geom::X], "px", display_unit.c_str() ); + if( doc_scale > 0 ) { + doc_scale= 1.0/doc_scale; } else { - c = shape->getCurve(); + doc_scale = 1.0; + } + unsigned const color = coloropacity.get_value() >> 8; + bool colorchanged = false; + if (color != rgb24) { + colorchanged = true; } - Geom::Point start_stored; - Geom::Point end_stored; + rgb24 = color; + SPCurve * c = NULL; + gchar * fontbutton_str = fontbutton.param_getSVGValue(); + Glib::ustring fontdesc_ustring = Glib::ustring(fontbutton_str); + Pango::FontDescription fontdesc(fontdesc_ustring); + fontsize = fontdesc.get_size()/(double)Pango::SCALE; + fontsize *= document->getRoot()->c2p.inverse().expansionX(); + g_free(fontbutton_str); + fontsize *= document->getRoot()->c2p.inverse().expansionX(); + c = shape->getCurve(); + Geom::Point prev_stored = Geom::Point(0,0); + Geom::Point start_stored = Geom::Point(0,0); + Geom::Point end_stored = Geom::Point(0,0); + Geom::Point next_stored = Geom::Point(0,0); Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem->parent), SP_OBJECT(document->getRoot())); Geom::PathVector pathvector = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); c->unref(); @@ -605,55 +651,137 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { pathvector *= writed_transform; } - if ((Glib::ustring(format.param_getSVGValue()).empty())) { + gchar * format_str = format.param_getSVGValue(); + if (Glib::ustring(format_str).empty()) { format.param_setValue(Glib::ustring("{measure}{unit}")); } + g_free(format_str); size_t ncurves = pathvector.curveCount(); items.clear(); double start_angle_cross = 0; double end_angle_cross = 0; - size_t counter = -1; + gint counter = -1; + Glib::ustring lpobjid = this->lpeobj->getId(); + bool previous_fix_overlaps = true; for (size_t i = 0; i < pathvector.size(); i++) { for (size_t j = 0; j < pathvector[i].size(); j++) { counter++; - if(hasMeassure(counter + 1)) { - Geom::Point prev = Geom::Point(0,0); - if (j == 0 && pathvector[i].closed()) { - prev = pathvector.pointAt(pathvector[i].size() - 1); - } else if (j != 0) { - prev = pathvector[i].pointAt(j - 1); + gint fix_overlaps_degree = fix_overlaps; + Geom::Point prev = Geom::Point(0,0); + if (j == 0 && pathvector[i].closed()) { + prev = pathvector.pointAt(pathvector[i].size() - 1); + } else if (j != 0) { + prev = pathvector[i].pointAt(j - 1); + } + Geom::Point start = pathvector[i].pointAt(j); + Geom::Point end = pathvector[i].pointAt(j + 1); + Geom::Point next = Geom::Point(0,0); + if(pathvector[i].closed() && pathvector[i].size() == j+1){ + end = pathvector[i].pointAt(0); + next = pathvector[i].pointAt(1); + } else if (pathvector[i].size() > j + 1) { + next = pathvector[i].pointAt(j+2); + } + if(hasMeassure(counter) && !Geom::are_near(start, end)) { + Glib::ustring idprev = Glib::ustring("infoline-on-start-"); + idprev += Glib::ustring::format(counter-1); + idprev += "-"; + idprev += lpobjid; + SPObject *elemref = NULL; + if (elemref = document->getObjectById(idprev.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* prevcurve = path->getCurve(); + if (prevcurve) { + prev_stored = *prevcurve->first_point(); + } + prevcurve->unref(); + } } - Geom::Point start = pathvector[i].pointAt(j); - Geom::Point end = pathvector[i].pointAt(j + 1); - Geom::Point next = Geom::Point(0,0); - if(pathvector[i].closed() && pathvector[i].size() == j+1){ - end = pathvector[i].pointAt(0); - next = pathvector[i].pointAt(1); - } else if (pathvector[i].size() > j + 1) { - next = pathvector[i].pointAt(j+2); + Glib::ustring idstart = Glib::ustring("infoline-on-start-"); + idstart += Glib::ustring::format(counter); + idstart += "-"; + idstart += lpobjid; + elemref = NULL; + if (elemref = document->getObjectById(idstart.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* startcurve = path->getCurve(); + if (startcurve) { + start_stored = *startcurve->first_point(); + } + startcurve->unref(); + } } - const char * idstart = Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(idstart))) { - start_stored = *SP_PATH(elemref)->get_curve()->first_point(); + Glib::ustring idend = Glib::ustring("infoline-on-end-"); + idend += Glib::ustring::format(counter); + idend += "-"; + idend += lpobjid; + elemref = NULL; + if (elemref = document->getObjectById(idend.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* endcurve = path->getCurve(); + if (endcurve) { + end_stored = *endcurve->first_point(); + } + endcurve->unref(); + } } - const char * idend = Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str(); + Glib::ustring idnext = Glib::ustring("infoline-on-start-"); + idnext += Glib::ustring::format(counter+1); + idnext += "-"; + idnext += lpobjid; elemref = NULL; - if ((elemref = document->getObjectById(idend))) { - end_stored = *SP_PATH(elemref)->get_curve()->first_point(); + if (elemref = document->getObjectById(idnext.c_str())) { + SPPath* path = dynamic_cast(elemref); + if (path) { + SPCurve* nextcurve = path->getCurve(); + if (nextcurve) { + next_stored = *nextcurve->first_point(); + } + nextcurve->unref(); + } } - if (Geom::are_near(start, start_stored, 0.01) && - Geom::are_near(end, end_stored, 0.01)) + Glib::ustring infoline_on_start = "infoline-on-start-"; + infoline_on_start += Glib::ustring::format(counter); + infoline_on_start += "-"; + infoline_on_start += lpobjid; + items.push_back(infoline_on_start); + Glib::ustring infoline_on_end = "infoline-on-end-"; + infoline_on_end += Glib::ustring::format(counter); + infoline_on_end += "-"; + infoline_on_end += lpobjid; + items.push_back(infoline_on_end); + Glib::ustring infoline = "infoline-"; + infoline += Glib::ustring::format(counter); + infoline += "-"; + infoline += lpobjid; + items.push_back(infoline); + Glib::ustring texton = "text-on-"; + texton += Glib::ustring::format(counter); + texton += "-"; + texton += lpobjid; + items.push_back(texton); + if (arrows_outside) { + items.push_back(Glib::ustring("ArrowDINout-start")); + items.push_back(Glib::ustring("ArrowDINout-end")); + } else { + items.push_back(Glib::ustring("ArrowDIN-start")); + items.push_back(Glib::ustring("ArrowDIN-end")); + } + if ((Geom::are_near(prev, prev_stored, 0.01) && Geom::are_near(next, next_stored, 0.01) || + fix_overlaps_degree == 180) && + Geom::are_near(start, start_stored, 0.01) && + Geom::are_near(end, end_stored, 0.01) && + !this->upd_params && + !colorchanged) { continue; } Geom::Point hstart = start; Geom::Point hend = end; bool remove = false; - if (Geom::are_near(hstart, hend)) { - remove = true; - } - if (orientation == OM_VERTICAL) { Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]); if (flip_side) { @@ -682,16 +810,23 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) if (Geom::are_near(hstart[Geom::X], hend[Geom::X])) { remove = true; } - } else if (fix_overlaps != 180) { - start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps); + } else if (fix_overlaps_degree != 180) { + start_angle_cross = getAngle( start, prev, end, flip_side, fix_overlaps_degree); if (prev == Geom::Point(0,0)) { start_angle_cross = 0; } - end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps); + end_angle_cross = getAngle(end, start, next, flip_side, fix_overlaps_degree); if (next == Geom::Point(0,0)) { end_angle_cross = 0; } } + if (remove) { + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); + continue; + } Geom::Ray ray(hstart,hend); Geom::Coord angle = ray.angle(); if (flip_side) { @@ -708,36 +843,42 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) start_angle_cross *= -1; //turn *= -1; } - if (fix_overlaps != 180 && start_angle_cross != 0) { - double position_turned = position / sin(start_angle_cross/2.0); - hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned); + double position_turned_start = position / sin(start_angle_cross/2.0); + double length = Geom::distance(start,end); + if (fix_overlaps_degree != 180 && + start_angle_cross != 0 && + position_turned_start < length && + previous_fix_overlaps) + { + hstart = hstart - Point::polar(angle_cross - (start_angle_cross/2.0) - turn, position_turned_start); } else { hstart = hstart - Point::polar(angle_cross, position); } - createLine(start, hstart, g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); - - if (fix_overlaps != 180 && end_angle_cross != 0) { - double position_turned = position / sin(end_angle_cross/2.0); - hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned); + createLine(start, hstart, Glib::ustring("infoline-on-start-"), counter, false, false); + double position_turned_end = position / sin(end_angle_cross/2.0); + double endlength = Geom::distance(end,next); + if (fix_overlaps_degree != 180 && + end_angle_cross != 0 && + position_turned_end < length && + position_turned_end < endlength) + { + hend = hend - Point::polar(angle_cross + (end_angle_cross/2.0) + turn, position_turned_end); + previous_fix_overlaps = true; } else { hend = hend - Point::polar(angle_cross, position); + previous_fix_overlaps = false; } - double length = Geom::distance(hstart,hend) * scale; + length = Geom::distance(start,end) * scale; Geom::Point pos = Geom::middle_point(hstart,hend); if (arrows_outside) { - createArrowMarker("ArrowDINout-start"); - createArrowMarker("ArrowDINout-end"); + createArrowMarker(Glib::ustring("ArrowDINout-start")); + createArrowMarker(Glib::ustring("ArrowDINout-end")); } else { - createArrowMarker("ArrowDIN-start"); - createArrowMarker("ArrowDIN-end"); + createArrowMarker(Glib::ustring("ArrowDIN-start")); + createArrowMarker(Glib::ustring("ArrowDIN-end")); } - //We get the font size to offset the text to the middle - Pango::FontDescription fontdesc(Glib::ustring(fontbutton.param_getSVGValue())); - fontsize = fontdesc.get_size()/(double)Pango::SCALE; - fontsize *= document->getRoot()->c2p.inverse().expansionX(); - if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); + pos = pos - Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } else { pos = pos + Point::polar(angle_cross, text_top_bottom + (fontsize/2.5)); } @@ -753,55 +894,42 @@ LPEMeasureSegments::doBeforeEffect (SPLPEItem const* lpeitem) } else { createTextLabel(pos, counter, length, angle, remove, true); } - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); arrow_gap = 8 * Inkscape::Util::Quantity::convert(line_width / doc_scale, "mm", display_unit.c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); - char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); setlocale (LC_NUMERIC, "C"); double width_line = atof(sp_repr_css_property(css,"stroke-width","-1")); - setlocale (LC_NUMERIC, oldlocale); - g_free (oldlocale); + setlocale (LC_NUMERIC, locale_base); if (width_line > -0.0001) { arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str()); } if(flip_side) { arrow_gap *= -1; } - createLine(end, hend, g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), false, remove); + createLine(end, hend, Glib::ustring("infoline-on-end-"), counter, false, false); if (!arrows_outside) { hstart = hstart + Point::polar(angle, arrow_gap); hend = hend - Point::polar(angle, arrow_gap ); } - if ((anotation_width/2) < Geom::distance(hstart,hend)/2.0) { - createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, remove, true); + if ((anotation_width/2.0) + arrow_gap < Geom::distance(hstart,hend)/2.0) { + createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, false, true); } else { - createLine(hstart, hend, g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); + createLine(hstart, hend, Glib::ustring("infoline-"), counter, true, true, true); } } else { - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); - createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { - elemref->deleteObject(); - } + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); } } } - for (size_t k = ncurves; k <= previous_size; k++) { - const char * downline = g_strdup(Glib::ustring("downline-").append(Glib::ustring::format(counter) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); - createLine(Geom::Point(),Geom::Point(), downline, true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-start-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - createLine(Geom::Point(), Geom::Point(), g_strdup(Glib::ustring("infoline-on-end-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()), true, true, true); - const char * id = g_strdup(Glib::ustring("text-on-").append(Glib::ustring::format(k) + Glib::ustring("-")).append(this->getRepr()->attribute("id")).c_str()); - SPObject *elemref = NULL; - if ((elemref = document->getObjectById(id))) { - elemref->deleteObject(); + if (previous_size) { + for (size_t counter = ncurves; counter < previous_size; counter++) { + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-start-"), counter, true, true, true); + createLine(Geom::Point(), Geom::Point(), Glib::ustring("infoline-on-end-"), counter, true, true, true); + createTextLabel(Geom::Point(), counter, 0, 0, true, true); } } previous_size = ncurves; @@ -837,12 +965,6 @@ LPEMeasureSegments::transform_multiply(Geom::Affine const& postmul, bool set) } } -Geom::PathVector -LPEMeasureSegments::doEffect_path(Geom::PathVector const &path_in) -{ - return path_in; -} - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-measure-segments.h b/src/live_effects/lpe-measure-segments.h index 903a5cbd27..1b6a5a81d7 100644 --- a/src/live_effects/lpe-measure-segments.h +++ b/src/live_effects/lpe-measure-segments.h @@ -11,19 +11,16 @@ */ #include "live_effects/effect.h" -#include "ui/dialog/styledialog.h" - +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/colorpicker.h" #include "live_effects/parameter/enum.h" #include "live_effects/parameter/fontbutton.h" +#include "live_effects/parameter/message.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/unit.h" -#include "live_effects/parameter/bool.h" -#include "live_effects/parameter/colorpicker.h" -#include "live_effects/parameter/message.h" -#include -#include <2geom/angle.h> -#include <2geom/ray.h> -#include <2geom/point.h> + namespace Inkscape { namespace LivePathEffect { @@ -39,16 +36,15 @@ class LPEMeasureSegments : public Effect { public: LPEMeasureSegments(LivePathEffectObject *lpeobject); virtual ~LPEMeasureSegments(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void doOnApply(SPLPEItem const* lpeitem); - virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); - virtual void doEffect (SPCurve * curve){}; //stop the chain + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* /*lpeitem*/); + virtual void doEffect(SPCurve * curve){}; //stop the chain virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); virtual void transform_multiply(Geom::Affine const& postmul, bool set); - virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); - void createLine(Geom::Point start,Geom::Point end, const char * id, bool main, bool remove, bool arrows = false); + void createLine(Geom::Point start,Geom::Point end, Glib::ustring name, size_t counter, bool main, bool remove, bool arrows = false); void createTextLabel(Geom::Point pos, size_t counter, double length, Geom::Coord angle, bool remove, bool valid); - void createArrowMarker(const char * mode); + void createArrowMarker(Glib::ustring mode); bool hasMeassure (size_t i); private: UnitParam unit; @@ -78,7 +74,9 @@ private: double fontsize; double anotation_width; double previous_size; + unsigned rgb24; double arrow_gap; + gchar const* locale_base; Geom::Affine star_ellipse_fix; LPEMeasureSegments(const LPEMeasureSegments &); LPEMeasureSegments &operator=(const LPEMeasureSegments &); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 926977a07b..1e62a98d51 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -15,8 +15,6 @@ */ #include -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" #include "live_effects/lpe-mirror_symmetry.h" #include "display/curve.h" #include "svg/path-string.h" @@ -41,7 +39,7 @@ namespace Inkscape { namespace LivePathEffect { -static const Util::EnumData ModeTypeData[MT_END] = { +static const Util::EnumData ModeTypeData[] = { { MT_V, N_("Vertical Page Center"), "vertical" }, { MT_H, N_("Horizontal Page Center"), "horizontal" }, { MT_FREE, N_("Free from reflection line"), "free" }, @@ -51,6 +49,7 @@ static const Util::EnumData ModeTypeData[MT_END] = { static const Util::EnumDataConverter MTConverter(ModeTypeData, MT_END); + LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), @@ -61,8 +60,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), - id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) { show_orig_path = true; registerParameter(&mode); @@ -74,15 +72,13 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter(&start_point); registerParameter(&end_point); registerParameter(¢er_point); - registerParameter(&id_origin); - id_origin.param_hide_canvas_text(); split_gap.param_set_range(-999999.0, 999999.0); split_gap.param_set_increments(0.1, 0.1); split_gap.param_set_digits(5); apply_to_clippath_and_mask = true; previous_center = Geom::Point(0,0); - id_origin.param_widget_is_visible(false); center_point.param_widget_is_visible(false); + reset = false; } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -97,30 +93,71 @@ LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) if (!document) { return; } + container = dynamic_cast(sp_lpe_item->parent); + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = document->getReprRoot(); + if (root_origin != root) { + return; + } + if (split_items && !discard_orig_path) { - container = dynamic_cast(sp_lpe_item->parent); - Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); - Inkscape::XML::Node *root_origin = document->getReprRoot(); - if (root_origin != root) { - return; - } Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); m = m * sp_lpe_item->transform; - toMirror(m); + toMirror(m, reset); + reset = false; } else { processObjects(LPE_ERASE); items.clear(); } } +Gtk::Widget * +LPEMirrorSymmetry::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles")))); + reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEMirrorSymmetry::resetStyles)); + reset_button->set_size_request(110,20); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } + return dynamic_cast(vbox); +} + void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - using namespace Geom; - original_bbox(lpeitem); - //center_point->param_set_liveupdate(false); + original_bbox(lpeitem, false, true); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); if (mode == MT_Y) { @@ -140,7 +177,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } if ( mode == MT_X || mode == MT_Y ) { if (!are_near(previous_center, (Geom::Point)center_point, 0.01)) { - center_point.param_setValue(Geom::middle_point(point_a, point_b), true); + center_point.param_setValue(Geom::middle_point(point_a, point_b)); end_point.param_setValue(point_b); start_point.param_setValue(point_a); } else { @@ -163,10 +200,12 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } else if ( mode == MT_FREE) { if (are_near(previous_center, (Geom::Point)center_point, 0.01)) { center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point)); + } else { Geom::Point trans = center_point - Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point); start_point.param_setValue(start_point * trans); end_point.param_setValue(end_point * trans); + } } else if ( mode == MT_V){ SPDocument * document = SP_ACTIVE_DOCUMENT; @@ -193,7 +232,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } void -LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool live, bool root) +LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { @@ -206,108 +245,99 @@ LPEMirrorSymmetry::cloneD(SPObject *orig, SPObject *dest, bool live, bool root) for (std::vector::iterator obj_it = childs.begin(); obj_it != childs.end(); ++obj_it) { SPObject *dest_child = dest->nthChild(index); - cloneD(*obj_it, dest_child, live, false); + cloneD(*obj_it, dest_child, reset); index++; } + return; } SPShape * shape = SP_SHAPE(orig); SPPath * path = SP_PATH(dest); - if (shape && !path) { - Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); - dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); - path = SP_PATH(dest); - } if (path && shape) { - if ( live) { - SPCurve *c = NULL; - if (root) { - c = new SPCurve(); - c->set_pathvector(pathvector_after_effect); - } else { - c = shape->getCurve(); - } - if (c) { - path->setCurve(c, TRUE); - c->unref(); - } else { - dest->getRepr()->setAttribute("d", NULL); - } + SPCurve *c = shape->getCurve(); + if (c) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + dest->getRepr()->setAttribute("d", str); + g_free(str); + c->unref(); } else { - dest->getRepr()->setAttribute("d", orig->getRepr()->attribute("d")); + dest->getRepr()->setAttribute("d", NULL); + } + if (reset) { + dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); + } + } +} + +Inkscape::XML::Node * +LPEMirrorSymmetry::createPathBase(SPObject *elemref) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return NULL; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Node *prev = elemref->getRepr(); + SPGroup *group = dynamic_cast(elemref); + if (group) { + Inkscape::XML::Node *container = xml_doc->createElement("svg:g"); + container->setAttribute("transform", prev->attribute("transform")); + std::vector const item_list = sp_item_group_item_list(group); + Inkscape::XML::Node *previous = NULL; + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPObject *sub_item = *iter; + Inkscape::XML::Node *resultnode = createPathBase(sub_item); + container->addChild(resultnode, previous); + previous = resultnode; } + return container; } + Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); + resultnode->setAttribute("transform", prev->attribute("transform")); + return resultnode; } void -LPEMirrorSymmetry::toMirror(Geom::Affine transform) +LPEMirrorSymmetry::toMirror(Geom::Affine transform, bool reset) { SPDocument * document = SP_ACTIVE_DOCUMENT; - if (document) { - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * id_origin_char = id_origin.param_getSVGValue(); - const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); - items.clear(); - items.push_back(elemref_id); - SPObject *elemref= NULL; - Inkscape::XML::Node *phantom = NULL; - if ((elemref = document->getObjectById(elemref_id))) { - phantom = elemref->getRepr(); - } else { - phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); - std::vector attrs; - attrs.push_back("inkscape:path-effect"); - attrs.push_back("inkscape:original-d"); - attrs.push_back("sodipodi:type"); - attrs.push_back("sodipodi:rx"); - attrs.push_back("sodipodi:ry"); - attrs.push_back("sodipodi:cx"); - attrs.push_back("sodipodi:cy"); - attrs.push_back("sodipodi:end"); - attrs.push_back("sodipodi:start"); - attrs.push_back("inkscape:flatsided"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:rounded"); - attrs.push_back("sodipodi:arg1"); - attrs.push_back("sodipodi:arg2"); - attrs.push_back("sodipodi:r1"); - attrs.push_back("sodipodi:r2"); - attrs.push_back("sodipodi:sides"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("sodipodi:argument"); - attrs.push_back("sodipodi:expansion"); - attrs.push_back("sodipodi:radius"); - attrs.push_back("sodipodi:revolution"); - attrs.push_back("sodipodi:t0"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("inkscape:randomized"); - attrs.push_back("x"); - attrs.push_back("y"); - attrs.push_back("rx"); - attrs.push_back("ry"); - attrs.push_back("width"); - attrs.push_back("height"); - for(const char * attr : attrs) { - phantom->setAttribute(attr, NULL); - } - } - phantom->setAttribute("id", elemref_id); - if (!elemref) { - elemref = container->appendChildRepr(phantom); - Inkscape::GC::release(phantom); - } - cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); - gchar *str = sp_svg_transform_write(transform); - elemref->getRepr()->setAttribute("transform" , str); - g_free(str); - if (elemref->parent != container) { - Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); - copy->setAttribute("id", elemref_id); - container->appendChildRepr(copy); - Inkscape::GC::release(copy); - elemref->deleteObject(); - } + if (!document) { + return; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Glib::ustring elemref_id = Glib::ustring("mirror-"); + elemref_id += this->lpeobj->getId(); + items.clear(); + items.push_back(elemref_id); + SPObject *elemref = NULL; + Inkscape::XML::Node *phantom = NULL; + if (elemref = document->getObjectById(elemref_id.c_str())) { + phantom = elemref->getRepr(); + } else { + phantom = createPathBase(sp_lpe_item); + phantom->setAttribute("id", elemref_id.c_str()); + reset = true; + } + if (!elemref) { + elemref = container->appendChildRepr(phantom); + Inkscape::GC::release(phantom); } + cloneD(SP_OBJECT(sp_lpe_item), elemref, reset); + gchar *str = sp_svg_transform_write(transform); + elemref->getRepr()->setAttribute("transform" , str); + g_free(str); + if (elemref->parent != container) { + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); + copy->setAttribute("id", elemref_id); + container->appendChildRepr(copy); + Inkscape::GC::release(copy); + elemref->deleteObject(); + } +} + + +void +LPEMirrorSymmetry::resetStyles(){ + reset = true; + doAfterEffect(sp_lpe_item); } //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication @@ -345,7 +375,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Point point_a(boundingbox_X.max(), boundingbox_Y.min()); Point point_b(boundingbox_X.max(), boundingbox_Y.max()); @@ -357,10 +387,6 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) center_point.param_setValue(point_c); previous_center = center_point; SPLPEItem * splpeitem = const_cast(lpeitem); - if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet - id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); - id_origin.write_to_SVG(); - } } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index e98c83f2b8..d2d04c2059 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -17,6 +17,8 @@ */ #include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/text.h" #include "live_effects/parameter/point.h" @@ -46,9 +48,11 @@ public: virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); - void toMirror(Geom::Affine transform); - // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); - void cloneD(SPObject *orig, SPObject *dest, bool live, bool root); + virtual Gtk::Widget * newWidget(); + void toMirror(Geom::Affine transform, bool reset); + void cloneD(SPObject *orig, SPObject *dest, bool reset); + Inkscape::XML::Node * createPathBase(SPObject *elemref); + void resetStyles(); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); @@ -63,9 +67,9 @@ private: PointParam start_point; PointParam end_point; PointParam center_point; - TextParam id_origin; Geom::Point previous_center; SPObject * container; + bool reset; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); }; diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 6e6f35f7dd..115c777d0c 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -316,7 +316,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Poin Geom::Point const s = snap_knot_position(p, state); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); + SPCurve *curve_before = sp_shape->getCurveForEdit(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); @@ -349,7 +349,7 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const LPEPatternAlongPath *lpe = dynamic_cast (_effect); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { - SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); + SPCurve *curve_before = sp_shape->getCurveForEdit(); if (curve_before) { Geom::Path const *path_in = curve_before->first_path(); Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index 2819094e7d..afaa6b9ca5 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -113,7 +113,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) { /* make the path a straight line */ /** - SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? + SPCurve* curve = sp_path_getCurveForEdit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? Geom::Point A(curve->first_point()); Geom::Point B(curve->last_point()); @@ -121,7 +121,7 @@ LPEPerpBisector::doOnApply (SPLPEItem const*/*lpeitem*/) SPCurve *c = new SPCurve(); c->moveto(A); c->lineto(B); - // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work? + // TODO: Why doesn't sp_path_set_curve_before_LPE(SP_PATH(lpeitem), c, TRUE, true) work? SP_PATH(lpeitem)->original_curve = c->ref(); c->unref(); **/ diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 3cff83fedc..e95cdfd4bb 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -414,6 +414,9 @@ LPEPerspectiveEnvelope::newWidget() reset_button->set_size_request(140,30); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*reset_button, false, false,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -462,7 +465,7 @@ LPEPerspectiveEnvelope::horizontal(PointParam ¶m_one, PointParam ¶m_two, void LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Geom::Line vert(Geom::Point(boundingbox_X.middle(),boundingbox_Y.max()), Geom::Point(boundingbox_X.middle(), boundingbox_Y.min())); Geom::Line horiz(Geom::Point(boundingbox_X.min(),boundingbox_Y.middle()), Geom::Point(boundingbox_X.max(), boundingbox_Y.middle())); if(vertical_mirror) { @@ -503,7 +506,7 @@ void LPEPerspectiveEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); setDefaults(); resetGrid(); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 3484d00a58..deed40bde7 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -255,6 +255,9 @@ LPEPerspectivePath::newWidget() Gtk::Widget* apply3DWidget = dynamic_cast(apply3D); apply3DWidget->set_tooltip_text("Refresh perspective"); vbox->pack_start(*apply3DWidget, true, true,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 2e90abfeb5..60237b54ef 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -44,11 +44,12 @@ LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ SPObject * clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); + gchar * uri_str = uri.param_getSVGValue(); if(hide_clip && clip_path) { SP_ITEM(sp_lpe_item)->clip_ref->detach(); - } else if (!hide_clip && !clip_path && uri.param_getSVGValue()) { + } else if (!hide_clip && !clip_path && uri_str) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -62,9 +63,10 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ if(!bbox) { return; } - if (uri.param_getSVGValue()) { + uri_str = uri.param_getSVGValue(); + if (uri_str) { try { - SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->clip_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->clip_ref->detach(); @@ -72,6 +74,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ } else { SP_ITEM(sp_lpe_item)->clip_ref->detach(); } + g_free(uri_str); Geom::Rect bboxrect = (*bbox); bboxrect.expandBy(1); Geom::Point topleft = bboxrect.corner(0); @@ -125,7 +128,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Geom::PathVector c_pv = c->get_pathvector(); c_pv *= affine; c->set_pathvector(c_pv); - SP_SHAPE(clip_to_path)->setCurve(c, TRUE); + SP_SHAPE(clip_to_path)->setCurve(c); c->unref(); } @@ -144,28 +147,38 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Inkscape::GC::release(clip_path_node); clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); } - if( is_inverse.param_getSVGValue() == (Glib::ustring)"false" && inverse && isVisible()) { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"false") && inverse && isVisible()) { if (clip_to_path) { addInverse(SP_ITEM(clip_to_path)); } else { addInverse(SP_ITEM(clip_data)); } - } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { + } else if(!strcmp(is_inverse_str,"true") && !inverse && isVisible()) { if (clip_to_path) { removeInverse(SP_ITEM(clip_to_path)); } else { removeInverse(SP_ITEM(clip_data)); } - } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ + } else if (inverse && !is_visible && is_inverse_str == (Glib::ustring)"true"){ removeInverse(SP_ITEM(clip_data)); } + g_free(is_inverse_str); } } } +void +LPEPowerClip::doAfterEffect (SPLPEItem const* lpeitem){ + if (!hide_clip && flatten && isVisible()) { + SP_ITEM(sp_lpe_item)->clip_ref->detach(); + } +} + void LPEPowerClip::addInverse (SPItem * clip_data){ - if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"false")) { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -185,9 +198,12 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } c_pv.push_back(clip_box); c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + SP_SHAPE(clip_data)->setCurve(c); c->unref(); - is_inverse.param_setValue((Glib::ustring)"true", true); + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if (strcmp(is_inverse_str, "true") != 0) { + is_inverse.param_setValue((Glib::ustring)"true", true); + } SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -202,11 +218,13 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } } } + g_free(is_inverse_str); } void LPEPowerClip::removeInverse (SPItem * clip_data){ - if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if(!strcmp(is_inverse_str,"true")) { if (SP_IS_GROUP(clip_data)) { std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_data)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { @@ -222,9 +240,12 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ c_pv.pop_back(); } c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); + SP_SHAPE(clip_data)->setCurve(c); c->unref(); - is_inverse.param_setValue((Glib::ustring)"false", true); + gchar * is_inverse_str = is_inverse.param_getSVGValue(); + if (strcmp(is_inverse_str, "false") != 0) { + is_inverse.param_setValue((Glib::ustring)"false", true); + } SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { if (tools_isactive(desktop, TOOLS_NODES)) { @@ -239,6 +260,7 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ } } } + g_free(is_inverse_str); } void @@ -281,6 +303,9 @@ LPEPowerClip::newWidget() topaths_button->set_size_request(220,30); hbox->pack_start(*topaths_button, false, false,2); vbox->pack_start(*hbox, true,true,2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } @@ -290,13 +315,15 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); if(!keep_paths) { if(clip_path) { + gchar * is_inverse_str = is_inverse.param_getSVGValue(); std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { SPObject * clip_data = *iter; - if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + if(!strcmp(is_inverse_str,"true")) { removeInverse(SP_ITEM(clip_data)); } } + g_free(is_inverse_str); } } else { if (flatten && clip_path) { @@ -317,7 +344,6 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ flattenClip(SP_ITEM(clip_data), path_out); } } - SP_ITEM(sp_lpe_item)->clip_ref->detach(); } return path_out; } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 6f99d220f6..240a1809b3 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -23,6 +23,7 @@ public: virtual Gtk::Widget * newWidget(); //virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); + virtual void doAfterEffect (SPLPEItem const* lpeitem); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 947482c24d..202c972594 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -50,13 +50,14 @@ LPEPowerMask::~LPEPowerMask() {} void LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ - //To avoid close of color dialog and better performance on change color + //To avoid close of color dialog and better performance on change color SPObject * mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); + gchar * uri_str = uri.param_getSVGValue(); if(hide_mask && mask) { SP_ITEM(sp_lpe_item)->mask_ref->detach(); - } else if (!hide_mask && !mask && uri.param_getSVGValue()) { + } else if (!hide_mask && !mask && uri_str) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -72,11 +73,13 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ SP_ITEM(sp_lpe_item)->mask_ref->detach(); Geom::OptRect bbox = sp_lpe_item->visualBounds(); if(!bbox) { + g_free(uri_str); return; } - if (uri.param_getSVGValue()) { + uri_str = uri.param_getSVGValue(); + if (uri_str) { try { - SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri.param_getSVGValue())); + SP_ITEM(sp_lpe_item)->mask_ref->attach(Inkscape::URI(uri_str)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); SP_ITEM(sp_lpe_item)->mask_ref->detach(); @@ -99,6 +102,7 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ setMask(); } } + g_free(uri_str); } void diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 6d63ffa81c..1d64e90420 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -170,13 +170,13 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this), sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve"), "sort_points", &wr, this, true), - interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER), + interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM), interpolator_beta(_("Smoothness:"), _("Sets the smoothness for the CubicBezierJohan interpolator; 0 = linear interpolation, 1 = smooth"), "interpolator_beta", &wr, this, 0.2), scale_width(_("Width scale:"), _("Width scale all points"), "scale_width", &wr, this, 1.0), - start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT), - linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_EXTRP_MITER_ARC), + start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_ROUND), miter_limit(_("Miter limit:"), _("Maximum length of the miter (in units of stroke width)"), "miter_limit", &wr, this, 4.), - end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT) + end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ZERO_WIDTH) { show_orig_path = true; diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index e847494a2f..e78ab99fda 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -163,6 +163,9 @@ Gtk::Widget *LPERoughen::newWidget() } ++it; } + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 149425112b..35da722d0f 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -95,7 +95,7 @@ Geom::PathVector LPEShowHandles::doEffect_path (Geom::PathVector const & path_in outline_path.clear(); } if (original_d) { - SPCurve * shape_curve = sp_shape->getCurveBeforeLPE(); + SPCurve * shape_curve = current_shape->getCurveForEdit(); if (shape_curve) { Geom::PathVector original_curve = shape_curve->get_pathvector(); if(original_path) { diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 5de9816bb9..e676f37a08 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -115,6 +115,9 @@ LPESimplify::newWidget() ++it; } vbox->pack_start(*buttons,true, true, 2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 914d23e4bc..47f8864ce3 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -89,13 +89,13 @@ void LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(!pathvector.empty()) { point_a = pathvector.initialPoint(); @@ -120,14 +120,14 @@ void LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast(lpeitem); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(from_original_width_toggler != from_original_width) { from_original_width_toggler = from_original_width; @@ -183,7 +183,7 @@ LPETransform2Pts::updateIndex() SPLPEItem * splpeitem = const_cast(sp_lpe_item); SPPath *sp_path = dynamic_cast(splpeitem); if (sp_path) { - pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector = sp_path->getCurveForEdit()->get_pathvector(); } if(pathvector.empty()) { return; @@ -362,6 +362,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->pack_start(*button2, true, true, 2); vbox->pack_start(*button3, true, true, 2); vbox->pack_start(*button4, true, true, 2); + if(Gtk::Widget* widg = defaultParamSet()) { + vbox->pack_start(*widg, true, true, 2); + } return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index f04c243f63..33460aa2d7 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -239,7 +239,7 @@ void LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + original_bbox(lpeitem, false, true); Geom::PathVector paths = ref_path.get_pathvector(); Geom::Point A,B; @@ -269,7 +269,7 @@ LPEVonKoch::resetDefaults(SPItem const* item) Effect::resetDefaults(item); using namespace Geom; - original_bbox(SP_LPE_ITEM(item)); + original_bbox(SP_LPE_ITEM(item), false, true); Point A,B; A[Geom::X] = boundingbox_X.min(); diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 8a42fc8b67..6df6278b11 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -5,8 +5,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "document.h" #include "live_effects/lpegroupbbox.h" - +#include "object/sp-clippath.h" +#include "object/sp-mask.h" +#include "object/sp-root.h" +#include "object/sp-shape.h" +#include "object/sp-item-group.h" #include "object/sp-lpe-item.h" namespace Inkscape { @@ -22,7 +27,32 @@ namespace LivePathEffect { * or of the transformed lpeitem (\c absolute = \c true) using sp_item_i2doc_affine. * @post Updated values of boundingbox_X and boundingbox_Y. These intervals are set to empty intervals when the precondition is not met. */ -void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) + +Geom::OptRect +GroupBBoxEffect::clip_mask_bbox(SPLPEItem *item, Geom::Affine transform) +{ + Geom::OptRect bbox; + Geom::Affine affine = transform * item->transform; + SPClipPath * clip_path = item->clip_ref->getObject(); + if(clip_path) { + bbox.unionWith(clip_path->geometricBounds(affine)); + } + SPMask * mask_path = item->mask_ref->getObject(); + if(mask_path) { + bbox.unionWith(mask_path->visualBounds(affine)); + } + SPGroup * group = dynamic_cast(item); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPLPEItem * subitem = dynamic_cast(*iter); + bbox.unionWith(clip_mask_bbox(subitem, affine)); + } + } + return bbox; +} + +void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute, bool clip_mask) { // Get item bounding box Geom::Affine transform; @@ -32,8 +62,12 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) else { transform = Geom::identity(); } - + Geom::OptRect bbox = lpeitem->geometricBounds(transform); + if (clip_mask) { + SPLPEItem * item = const_cast(lpeitem); + bbox.unionWith(clip_mask_bbox(item, transform * item->transform.inverse())); + } if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/live_effects/lpegroupbbox.h b/src/live_effects/lpegroupbbox.h index 7d4ac3e78c..de20138c93 100644 --- a/src/live_effects/lpegroupbbox.h +++ b/src/live_effects/lpegroupbbox.h @@ -18,12 +18,13 @@ namespace LivePathEffect { class GroupBBoxEffect { protected: - // Bounding box of the item the path effect is applied on + // Bounding box of the item the path effect is applied on Geom::Interval boundingbox_X; Geom::Interval boundingbox_Y; - //This sets boundingbox_X and boundingbox_Y - void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); + //This sets boundingbox_X and boundingbox_Y + Geom::OptRect clip_mask_bbox(SPLPEItem * item, Geom::Affine transform); + void original_bbox(SPLPEItem const* lpeitem, bool absolute = false, bool clip_mask = false); }; }; //namespace LivePathEffect diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index c66d53266e..b5ee8b5cf5 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -64,8 +64,7 @@ public: virtual gchar * param_getSVGValue() const { Inkscape::SVGOStringStream os; writesvg(os, _vector); - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } virtual gchar * param_getDefaultSVGValue() const { diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 1a01f269be..bfbda2bfd2 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -57,15 +57,13 @@ BoolParam::param_readSVGValue(const gchar * strvalue) gchar * BoolParam::param_getSVGValue() const { - gchar * str = g_strdup(value ? "true" : "false"); - return str; + return g_strdup(value ? "true" : "false"); } gchar * BoolParam::param_getDefaultSVGValue() const { - gchar * str = g_strdup(defvalue ? "true" : "false"); - return str; + return g_strdup(defvalue ? "true" : "false"); } Gtk::Widget * diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h index ca237c0f74..82eaa6d433 100644 --- a/src/live_effects/parameter/enum.h +++ b/src/live_effects/parameter/enum.h @@ -61,13 +61,11 @@ public: return true; }; gchar * param_getSVGValue() const { - gchar * str = g_strdup( enumdataconv->get_key(value).c_str() ); - return str; + return g_strdup( enumdataconv->get_key(value).c_str() ); }; gchar * param_getDefaultSVGValue() const { - gchar * str = g_strdup( enumdataconv->get_key(defvalue).c_str() ); - return str; + return g_strdup( enumdataconv->get_key(defvalue).c_str() ); }; E get_value() const { diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index e08881f6d4..5a21f572b5 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -55,8 +55,7 @@ HiddenParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -64,8 +63,7 @@ HiddenParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } Gtk::Widget * diff --git a/src/live_effects/parameter/message.cpp b/src/live_effects/parameter/message.cpp index 1e2c9ec50f..03eb2219f5 100644 --- a/src/live_effects/parameter/message.cpp +++ b/src/live_effects/parameter/message.cpp @@ -17,8 +17,8 @@ MessageParam::MessageParam( const Glib::ustring& label, const Glib::ustring& tip const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, const gchar * default_message ) : Parameter(label, tip, key, wr, effect), - message(g_strdup(default_message)), - defmessage(g_strdup(default_message)) + message(default_message), + defmessage(default_message) { _label = NULL; _min_height = -1; @@ -33,7 +33,7 @@ MessageParam::param_set_default() void MessageParam::param_update_default(const gchar * default_message) { - defmessage = g_strdup(default_message); + defmessage = default_message; } bool @@ -46,13 +46,13 @@ MessageParam::param_readSVGValue(const gchar * strvalue) gchar * MessageParam::param_getSVGValue() const { - return message; + return g_strdup(message); } gchar * MessageParam::param_getDefaultSVGValue() const { - return defmessage; + return g_strdup(defmessage); } void @@ -106,7 +106,7 @@ MessageParam::param_setValue(const gchar * strvalue) if (strcmp(strvalue, message) != 0) { param_effect->upd_params = true; } - message = g_strdup(strvalue); + message = strvalue; } diff --git a/src/live_effects/parameter/message.h b/src/live_effects/parameter/message.h index 2ac2c791a6..fd850a7675 100644 --- a/src/live_effects/parameter/message.h +++ b/src/live_effects/parameter/message.h @@ -41,8 +41,8 @@ private: int _min_height; MessageParam(const MessageParam&); MessageParam& operator=(const MessageParam&); - gchar * message; - gchar * defmessage; + const gchar * message; + const gchar * defmessage; }; } //namespace LivePathEffect diff --git a/src/live_effects/parameter/originalitemarray.cpp b/src/live_effects/parameter/originalitemarray.cpp index fe2dc0c8d6..b89485e2db 100644 --- a/src/live_effects/parameter/originalitemarray.cpp +++ b/src/live_effects/parameter/originalitemarray.cpp @@ -438,8 +438,7 @@ gchar * OriginalItemArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->actived ? "1" : "0"); } - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * OriginalItemArrayParam::param_getDefaultSVGValue() const diff --git a/src/live_effects/parameter/originalpath.cpp b/src/live_effects/parameter/originalpath.cpp index b6a90671e0..018e1e69e9 100644 --- a/src/live_effects/parameter/originalpath.cpp +++ b/src/live_effects/parameter/originalpath.cpp @@ -93,7 +93,7 @@ OriginalPathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags* SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index caec74a8ba..928bf29766 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -428,9 +428,9 @@ void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/ if (SP_IS_SHAPE(linked_obj)) { SPLPEItem * lpe_item = SP_LPE_ITEM(linked_obj); if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else if (_allow_only_bspline_spiro && lpe_item && lpe_item->hasPathEffect()){ - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); PathEffectList lpelist = lpe_item->getEffectList(); PathEffectList::iterator i; for (i = lpelist.begin(); i != lpelist.end(); ++i) { @@ -524,13 +524,12 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const } os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0") << "," << ((*iter)->visibled ? "1" : "0"); } - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * OriginalPathArrayParam::param_getDefaultSVGValue() const { - return ""; + return g_strdup(""); } void OriginalPathArrayParam::update() diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 497113e032..a175359f09 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -91,8 +91,7 @@ ScalarParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -100,8 +99,7 @@ ScalarParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void @@ -129,6 +127,9 @@ ScalarParam::param_update_default(const gchar * default_value) void ScalarParam::param_set_value(gdouble val) { + if (value != val) { + param_effect->upd_params = true; + } value = val; if (integer) value = round(value); diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 02075ee8e1..ab385daa64 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -460,7 +460,7 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { if (_from_original_d) { - curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + curve = SP_SHAPE(linked_obj)->getCurveForEdit(); } else { curve = SP_SHAPE(linked_obj)->getCurve(); } diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 9b4723da3e..b811b7f2b9 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -128,8 +128,7 @@ PointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << *dynamic_cast( this ); - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -137,8 +136,7 @@ PointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void @@ -212,10 +210,10 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or s = A; } } - pparam->param_setValue(s); - SPLPEItem * splpeitem = dynamic_cast(item); - if(splpeitem && this->pparam->liveupdate){ - sp_lpe_item_update_patheffect(splpeitem, true, true); + if(this->pparam->liveupdate){ + pparam->param_setValue(s, true); + } else { + pparam->param_setValue(s); } } @@ -231,10 +229,7 @@ PointParamKnotHolderEntity::knot_click(guint state) if (state & GDK_CONTROL_MASK) { if (state & GDK_MOD1_MASK) { this->pparam->param_set_default(); - SPLPEItem * splpeitem = dynamic_cast(item); - if(splpeitem){ - sp_lpe_item_update_patheffect(splpeitem, true, true); - } + pparam->param_setValue(*pparam,true); } } } diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index 4afa43c6ea..23912bedbe 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -67,8 +67,7 @@ RandomParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value << ';' << startseed; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -76,8 +75,7 @@ RandomParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue << ';' << defseed; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 7e56b2c758..37ae3a1d7c 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -112,8 +112,7 @@ TextParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << value; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -121,8 +120,7 @@ TextParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index e26884d6ad..bb9d9a90e0 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -55,15 +55,13 @@ ToggleButtonParam::param_readSVGValue(const gchar * strvalue) gchar * ToggleButtonParam::param_getSVGValue() const { - gchar * str = g_strdup(value ? "true" : "false"); - return str; + return g_strdup(value ? "true" : "false"); } gchar * ToggleButtonParam::param_getDefaultSVGValue() const { - gchar * str = g_strdup(defvalue ? "true" : "false"); - return str; + return g_strdup(defvalue ? "true" : "false"); } void diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index a010faf27c..ab66e72569 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -78,8 +78,7 @@ TransformedPointParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -87,8 +86,7 @@ TransformedPointParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } void diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp index ced93ef0de..1207a05da2 100644 --- a/src/live_effects/parameter/vector.cpp +++ b/src/live_effects/parameter/vector.cpp @@ -97,8 +97,7 @@ VectorParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; os << origin << " , " << vector; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } gchar * @@ -106,8 +105,7 @@ VectorParam::param_getDefaultSVGValue() const { Inkscape::SVGOStringStream os; os << defvalue; - gchar * str = g_strdup(os.str().c_str()); - return str; + return g_strdup(os.str().c_str()); } Gtk::Widget * diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index 3eea8855ca..6ecd3a1fae 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -192,21 +192,22 @@ void Box3DSide::set_shape() { c->lineto(box3d_get_corner_screen(box, corners[3])); c->closepath(); - /* Reset the this'scurve to the "original_curve" + /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveInsync( c, TRUE); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); - - if (success) { - this->setCurveInsync(c_lpe, TRUE); + SPCurve * before = this->getCurveBeforeLPE(); + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } - - c_lpe->unref(); + } else { + this->setCurveInsync(c); + } + if (before) { + before->unref(); } - c->unref(); } diff --git a/src/object/sp-clippath.cpp b/src/object/sp-clippath.cpp index 4f69bd0262..4afbf7e510 100644 --- a/src/object/sp-clippath.cpp +++ b/src/object/sp-clippath.cpp @@ -238,14 +238,12 @@ void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox) { Geom::OptRect SPClipPath::geometricBounds(Geom::Affine const &transform) { Geom::OptRect bbox; - for (auto& i: children) { if (SP_IS_ITEM(&i)) { - Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); - bbox.unionWith(tmp); + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(transform); + bbox.unionWith(tmp); } } - return bbox; } diff --git a/src/object/sp-conn-end-pair.cpp b/src/object/sp-conn-end-pair.cpp index daadd0cddc..1a0ec5d705 100644 --- a/src/object/sp-conn-end-pair.cpp +++ b/src/object/sp-conn-end-pair.cpp @@ -175,7 +175,7 @@ void SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const { void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { - SPCurve const *curve = _path->get_curve_reference(); + SPCurve const *curve = _path->getCurveForEdit(true); SPItem *h2attItem[2] = {0}; getAttachedItems(h2attItem); Geom::Affine i2d = _path->i2doc_affine(); @@ -322,7 +322,7 @@ bool SPConnEndPair::reroutePathFromLibavoid() return false; } - SPCurve *curve = _path->get_curve(); + SPCurve *curve = _path->getCurve(true); recreateCurve(curve, _connRef, _connCurvature); diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index c32e3012c6..95bfd61606 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -18,6 +18,8 @@ #include #include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include <2geom/angle.h> #include <2geom/circle.h> @@ -410,7 +412,7 @@ const char *SPGenericEllipse::displayName() const } // Create path for rendering shape on screen -void SPGenericEllipse::set_shape(bool force) +void SPGenericEllipse::set_shape() { // std::cout << "SPGenericEllipse::set_shape: Entrance" << std::endl; if (hasBrokenPathEffect()) { @@ -420,7 +422,7 @@ void SPGenericEllipse::set_shape(bool force) // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync(cold, TRUE); + this->setCurveInsync(cold); cold->unref(); } @@ -432,7 +434,7 @@ void SPGenericEllipse::set_shape(bool force) this->normalize(); - SPCurve *curve = NULL; + SPCurve *c = NULL; // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. Geom::Circle circle(0, 0, 1); @@ -465,7 +467,7 @@ void SPGenericEllipse::set_shape(bool force) } else { pb.flush(); } - curve = new SPCurve(pb.peek()); + c = new SPCurve(pb.peek()); // gchar *str = sp_svg_write_path(curve->get_pathvector()); // std::cout << " path: " << str << std::endl; @@ -473,32 +475,25 @@ void SPGenericEllipse::set_shape(bool force) // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); - curve->transform(aff); - + c->transform(aff); + /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { - curve->unref(); - return; + SPCurve * before = this->getCurveBeforeLPE(); + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } + } else { + this->setCurveInsync(c); } - this->setCurveInsync(curve, TRUE); - this->setCurveBeforeLPE(curve); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = curve->copy(); - bool success = this->performPathEffect(c_lpe); - - if (success) { - this->setCurveInsync(c_lpe, TRUE); - } - - c_lpe->unref(); + if (before) { + before->unref(); } - - curve->unref(); - // std::cout << "SPGenericEllipse::set_shape: Exit" << std::endl; + c->unref(); } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) @@ -633,25 +628,6 @@ void SPGenericEllipse::modified(guint flags) SPShape::modified(flags); } -void SPGenericEllipse::update_patheffect(bool write) -{ - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); - - if (this->_curve != NULL && type == SP_GENERIC_ELLIPSE_ARC) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - void SPGenericEllipse::normalize() { Geom::AngleInterval a(this->start, this->end, true); @@ -698,7 +674,7 @@ void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry this->rx = rx; this->ry = ry; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Inkscape::Preferences * prefs = Inkscape::Preferences::get(); // those pref values are in degrees, while we want radians if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) { diff --git a/src/object/sp-ellipse.h b/src/object/sp-ellipse.h index a31b571d85..0aa3dd1c62 100644 --- a/src/object/sp-ellipse.h +++ b/src/object/sp-ellipse.h @@ -64,15 +64,13 @@ public: virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char *displayName() const; - virtual void set_shape(bool force = false); + virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const &xform); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void modified(unsigned int flags); - virtual void update_patheffect(bool write); - /** * @brief Makes sure that start and end lie between 0 and 2 * PI. */ diff --git a/src/object/sp-item-group.cpp b/src/object/sp-item-group.cpp index 73c1dcb6c6..a3fa6c6e87 100644 --- a/src/object/sp-item-group.cpp +++ b/src/object/sp-item-group.cpp @@ -58,7 +58,7 @@ using Inkscape::DocumentUndo; -static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write); +static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write); SPGroup::SPGroup() : SPLPEItem(), _expanded(false), @@ -88,7 +88,6 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) SPLPEItem::child_added(child, ref); SPObject *last_child = this->lastChild(); - if (last_child && last_child->getRepr() == child) { // optimization for the common special case where the child is being added at the end SPItem *item = dynamic_cast(last_child); @@ -121,7 +120,6 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) } } } - this->requestModified(SP_OBJECT_MODIFIED_FLAG); } @@ -642,13 +640,13 @@ sp_item_group_ungroup (SPGroup *group, std::vector &children, bool do_d if (item) { item->doWriteTransform(item->transform, NULL, false); children.insert(children.begin(),item); + item->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { g_assert_not_reached(); } Inkscape::GC::release(repr); } - if (do_done) { DocumentUndo::done(doc, SP_VERB_NONE, _("Ungroup")); } @@ -900,54 +898,52 @@ void SPGroup::update_patheffect(bool write) { #ifdef GROUP_VERBOSE g_message("sp_group_update_patheffect: %p\n", lpeitem); #endif - std::vector const item_list = sp_item_group_item_list(this); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; - - SPLPEItem *lpe_item = dynamic_cast(sub_item); - if (lpe_item) { - lpe_item->update_patheffect(write); + if (sub_item) { + SPLPEItem *lpe_item = dynamic_cast(sub_item); + if (lpe_item) { + lpe_item->update_patheffect(write); + } } } + this->resetClipPathAndMaskLPE(); if (hasPathEffect() && pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - - if (lpeobj && lpeobj->get_lpe()) { - lpeobj->get_lpe()->doBeforeEffect_impl(this); - } - } - - sp_group_perform_patheffect(this, this, write); - - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - - if (lpeobj && lpeobj->get_lpe()) { - lpeobj->get_lpe()->doAfterEffect(this); + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe) { + lpeobj->get_lpe()->doBeforeEffect_impl(this); + sp_group_perform_patheffect(this, this, lpe, write); + lpeobj->get_lpe()->doAfterEffect(this); + } } } } } static void -sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) +sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write) { std::vector const item_list = sp_item_group_item_list(group); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *sub_item = *iter; - SPGroup *sub_group = dynamic_cast(sub_item); if (sub_group) { - sp_group_perform_patheffect(sub_group, top_group, write); + sp_group_perform_patheffect(sub_group, top_group, lpe, write); } else { - SPShape *sub_shape = dynamic_cast(sub_item); + SPShape* sub_shape = dynamic_cast(sub_item); + SPPath* sub_path = dynamic_cast(sub_item); + SPItem* clipmaskto = dynamic_cast(sub_item); + if (clipmaskto) { + top_group->applyToClipPath(clipmaskto, lpe); + top_group->applyToMask(clipmaskto, lpe); + } if (sub_shape) { SPCurve * c = NULL; // If item is a SPRect, convert it to path first: @@ -973,19 +969,16 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) bool success = false; // only run LPEs when the shape has a curve defined if (c) { + lpe->pathvector_before_effect = c->get_pathvector(); c->transform(i2anc_affine(sub_item, top_group)); - success = top_group->performPathEffect(c, sub_shape); + success = top_group->performOnePathEffect(c, sub_shape, lpe); c->transform(i2anc_affine(sub_item, top_group).inverse()); Inkscape::XML::Node *repr = sub_item->getRepr(); if (c && success) { - SPPath *sub_path = dynamic_cast(sub_item); - if (!sub_path) { - sub_shape->setCurveInsync( sub_shape->getCurveBeforeLPE(), TRUE); - sub_shape->setCurve(c, TRUE); - sub_shape->setCurveInsync( c, TRUE); - } + sub_shape->setCurveInsync(c); + lpe->pathvector_after_effect = c->get_pathvector(); if (write) { - gchar *str = sp_svg_write_path(c->get_pathvector()); + gchar *str = sp_svg_write_path(lpe->pathvector_after_effect); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE g_message("sp_group_perform_patheffect writes 'd' attribute"); @@ -999,7 +992,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - sub_shape->setCurve(oldcurve, TRUE); + sub_shape->setCurve(oldcurve); oldcurve->unref(); } } @@ -1008,6 +1001,11 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, bool write) } } } + SPItem* clipmaskto = dynamic_cast(group); + if (clipmaskto) { + top_group->applyToClipPath(clipmaskto, lpe); + top_group->applyToMask(clipmaskto, lpe); + } } /* diff --git a/src/object/sp-item.cpp b/src/object/sp-item.cpp index f7a4ff6720..a228d9313d 100644 --- a/src/object/sp-item.cpp +++ b/src/object/sp-item.cpp @@ -29,7 +29,6 @@ #include "inkscape.h" #include "desktop.h" - #include "gradient-chemistry.h" #include "conn-avoid-ref.h" #include "conditions.h" @@ -1079,6 +1078,23 @@ bool SPItem::isFiltered() const { return (style && style->filter.href && style->filter.href->getObject()); } + +SPObject* SPItem::isInMask() const { + SPObject* parent = this->parent; + while (parent && !dynamic_cast(parent)) { + parent = parent->parent; + } + return parent; +} + +SPObject* SPItem::isInClipPath() const { + SPObject* parent = this->parent; + while (parent && !dynamic_cast(parent)) { + parent = parent->parent; + } + return parent; +} + unsigned SPItem::display_key_new(unsigned numkeys) { static unsigned dkey = 0; diff --git a/src/object/sp-item.h b/src/object/sp-item.h index 36af02edc7..88fca97799 100644 --- a/src/object/sp-item.h +++ b/src/object/sp-item.h @@ -290,6 +290,10 @@ public: */ bool isFiltered() const; + SPObject* isInMask() const; + + SPObject* isInClipPath() const; + void invoke_print(SPPrintContext *ctx); /** diff --git a/src/object/sp-line.cpp b/src/object/sp-line.cpp index 09ffd1f17d..2ba6339728 100644 --- a/src/object/sp-line.cpp +++ b/src/object/sp-line.cpp @@ -150,7 +150,7 @@ void SPLine::set_shape() { c->moveto(this->x1.computed, this->y1.computed); c->lineto(this->x2.computed, this->y2.computed); - this->setCurveInsync(c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update + this->setCurveInsync(c); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update this->setCurveBeforeLPE(c); // LPE's cannot be applied to lines. (the result can (generally) not be represented as SPLine) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index f3cc841fb8..e0ef848af0 100644 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -41,6 +41,7 @@ #include "svg/svg.h" #include "sp-clippath.h" #include "sp-mask.h" +#include "sp-rect.h" #include "ui/tools-switch.h" #include "ui/tools/node-tool.h" @@ -48,9 +49,8 @@ static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); - static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); -static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths); +static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false); typedef std::list HRefList; static std::string patheffectlist_svg_string(PathEffectList const & list); @@ -179,11 +179,11 @@ void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { } void SPLPEItem::modified(unsigned int flags) { - if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { - sp_lpe_item_update_patheffect(this, true, true); - } - -// SPItem::onModified(flags); + //TODO: remove if no regressions + //stop update when modified and make the effect update on the LPE transform method if the effect require it + //if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + // sp_lpe_item_update_patheffect(this, true, true); + //} } Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { @@ -200,113 +200,85 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape return repr; } + /** * returns true when LPE was successful. */ -bool SPLPEItem::hasPathEffectOnClipOrMask() const -{ - bool has_clipormask_lpe = false; +bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { + + if (!curve) { + return false; + } + if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (!lpeobj) { + /** \todo Investigate the cause of this. + * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. + */ + g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); return false; } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!lpe) { + if(!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { return false; } - if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - return false; - } - if (lpe->apply_to_clippath_and_mask) { - has_clipormask_lpe = true; - } - } } } - return has_clipormask_lpe; -} - -bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive() const -{ - if (parent && SP_IS_LPE_ITEM(parent)) { - return hasPathEffectOnClipOrMask() || SP_LPE_ITEM(parent)->hasPathEffectOnClipOrMaskRecursive(); - } - else { - return hasPathEffectOnClipOrMask(); - } + return true; } /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask) { - - if (!curve) { +bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask) { + if (!lpe) { + /** \todo Investigate the cause of this. + * Not sure, but I think this can happen when an unknown effect type is specified... + */ + g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); return false; } - bool has_clipormask_lpe = false; - if (this->hasPathEffect() && this->pathEffectsEnabled()) { - for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj) { - /** \todo Investigate the cause of this. - * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. - */ - g_warning("SPLPEItem::performPathEffect - NULL lpeobj in list!"); - return false; + if (lpe->isVisible()) { + if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { + // if the effect expects mouse input before being applied and the input is not finished + // yet, we don't alter the path + return false; + } + //if is not clip or mask or LPE apply to clip and mask + if (!(is_clip_or_mask && !lpe->apply_to_clippath_and_mask)) { + lpe->setCurrentShape(current); + if (!SP_IS_GROUP(this)) { + lpe->pathvector_before_effect = curve->get_pathvector(); } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!lpe) { - /** \todo Investigate the cause of this. - * Not sure, but I think this can happen when an unknown effect type is specified... - */ - g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); - return false; + // To Calculate BBox on shapes and nested LPE + current->setCurveInsync(curve); + // Groups have their doBeforeEffect called elsewhere + if (!SP_IS_GROUP(this) && !is_clip_or_mask) { + lpe->doBeforeEffect_impl(this); } - if (lpe->isVisible()) { - if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { - // if the effect expects mouse input before being applied and the input is not finished - // yet, we don't alter the path - return false; - } - if (lpe->apply_to_clippath_and_mask) { - has_clipormask_lpe = true; - } - if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { - // Groups have their doBeforeEffect called elsewhere - if (current) { - lpe->setCurrentShape(current); - } - if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect_impl(this); - } - try { - lpe->doEffect(curve); - } - catch (std::exception & e) { - g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); - if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Path Effect.") ); - } - return false; - } - if (!SP_IS_GROUP(this)) { - lpe->pathvector_after_effect = curve->get_pathvector(); - lpe->doAfterEffect(this); - } + try { + lpe->doEffect(curve); + } + + catch (std::exception & e) { + g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); + if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { + SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, + _("An exception occurred during execution of the Path Effect.") ); } + return false; + } + + + if (!SP_IS_GROUP(this)) { + // To have processed the shape to doAfterEffect + lpe->pathvector_after_effect = curve->get_pathvector(); + lpe->doAfterEffect(this); } - } - if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_clipormask_lpe){ - this->applyToClipPath(this); - this->applyToMask(this); } } return true; @@ -327,6 +299,7 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); #endif g_return_if_fail (lpeitem != NULL); + g_return_if_fail (SP_IS_OBJECT (lpeitem)); g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); if (!lpeitem->pathEffectsEnabled()) @@ -346,7 +319,6 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) else { top = lpeitem; } - top->update_patheffect(write); } @@ -367,95 +339,98 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) - { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPLPEItem * clip_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(clip_data); + } } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + + SPMask *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPLPEItem * mask_data = dynamic_cast(*iter); + sp_lpe_item_create_original_path_recursive(mask_data); + } } if (SP_IS_GROUP(lpeitem)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); + std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); } } - } - else if (SP_IS_PATH(lpeitem)) { - Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); + } else if (SPPath * path = dynamic_cast(lpeitem)) { + Inkscape::XML::Node *pathrepr = path->getRepr(); if ( !pathrepr->attribute("inkscape:original-d") ) { pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); + path->setCurveBeforeLPE(path->getCurve()); + } + } else if (SPShape * shape = dynamic_cast(lpeitem)) { + if (SPCurve * c_lpe = shape->getCurveBeforeLPE()) { + c_lpe->unref(); + } else { + shape->setCurveBeforeLPE(shape->getCurve()); } } } static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force) { g_return_if_fail(lpeitem != NULL); - if (SP_IS_GROUP(lpeitem)) { - if (!lpeitem->hasPathEffectOnClipOrMaskRecursive()) { - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } + SPItem *item = dynamic_cast(lpeitem); + if (!item) { + return; + } + SPGroup *group = dynamic_cast(lpeitem); + SPShape *shape = dynamic_cast(lpeitem); + SPPath *path = dynamic_cast(lpeitem); + SPClipPath *clip_path = item->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPLPEItem* clip_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, shape && !shape->hasPathEffectRecursive()); } + } + + SPMask *mask_path = item->mask_ref->getObject(); + if(mask_path) { + std::vector mask_path_list = mask_path->childList(true); + for ( std::vector::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) { + SPLPEItem* mask_data = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, shape && !shape->hasPathEffectRecursive()); + } + } + + if (group) { std::vector item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - if (SP_IS_LPE_ITEM(subitem)) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths); - } + SPLPEItem* subitem = dynamic_cast(*iter); + sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths, false); } - } else if (SP_IS_PATH(lpeitem)) { + } else if (path) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } - mask = dynamic_cast(lpeitem->parent); - clip_path = dynamic_cast(lpeitem->parent); - if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("inkscape:original-d")) || - ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("inkscape:original-d"))) + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("inkscape:original-d")) { if (!keep_paths) { repr->setAttribute("d", repr->attribute("inkscape:original-d")); } repr->setAttribute("inkscape:original-d", NULL); + path->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); } } - } else if (SP_IS_SHAPE(lpeitem)) { + } else if (shape) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), keep_paths); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); - } - mask = dynamic_cast(lpeitem->parent); - clip_path = dynamic_cast(lpeitem->parent); - if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("d")) || - ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("d"))) + if ((!lpeitem->hasPathEffectRecursive() || force) && repr->attribute("d")) { if (!keep_paths) { repr->setAttribute("d", NULL); @@ -469,6 +444,7 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) sp_item_list_to_curves(items, selected, to_select, true); } } + shape->setCurveBeforeLPE(NULL); } else { if (!keep_paths) { sp_lpe_item_update_patheffect(lpeitem, true, true); @@ -515,7 +491,7 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) } // perform this once when the effect is applied - lpe->doOnApply(this); + lpe->doOnApply_impl(this); // indicate that all necessary preparations are done and the effect can be performed lpe->setReady(); @@ -526,16 +502,6 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); - SPMask * mask = mask_ref->getObject(); - if(mask && !hasPathEffectOnClipOrMaskRecursive()) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), false); - } - SPClipPath * clip_path = clip_ref->getObject(); - if(clip_path && !hasPathEffectOnClipOrMaskRecursive()) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), false); - } //fix bug 1219324 if (SP_ACTIVE_DESKTOP ) { Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; @@ -678,23 +644,6 @@ bool SPLPEItem::hasBrokenPathEffect() const } -bool SPLPEItem::hasPathEffect() const -{ - if (!path_effect_list || path_effect_list->empty()) { - return false; - } - - // go through the list; if some are unknown or invalid, we are not an LPE item! - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (!lpeobj || !lpeobj->get_lpe()) { - return false; - } - } - - return true; -} bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const { @@ -718,10 +667,69 @@ bool SPLPEItem::hasPathEffectOfType(int const type, bool is_ready) const return false; } +/** + * returns true when any LPE apply to clip or mask. + */ +bool SPLPEItem::hasPathEffectOnClipOrMask(SPLPEItem * shape) const +{ + if (shape->hasPathEffectRecursive()) { + return true; + } + if (!path_effect_list || path_effect_list->empty()) { + return false; + } + + for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj) { + continue; + } + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (lpe->apply_to_clippath_and_mask) { + return true; + } + } + return false; +} + +/** + * returns true when any LPE apply to clip or mask. + */ +bool SPLPEItem::hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const +{ + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (parent_lpe_item) { + return hasPathEffectOnClipOrMask(shape) || parent_lpe_item->hasPathEffectOnClipOrMaskRecursive(shape); + } + else { + return hasPathEffectOnClipOrMask(shape); + } +} + +bool SPLPEItem::hasPathEffect() const +{ + if (!path_effect_list || path_effect_list->empty()) { + return false; + } + + // go through the list; if some are unknown or invalid, we are not an LPE item! + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (!lpeobj || !lpeobj->get_lpe()) { + return false; + } + } + + return true; +} + bool SPLPEItem::hasPathEffectRecursive() const { - if (parent && SP_IS_LPE_ITEM(parent)) { - return hasPathEffect() || SP_LPE_ITEM(parent)->hasPathEffectRecursive(); + SPLPEItem * parent_lpe_item = dynamic_cast(parent); + if (parent_lpe_item) { + return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive(); } else { return hasPathEffect(); @@ -729,71 +737,172 @@ bool SPLPEItem::hasPathEffectRecursive() const } void -SPLPEItem::applyToClipPath(SPItem *item) +SPLPEItem::resetClipPathAndMaskLPE(bool fromrecurse) { - SPClipPath *clip_path = item->clip_ref->getObject(); + if (fromrecurse) { + SPGroup* group = dynamic_cast(this); + SPShape* shape = dynamic_cast(this); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(true); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit()); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); + } + } + return; + } + SPClipPath *clip_path = this->clip_ref->getObject(); if(clip_path) { std::vector clip_path_list = clip_path->childList(true); for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { - SPObject * clip_data = *iter; - applyToClipPathOrMask(SP_ITEM(clip_data), item); + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(true); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit()); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); + } + } } } - if(SP_IS_GROUP(item)){ - std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - applyToClipPath(SP_ITEM(subitem)); + SPMask *mask = this->mask_ref->getObject(); + if(mask) { + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPGroup* group = dynamic_cast(*iter); + SPShape* shape = dynamic_cast(*iter); + if (group) { + std::vector item_list = sp_item_group_item_list(group); + for ( std::vector::const_iterator iter2=item_list.begin();iter2!=item_list.end();++iter2) { + SPLPEItem * subitem = dynamic_cast(*iter2); + if (subitem) { + subitem->resetClipPathAndMaskLPE(true); + } + } + } else if (shape) { + shape->setCurveInsync( shape->getCurveForEdit()); + if (!hasPathEffectOnClipOrMaskRecursive(shape)) { + shape->getRepr()->setAttribute("inkscape:original-d", NULL); + shape->setCurveBeforeLPE(NULL); + } else { + // make sure there is an original-d for paths!!! + sp_lpe_item_create_original_path_recursive(shape); + } + } + } + } +} + +void +SPLPEItem::applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) +{ + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } + SPClipPath *clip_path = to->clip_ref->getObject(); + if(clip_path) { + std::vector clip_path_list = clip_path->childList(true); + for ( std::vector::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { + SPObject * clip_data = *iter; + applyToClipPathOrMask(SP_ITEM(clip_data), to, lpe); } } } void -SPLPEItem::applyToMask(SPItem *item) +SPLPEItem::applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { - SPMask *mask = item->mask_ref->getObject(); + if (lpe && !lpe->apply_to_clippath_and_mask) { + return; + } + SPMask *mask = to->mask_ref->getObject(); if(mask) { std::vector mask_list = mask->childList(true); for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { SPObject * mask_data = *iter; - applyToClipPathOrMask(SP_ITEM(mask_data), item); - } - } - if(SP_IS_GROUP(item)){ - std::vector item_list = sp_item_group_item_list(SP_GROUP(item)); - for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPObject *subitem = *iter; - applyToMask(SP_ITEM(subitem)); + applyToClipPathOrMask(SP_ITEM(mask_data), to, lpe); } } } void -SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) +SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe) { - if (SP_IS_GROUP(clip_mask)) { - std::vector item_list = sp_item_group_item_list(SP_GROUP(clip_mask)); + SPGroup* group = dynamic_cast(clip_mask); + SPShape* shape = dynamic_cast(clip_mask); + SPLPEItem* tolpe = dynamic_cast(to); + if (group) { + std::vector item_list = sp_item_group_item_list(group); for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { SPItem *subitem = *iter; - applyToClipPathOrMask(subitem, item); + applyToClipPathOrMask(subitem, to, lpe); } - } else if (SP_IS_SHAPE(clip_mask)) { + } else if (shape) { SPCurve * c = NULL; - - if (SP_IS_PATH(clip_mask)) { - c = SP_PATH(clip_mask)->get_original_curve(); + // If item is a SPRect, convert it to path first: + if ( dynamic_cast(shape) ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty() ) { + sel->clear(); + sel->add(SP_ITEM(shape)); + sel->toCurves(); + SPItem* item = sel->singleItem(); + shape = dynamic_cast(item); + if (!shape) { + return; + } + sel->clear(); + sel->add(this); + } + } + } + if (lpe) { //group + c = shape->getCurve(); } else { - c = SP_SHAPE(clip_mask)->getCurve(); + c = shape->getCurveForEdit(); } if (c) { bool success = false; try { if(SP_IS_GROUP(this)){ - c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); - c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this))); + if (lpe) { + success = this->performOnePathEffect(c, shape, lpe, true); + } else { + success = this->performPathEffect(c, shape, true); + } + c->transform(i2anc_affine(SP_GROUP(to), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + if (lpe) { + success = this->performOnePathEffect(c, shape, lpe, true); + } else { + success = this->performPathEffect(c, SP_SHAPE(clip_mask), true); + } } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); @@ -804,8 +913,8 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) success = false; } Inkscape::XML::Node *repr = clip_mask->getRepr(); - // This c check allow to not apply LPE if curve is NULL after performPathEffect used in clone.obgets LPE if (success && c) { + shape->setCurveInsync(c); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); g_free(str); @@ -815,7 +924,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new (std::nothrow) SPCurve(pv); if (oldcurve) { - SP_SHAPE(clip_mask)->setCurve(oldcurve, TRUE); + SP_SHAPE(clip_mask)->setCurve(oldcurve); oldcurve->unref(); } } @@ -823,6 +932,7 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem *item) if (c) { c->unref(); } + shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 82f3940c10..0e6049d4e6 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -70,14 +70,14 @@ public: virtual void update_patheffect(bool write); - bool hasPathEffectOnClipOrMask() const; - bool hasPathEffectOnClipOrMaskRecursive() const; - bool performPathEffect(SPCurve *curve, SPShape *current = NULL, bool is_clip_or_mask = false); - + bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask = false); + bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type, bool is_ready = true) const; bool hasPathEffectRecursive() const; + bool hasPathEffectOnClipOrMask(SPLPEItem * shape) const; + bool hasPathEffectOnClipOrMaskRecursive(SPLPEItem * shape) const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; @@ -94,9 +94,10 @@ public: void removeAllPathEffects(bool keep_paths); void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); - void applyToMask(SPItem * item); - void applyToClipPath(SPItem * item); - void applyToClipPathOrMask(SPItem * clip_mask, SPItem * item); + void resetClipPathAndMaskLPE(bool fromrecurse = false); + void applyToMask(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); + void applyToClipPath(SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); + void applyToClipPathOrMask(SPItem * clip_mask, SPItem* to, Inkscape::LivePathEffect::Effect *lpe = NULL); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); void editNextParamOncanvas(SPDesktop *dt); diff --git a/src/object/sp-mask.cpp b/src/object/sp-mask.cpp index b65c145fc2..2e764131c2 100644 --- a/src/object/sp-mask.cpp +++ b/src/object/sp-mask.cpp @@ -115,6 +115,33 @@ void SPMask::set(unsigned int key, const gchar* value) { } } +Geom::OptRect +SPMask::geometricBounds(Geom::Affine const &transform) { + Geom::OptRect bbox; + + for (auto& i: children) { + if (SP_IS_ITEM(&i)) { + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); + bbox.unionWith(tmp); + } + } + + return bbox; +} + +Geom::OptRect +SPMask::visualBounds(Geom::Affine const &transform) { + Geom::OptRect bbox; + for (auto& i: children) { + if (SP_IS_ITEM(&i)) { + Geom::OptRect tmp = SP_ITEM(&i)->visualBounds(transform); + bbox.unionWith(tmp); + } + } + + return bbox; +} + void SPMask::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { /* Invoke SPObjectGroup implementation */ SPObjectGroup::child_added(child, ref); diff --git a/src/object/sp-mask.h b/src/object/sp-mask.h index 02d37b82b0..26e5108300 100644 --- a/src/object/sp-mask.h +++ b/src/object/sp-mask.h @@ -47,6 +47,10 @@ public: Inkscape::DrawingItem *sp_mask_show(Inkscape::Drawing &drawing, unsigned int key); void sp_mask_hide(unsigned int key); + Geom::OptRect geometricBounds(Geom::Affine const &transform); + + Geom::OptRect visualBounds(Geom::Affine const &transform) ; + void sp_mask_set_bbox(unsigned int key, Geom::OptRect const &bbox); protected: diff --git a/src/object/sp-object.cpp b/src/object/sp-object.cpp index bc930a4304..d3c429c2a9 100644 --- a/src/object/sp-object.cpp +++ b/src/object/sp-object.cpp @@ -413,7 +413,6 @@ std::vector SPObject::childList(bool add_ref, Action) { l.push_back(&child); } return l; - } gchar const *SPObject::label() const { diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index 82e0b49476..2864e88cb9 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -361,7 +361,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c, TRUE); + this->setCurveInsync (c); this->setCurveBeforeLPE(c); c->unref(); @@ -669,7 +669,7 @@ void SPOffset::set_shape() { SPCurve *c = new SPCurve(pv); g_assert(c != NULL); - this->setCurveInsync (c, TRUE); + this->setCurveInsync (c); this->setCurveBeforeLPE(c); c->unref(); diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp index a0c7f098d9..d6a06498cd 100644 --- a/src/object/sp-path.cpp +++ b/src/object/sp-path.cpp @@ -191,13 +191,14 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->set_original_curve(curve, TRUE, true); + this->setCurveBeforeLPE(curve); curve->unref(); } } else { - this->set_original_curve(NULL, TRUE, true); + this->setCurveBeforeLPE(NULL); + } - + sp_lpe_item_update_patheffect(this, true, true); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -207,11 +208,11 @@ void SPPath::set(unsigned int key, const gchar* value) { SPCurve *curve = new SPCurve(pv); if (curve) { - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); } } else { - this->setCurve(NULL, TRUE); + this->setCurve(NULL); } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -325,130 +326,6 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { return Geom::identity(); } - -void SPPath::update_patheffect(bool write) { - Inkscape::XML::Node *repr = this->getRepr(); - -#ifdef PATH_VERBOSE -g_message("sp_path_update_patheffect"); -#endif - - if (_curve_before_lpe && hasPathEffectRecursive()) { - SPCurve *curve = _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)*/ - this->setCurveInsync(curve, TRUE); - - bool success = this->performPathEffect(curve); - - if (success && write) { - // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. -#ifdef PATH_VERBOSE -g_message("sp_path_update_patheffect writes 'd' attribute"); -#endif - if (_curve) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } else if (!success) { - // LPE was unsuccessful. 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) { - this->setCurve(oldcurve, TRUE); - oldcurve->unref(); - } - } - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - curve->unref(); - } -} - - -/** - * Adds a original_curve to the path. If owner is specified, a reference - * will be made, otherwise the curve will be copied into the path. - * Any existing curve in the path will be unreferenced first. - * This routine triggers reapplication of an effect if present - * and also triggers a request to update the display. Does not write - * result to XML when write=false. - */ -void SPPath::set_original_curve (SPCurve *new_curve, unsigned int owner, bool write) -{ - if (_curve_before_lpe) { - _curve_before_lpe = _curve_before_lpe->unref(); - } - - if (new_curve) { - if (owner) { - _curve_before_lpe = new_curve->ref(); - } else { - _curve_before_lpe = new_curve->copy(); - } - } - - sp_lpe_item_update_patheffect(this, true, write); - requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -/** - * Return duplicate of _curve_before_lpe (if any exists) or NULL if there is no curve - */ -SPCurve * SPPath::get_original_curve () const -{ - if (_curve_before_lpe) { - return _curve_before_lpe->copy(); - } - - return NULL; -} - -/** - * 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 && hasPathEffectRecursive()) { - return get_original_curve(); - } else { - return getCurve(); - } -} - -/** - * 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 && hasPathEffectRecursive()) { - return _curve_before_lpe; - } else { - return _curve; - } -} - -/** - * Returns \c _curve_before_lpe if it is not NULL and a valid LPE is applied or \c curve if not. - * \todo should only be available to class friends! - */ -SPCurve* SPPath::get_curve () -{ - if (_curve_before_lpe && hasPathEffectRecursive()) { - return _curve_before_lpe; - } else { - return _curve; - } -} - /* Local Variables: mode:c++ diff --git a/src/object/sp-path.h b/src/object/sp-path.h index 572fd648d1..2d7ab4e94b 100644 --- a/src/object/sp-path.h +++ b/src/object/sp-path.h @@ -29,37 +29,24 @@ class SPCurve; */ class SPPath : public SPShape { public: - SPPath(); - virtual ~SPPath(); + SPPath(); + virtual ~SPPath(); int nodesInPath() const; - - // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. - void set_original_curve (SPCurve *curve, unsigned int owner, bool write); - SPCurve* get_original_curve () const; - SPCurve* get_curve_for_edit () const; - const SPCurve* get_curve_reference() const; - -public: // should be made protected - SPCurve* get_curve(); friend class SPConnEndPair; - -public: SPConnEndPair connEndPair; - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void release(); - virtual void update(SPCtx* ctx, unsigned int flags); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual void release(); + virtual void update(SPCtx* ctx, unsigned int flags); - virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); - virtual const char* displayName() const; - virtual char* description() const; - virtual Geom::Affine set_transform(Geom::Affine const &transform); + virtual const char* displayName() const; + virtual char* description() const; + virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; - - virtual void update_patheffect(bool write); }; #endif // SEEN_SP_PATH_H diff --git a/src/object/sp-polygon.cpp b/src/object/sp-polygon.cpp index 14fd104b33..b2a0c14808 100644 --- a/src/object/sp-polygon.cpp +++ b/src/object/sp-polygon.cpp @@ -157,7 +157,7 @@ void SPPolygon::set(unsigned int key, const gchar* value) { curve->closepath(); } - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); break; } diff --git a/src/object/sp-polyline.cpp b/src/object/sp-polyline.cpp index 29054f934a..3be4700eb8 100644 --- a/src/object/sp-polyline.cpp +++ b/src/object/sp-polyline.cpp @@ -91,7 +91,7 @@ void SPPolyLine::set(unsigned int key, const gchar* value) { } } - this->setCurve(curve, TRUE); + this->setCurve(curve); curve->unref(); break; } diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index 88dad5354f..f21dafd54f 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -198,8 +198,8 @@ const char* SPRect::displayName() const { void SPRect::set_shape() { if ((this->height.computed < 1e-18) || (this->width.computed < 1e-18)) { - this->setCurveInsync( NULL, TRUE); - this->setCurveBeforeLPE( NULL ); + this->setCurveInsync(NULL); + this->setCurveBeforeLPE(NULL); return; } @@ -265,7 +265,7 @@ void SPRect::set_shape() { } c->closepath(); - this->setCurveInsync(c, true); + this->setCurveInsync(c); this->setCurveBeforeLPE(c); // LPE is not applied because result can generally not be represented as SPRect diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 9edf03cbfc..07416650ea 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -37,7 +37,8 @@ #include "sp-path.h" #include "preferences.h" #include "attributes.h" - +#include "svg/svg.h" +#include "svg/path-string.h" #include "live_effects/lpeobject.h" #include "helper/mathfns.h" // for triangle_area() @@ -416,7 +417,7 @@ void SPShape::modified(unsigned int flags) { Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const { Geom::OptRect bbox; - if (!this->_curve) { + if (!this->_curve || this->_curve->get_pathvector().empty()) { return bbox; } @@ -738,6 +739,38 @@ void SPShape::print(SPPrintContext* ctx) { } } +void SPShape::update_patheffect(bool write) +{ + if (SPCurve *c_lpe = this->getCurveForEdit()) { + /* 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)*/ + this->setCurveInsync(c_lpe); + this->resetClipPathAndMaskLPE(); + bool success = false; + if (hasPathEffect() && pathEffectsEnabled()) { + success = this->performPathEffect(c_lpe, SP_SHAPE(this)); + if (success) { + this->setCurveInsync(c_lpe); + this->applyToClipPath(this); + this->applyToMask(this); + } + } + + if (write && success) { + Inkscape::XML::Node *repr = this->getRepr(); + if (c_lpe != NULL) { + gchar *str = sp_svg_write_path(c_lpe->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } + } + c_lpe->unref(); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); @@ -995,67 +1028,93 @@ void SPShape::setCurve(SPCurve *new_curve, unsigned int owner) this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } + /** * Sets _curve_before_lpe to refer to the curve. */ void -SPShape::setCurveBeforeLPE (SPCurve *new_curve) +SPShape::setCurveBeforeLPE(SPCurve *new_curve, unsigned int owner) { if (_curve_before_lpe) { _curve_before_lpe = _curve_before_lpe->unref(); } if (new_curve) { - _curve_before_lpe = new_curve->ref(); + if (owner) { + _curve_before_lpe = new_curve->ref(); + } else { + _curve_before_lpe = new_curve->copy(); + } } } /** - * Return duplicate of curve (if any exists) or NULL if there is no curve + * Same as sp_shape_set_curve but without updating the display */ -SPCurve * SPShape::getCurve() const +void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) { if (_curve) { - return _curve->copy(); + _curve = _curve->unref(); } - return NULL; + if (new_curve) { + if (owner) { + _curve = new_curve->ref(); + } else { + _curve = new_curve->copy(); + } + } } + /** - * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve + * Return curve (if any exists) or NULL if there is no curve +* if owner == 0 return a copy */ -SPCurve * SPShape::getCurveBeforeLPE() const +SPCurve * SPShape::getCurve(unsigned int owner) const { - if (hasPathEffectRecursive()) { - if (_curve_before_lpe) { - return this->_curve_before_lpe->copy(); - } - } else { - if (_curve) { - return _curve->copy(); + if (_curve) { + if(owner) { + return _curve; } + return _curve->copy(); } return NULL; } /** - * Same as sp_shape_set_curve but without updating the display + * Return curve *before* LPE (if any exists) or NULL if there is no curve + * If force is set allow return curve_before_lpe even if not + * has path effect like in clips and mask + * if owner == 0 return a copy */ -void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) +SPCurve * SPShape::getCurveBeforeLPE(unsigned int owner) const { - if (_curve) { - _curve = _curve->unref(); - } + if (_curve_before_lpe) { + if (owner) { + return _curve_before_lpe; + } + return _curve_before_lpe->copy(); + } + return NULL; +} - if (new_curve) { +/** + * Return curve for edit + * If force is set allow return curve_before_lpe even if not + * has path effect like in clips and mask + * if owner == 0 return a copy + */ +SPCurve * SPShape::getCurveForEdit(unsigned int owner) const +{ + if (_curve_before_lpe) { if (owner) { - _curve = new_curve->ref(); - } else { - _curve = new_curve->copy(); + return _curve_before_lpe; } + return _curve_before_lpe->copy(); } + return getCurve(owner); } void SPShape::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const { diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index fe9d032755..be097e390a 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -39,14 +39,16 @@ public: SPShape(); virtual ~SPShape(); - SPCurve * getCurve () const; - SPCurve * getCurveBeforeLPE () const; - void setCurve (SPCurve *curve, unsigned int owner); - void setCurveInsync (SPCurve *curve, unsigned int owner); - void setCurveBeforeLPE (SPCurve *curve); + SPCurve * getCurve (unsigned int owner = FALSE) const; + SPCurve * getCurveBeforeLPE (unsigned int owner = FALSE) const; + SPCurve * getCurveForEdit (unsigned int owner = FALSE) const; + void setCurve (SPCurve *curve, unsigned int owner = TRUE); + void setCurveBeforeLPE (SPCurve *new_curve, unsigned int owner = TRUE); + void setCurveInsync (SPCurve *curve, unsigned int owner = TRUE); int hasMarkers () const; int numberOfMarkers (int type) const; + public: // temporarily public, until SPPath is properly classed, etc. SPCurve *_curve_before_lpe; SPCurve *_curve; @@ -73,6 +75,7 @@ public: virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual void set_shape(); + virtual void update_patheffect(bool write); }; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index a84fc60412..7a449807df 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -196,24 +196,6 @@ void SPSpiral::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -void SPSpiral::update_patheffect(bool write) { - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); - - if ( this->_curve != NULL ) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - const char* SPSpiral::displayName() const { return _("Spiral"); } @@ -310,7 +292,7 @@ void SPSpiral::fitAndDraw(SPCurve* c, double dstep, Geom::Point darray[], Geom:: g_assert (is_unit_vector (hat2)); } -void SPSpiral::set_shape(bool force) { +void SPSpiral::set_shape() { if (hasBrokenPathEffect()) { 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"); @@ -318,7 +300,7 @@ void SPSpiral::set_shape(bool force) { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync( cold, TRUE); + this->setCurveInsync(cold); this->setCurveBeforeLPE( cold ); cold->unref(); } @@ -363,28 +345,22 @@ void SPSpiral::set_shape(bool force) { this->fitAndDraw(c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); } - /* Reset the shape'scurve to the "original_curve" + /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { - c->unref(); - return; + SPCurve * before = this->getCurveBeforeLPE(); + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } + } else { + this->setCurveInsync(c); } - setCurveInsync( c, TRUE); - setCurveBeforeLPE( c ); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); - - if (success) { - this->setCurveInsync( c_lpe, TRUE); - } - - c_lpe->unref(); + if (before) { + before->unref(); } - c->unref(); } diff --git a/src/object/sp-spiral.h b/src/object/sp-spiral.h index ebf4c9e280..138eae9149 100644 --- a/src/object/sp-spiral.h +++ b/src/object/sp-spiral.h @@ -70,8 +70,7 @@ public: virtual const char* displayName() const; virtual char* description() const; - virtual void set_shape(bool force = false); - virtual void update_patheffect(bool write); + virtual void set_shape(); private: Geom::Point getTangent(double t) const; diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 9844df98af..097b5d9893 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -223,23 +223,6 @@ void SPStar::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -void SPStar::update_patheffect(bool write) { - this->set_shape(true); - - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); - - if ( this->_curve != NULL ) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); - } - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} const char* SPStar::displayName() const { if (this->flatsided == false) @@ -364,7 +347,7 @@ sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ) #define NEXT false #define PREV true -void SPStar::set_shape(bool force) { +void SPStar::set_shape() { // perhaps we should convert all our shapes into LPEs without source path // and with knotholders for parameters, then this situation will be handled automatically // by disabling the entire stack (including the shape LPE) @@ -375,7 +358,7 @@ void SPStar::set_shape(bool force) { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync( cold, TRUE); + this->setCurveInsync(cold); this->setCurveBeforeLPE(cold); cold->unref(); } @@ -445,28 +428,22 @@ void SPStar::set_shape(bool force) { c->closepath(); - /* Reset the shape'scurve to the "original_curve" + /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - if(this->getCurveBeforeLPE()) { - if(!force && this->getCurveBeforeLPE()->get_pathvector() == c->get_pathvector()) { - c->unref(); - return; + SPCurve * before = this->getCurveBeforeLPE(); + if (before || this->hasPathEffectRecursive()) { + if (!before || before->get_pathvector() != c->get_pathvector()){ + this->setCurveBeforeLPE(c); + this->update_patheffect(false); + } else { + this->setCurveBeforeLPE(c); } + } else { + this->setCurveInsync(c); } - this->setCurveInsync( c, TRUE); - this->setCurveBeforeLPE( c ); - - if (hasPathEffect() && pathEffectsEnabled()) { - SPCurve *c_lpe = c->copy(); - bool success = this->performPathEffect(c_lpe); - - if (success) { - this->setCurveInsync( c_lpe, TRUE); - } - - c_lpe->unref(); + if (before) { + before->unref(); } - c->unref(); } diff --git a/src/object/sp-star.h b/src/object/sp-star.h index 4519de8694..86f3e8ef91 100644 --- a/src/object/sp-star.h +++ b/src/object/sp-star.h @@ -54,8 +54,7 @@ public: virtual char* description() const; virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; - virtual void update_patheffect(bool write); - virtual void set_shape(bool force = false); + virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const& xform); }; diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 2eb471bb39..7d5346f317 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -123,7 +123,7 @@ ObjectSet::combine(bool skip_undo) did = true; } - SPCurve *c = path->get_curve_for_edit(); + SPCurve *c = path->getCurveForEdit(); if (first == NULL) { // this is the topmost path first = item; parent = first->getRepr()->parent(); @@ -225,7 +225,7 @@ ObjectSet::breakApart(bool skip_undo) continue; } - SPCurve *curve = path->get_curve_for_edit(); + SPCurve *curve = path->getCurveForEdit(); if (curve == NULL) { continue; } @@ -650,7 +650,7 @@ ObjectSet::pathReverse() did = true; - SPCurve *rcurve = path->get_curve_reference()->create_reverse(); + SPCurve *rcurve = path->getCurveForEdit(true)->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index ae2f63f970..622a843e4c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -771,10 +771,6 @@ Inkscape::XML::Node* ObjectSet::group() { group->setPosition(topmost + 1); set(doc->getObjectByRepr(group)); - SPLPEItem *lpeitem = dynamic_cast(*(items().begin())); - if (lpeitem) { - sp_lpe_item_update_patheffect(lpeitem, true, true); - } DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); @@ -4155,9 +4151,14 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { for (auto& child: obj->children) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); - if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) - { + if (copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { copy->setAttribute("d", copy->attribute("inkscape:original-d")); + } else if (copy->attribute("inkscape:original-d")) { + copy->setAttribute("d", copy->attribute("inkscape:original-d")); + copy->setAttribute("inkscape:original-d", NULL); + } else if (!copy->attribute("inkscape:path-effect") && !SP_IS_PATH(&child)) { + copy->setAttribute("d", NULL); + copy->setAttribute("inkscape:original-d", NULL); } items_to_move.push_back(copy); } @@ -4204,7 +4205,6 @@ void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { // rebuild selection addList(items_to_select); - if (!skip_undo) { if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index cbb51f3122..1c0cc8cb13 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2538,7 +2538,7 @@ SPCurve* curve_for_item(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { if (SP_IS_PATH(item)) { - curve = SP_PATH(item)->get_curve_for_edit(); + curve = SP_PATH(item)->getCurveForEdit(); } else { curve = SP_SHAPE(item)->getCurve(); } @@ -2566,7 +2566,7 @@ SPCurve* curve_for_item_before_LPE(SPItem *item) SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { - curve = SP_SHAPE(item)->getCurveBeforeLPE(); + curve = SP_SHAPE(item)->getCurveForEdit(); } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { diff --git a/src/style-internal.h b/src/style-internal.h index 7a6c51a3bf..68b67531dd 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -872,7 +872,7 @@ public: } bool isNone() const { - return (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL) && !colorSet && !isPaintserver(); + return !colorSet && !isPaintserver() && (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL); } // TODO refine bool isColor() const { diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index ec8ae4f31b..6cf7f807a6 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -42,6 +42,7 @@ #include "object/sp-text.h" #include "ui/icon-names.h" +#include "ui/tools/node-tool.h" #include "ui/widget/imagetoggler.h" namespace Inkscape { @@ -205,42 +206,16 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect) lpe_changed = false; return; } - bool expanderopen = false; - Gtk::Widget * defaultswidget = effect.defaultParamSet(); - if (effectwidget) { - if (defaultswidget) { - Gtk::Expander * expander = NULL; - std::vector childs = dynamic_cast (effectwidget)->get_children(); - if (childs.size()) { - std::vector childs_default = dynamic_cast (childs[childs.size()-1])->get_children(); - if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ - expanderopen = expander->get_expanded(); - } - } - } effectcontrol_vbox.remove(*effectwidget); delete effectwidget; effectwidget = NULL; } - + effectwidget = effect.newWidget(); effectcontrol_frame.set_label(effect.getName()); + effectcontrol_vbox.pack_start(*effectwidget, true, true); - effectwidget = effect.newWidget(); - if (effectwidget) { - - if (defaultswidget) { - Gtk::Expander * expander = NULL; - std::vector childs_default = dynamic_cast (defaultswidget)->get_children(); - if ((expander = dynamic_cast(childs_default[childs_default.size()-1]))){ - expander->set_expanded(expanderopen); - } - dynamic_cast (effectwidget)->pack_start(*defaultswidget, true, true); - } - effectcontrol_vbox.pack_start(*effectwidget, true, true); - } button_remove.show(); - status_label.hide(); effectcontrol_frame.show(); effectcontrol_vbox.show_all_children(); @@ -254,7 +229,7 @@ LivePathEffectEditor::selectInList(LivePathEffect::Effect* effect) { Gtk::TreeNodeChildren chi = effectlist_view.get_model()->children(); for (Gtk::TreeIter ci = chi.begin() ; ci != chi.end(); ci++) { - if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect) + if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect && effectlist_view.get_selection()) effectlist_view.get_selection()->select(ci); } } @@ -580,6 +555,16 @@ void LivePathEffectEditor::on_effect_selection_changed() if (effect) { lpe_changed = true; showParams(*effect); + //To reload knots and helper paths + Inkscape::Selection *sel = _getSelection(); + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); + if (item) { + sel->clear(); + sel->add(item); + Inkscape::UI::Tools::sp_update_helperpath(); + } + } } } } diff --git a/src/ui/shape-editor-knotholders.cpp b/src/ui/shape-editor-knotholders.cpp index 5fb677f27a..885f3ef40d 100644 --- a/src/ui/shape-editor-knotholders.cpp +++ b/src/ui/shape-editor-knotholders.cpp @@ -107,13 +107,7 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) { KnotHolder *knotholder = NULL; - SPLPEItem *lpe = dynamic_cast(item); - if (lpe && - lpe->getCurrentLPE() && - lpe->getCurrentLPE()->isVisible() && - lpe->getCurrentLPE()->providesKnotholder()) { - knotholder = sp_lpe_knot_holder(lpe, desktop); - } else if (dynamic_cast(item)) { + if (dynamic_cast(item)) { knotholder = new RectKnotHolder(desktop, item, NULL); } else if (dynamic_cast(item)) { knotholder = new Box3DKnotHolder(desktop, item, NULL); @@ -139,6 +133,20 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) return knotholder; } +KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knotholder = NULL; + + SPLPEItem *lpe = dynamic_cast(item); + if (lpe && + lpe->getCurrentLPE() && + lpe->getCurrentLPE()->isVisible() && + lpe->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(lpe, desktop); + } + return knotholder; +} + } } // namespace Inkscape diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp index 3a5aec056d..b40bec86f7 100644 --- a/src/ui/shape-editor.cpp +++ b/src/ui/shape-editor.cpp @@ -29,13 +29,16 @@ namespace Inkscape { namespace UI { KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); +KnotHolder *createLPEKnotHolder(SPItem *item, SPDesktop *desktop); bool ShapeEditor::_blockSetItem = false; ShapeEditor::ShapeEditor(SPDesktop *dt, Geom::Affine edit_transform) : desktop(dt), knotholder(nullptr), + lpeknotholder(nullptr), knotholder_listener_attached_for(nullptr), + lpeknotholder_listener_attached_for(nullptr), _edit_transform(edit_transform) { } @@ -58,25 +61,43 @@ void ShapeEditor::unset_item(bool keep_knotholder) { this->knotholder = NULL; } } + if (this->lpeknotholder) { + Inkscape::XML::Node *old_repr = this->lpeknotholder->repr; + if (old_repr && old_repr == lpeknotholder_listener_attached_for) { + sp_repr_remove_listener_by_data(old_repr, this); + Inkscape::GC::release(old_repr); + lpeknotholder_listener_attached_for = NULL; + } + + if (!keep_knotholder) { + delete this->lpeknotholder; + this->lpeknotholder = NULL; + } + } } bool ShapeEditor::has_knotholder() { - return this->knotholder != NULL; + return this->knotholder != NULL || this->lpeknotholder != NULL; } void ShapeEditor::update_knotholder() { if (this->knotholder) this->knotholder->update_knots(); + if (this->lpeknotholder) + this->lpeknotholder->update_knots(); } bool ShapeEditor::has_local_change() { - return (this->knotholder && this->knotholder->local_change != 0); + return (this->knotholder && this->knotholder->local_change != 0) || (this->lpeknotholder && this->lpeknotholder->local_change != 0); } void ShapeEditor::decrement_local_change() { if (this->knotholder) { this->knotholder->local_change = FALSE; } + if (this->lpeknotholder) { + this->lpeknotholder->local_change = FALSE; + } } void ShapeEditor::event_attr_changed(Inkscape::XML::Node * node, gchar const *name, gchar const *, gchar const *, bool, void *data) @@ -123,6 +144,10 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { // only recreate knotholder if none is present this->knotholder = createKnotHolder(item, desktop); } + if (!this->lpeknotholder) { + // only recreate knotholder if none is present + this->lpeknotholder = createLPEKnotHolder(item, desktop); + } if (this->knotholder) { this->knotholder->setEditTransform(_edit_transform); this->knotholder->update_knots(); @@ -134,6 +159,17 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { knotholder_listener_attached_for = repr; } } + if (this->lpeknotholder) { + this->lpeknotholder->setEditTransform(_edit_transform); + this->lpeknotholder->update_knots(); + // setting new listener + repr = this->lpeknotholder->repr; + if (repr != lpeknotholder_listener_attached_for) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &shapeeditor_repr_events, this); + lpeknotholder_listener_attached_for = repr; + } + } } } @@ -145,6 +181,9 @@ void ShapeEditor::reset_item(bool keep_knotholder) if (knotholder) { SPObject *obj = desktop->getDocument()->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. set_item(SP_ITEM(obj), keep_knotholder); + } else if (lpeknotholder) { + SPObject *obj = desktop->getDocument()->getObjectByRepr(lpeknotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + set_item(SP_ITEM(obj), keep_knotholder); } } @@ -155,7 +194,9 @@ bool ShapeEditor::knot_mouseover() const { if (this->knotholder) { return knotholder->knot_mouseover(); } - + if (this->lpeknotholder) { + return lpeknotholder->knot_mouseover(); + } return false; } diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h index e30b2d60b9..67bce1c98d 100644 --- a/src/ui/shape-editor.h +++ b/src/ui/shape-editor.h @@ -36,6 +36,7 @@ public: bool knot_mouseover() const; KnotHolder *knotholder; + KnotHolder *lpeknotholder; bool has_knotholder(); static void blockSetItem(bool b) { _blockSetItem = b; } // kludge static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, @@ -46,6 +47,7 @@ private: SPDesktop *desktop; Inkscape::XML::Node *knotholder_listener_attached_for; + Inkscape::XML::Node *lpeknotholder_listener_attached_for; Geom::Affine _edit_transform; }; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 55e1714201..dcf0a4d4b7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -190,7 +190,7 @@ void PathManipulator::writeXML() { if (!_live_outline) _updateOutline(); - if (!_live_objects) + if (_live_objects) _setGeometry(); if (!_path) return; @@ -1152,6 +1152,9 @@ void PathManipulator::_createControlPointsFromGeometry() ++i; } } + if (pathv.empty()) { + return; + } _spcurve->set_pathvector(pathv); pathv *= (_edit_transform * _i2d_transform); @@ -1358,6 +1361,23 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } builder.flush(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); + for (Geom::PathVector::iterator i = pathv.begin(); i != pathv.end(); ) { + // NOTE: this utilizes the fact that Geom::PathVector is an std::vector. + // When we erase an element, the next one slides into position, + // so we do not increment the iterator even though it is theoretically invalidated. + if (i->empty()) { + i = pathv.erase(i); + } else { + ++i; + } + } + if (pathv.empty()) { + return; + } + + if (_spcurve->get_pathvector() == pathv) { + return; + } _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? @@ -1371,7 +1391,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } } } - if (_live_outline) _updateOutline(); if (_live_objects) @@ -1465,7 +1484,7 @@ void PathManipulator::_getGeometry() } } else { _spcurve->unref(); - _spcurve = _path->get_curve_for_edit(); + _spcurve = _path->getCurveForEdit(); // never allow NULL to sneak in here! if (_spcurve == NULL) { _spcurve = new SPCurve(); @@ -1477,7 +1496,6 @@ void PathManipulator::_getGeometry() void PathManipulator::_setGeometry() { using namespace Inkscape::LivePathEffect; - if (!_lpe_key.empty()) { // copied from nodepath.cpp // NOTE: if we are editing an LPE param, _path is not actually an SPPath, it is @@ -1485,17 +1503,22 @@ void PathManipulator::_setGeometry() Effect *lpe = LIVEPATHEFFECT(_path)->get_lpe(); if (lpe) { PathParam *pathparam = dynamic_cast(lpe->getParameter(_lpe_key.data())); + if (pathparam->get_pathvector() == _spcurve->get_pathvector()) { + return; //False we dont update LPE + } pathparam->set_new_value(_spcurve->get_pathvector(), false); LIVEPATHEFFECT(_path)->requestModified(SP_OBJECT_MODIFIED_FLAG); } } else { + // return true to leave the decission on empty to the caller. + // Maybe the path become empty and we want to update to empty if (empty()) return; - if (SPCurve * original = _path->get_original_curve()){ + if (SPCurve * original = _path->getCurveBeforeLPE()){ if(!_spcurve->is_equal(original)) { - _path->set_original_curve(_spcurve, false, false); + _path->setCurveBeforeLPE(_spcurve); delete original; } - } else if(!_spcurve->is_equal(_path->get_curve())) { + } else if(!_spcurve->is_equal(_path->getCurve(true))) { _path->setCurve(_spcurve, false); } } @@ -1658,7 +1681,6 @@ Geom::Coord PathManipulator::_updateDragPoint(Geom::Point const &evp) Geom::Affine to_desktop = _edit_transform * _i2d_transform; Geom::PathVector pv = _spcurve->get_pathvector(); - boost::optional pvp = pv.nearestTime(_desktop->w2d(evp) * to_desktop.inverse()); if (!pvp) return dist; diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index ec55ab80b2..20b309a98f 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -617,7 +617,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) Geom::Affine i2d ( (this->clickeditem)->i2dt_affine() ); Geom::Affine d2i = i2d.inverse(); SPPath *path = SP_PATH(this->clickeditem); - SPCurve *curve = path->get_curve(); + SPCurve *curve = path->getCurve(true); if (this->clickedhandle == this->endpt_handle[0]) { Geom::Point o = this->endpt_handle[1]->pos; curve->stretch_endpoints(p * d2i, o * d2i); @@ -628,7 +628,7 @@ bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) sp_conn_reroute_path_immediate(path); // Copy this to the temporary visible path - this->red_curve = path->get_curve_for_edit(); + this->red_curve = path->getCurveForEdit(); this->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve, true); @@ -1041,7 +1041,7 @@ static gboolean endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool * } // Show the red path for dragging. - cc->red_curve = SP_PATH(cc->clickeditem)->get_curve_for_edit(); + cc->red_curve = SP_PATH(cc->clickeditem)->getCurveForEdit(); Geom::Affine i2d = (cc->clickeditem)->i2dt_affine(); cc->red_curve->transform(i2d); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve, true); @@ -1135,7 +1135,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { g_assert( SP_IS_PATH(item) ); - const SPCurve *curve = SP_PATH(item)->get_curve_reference(); + const SPCurve *curve = SP_PATH(item)->getCurveForEdit(true); Geom::Affine i2dt = item->i2dt_affine(); if (this->active_conn == item) { @@ -1275,7 +1275,7 @@ static bool cc_item_is_shape(SPItem *item) bool cc_item_is_connector(SPItem *item) { if (SP_IS_PATH(item)) { - bool closed = SP_PATH(item)->get_curve_reference()->is_closed(); + bool closed = SP_PATH(item)->getCurveForEdit(true)->is_closed(); if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) { // To be considered a connector, an object must be a non-closed // path that is marked with a "inkscape:connector-type" attribute. diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 26d8123940..b57aa2fb03 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -645,7 +645,7 @@ static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/ // Curve list // We keep it in desktop coordinates to eliminate calculation errors - SPCurve *norm = SP_PATH(item)->get_curve_for_edit(); + SPCurve *norm = SP_PATH(item)->getCurveForEdit(); norm->transform((dc->white_item)->i2dt_affine()); g_return_if_fail( norm != NULL ); dc->white_curves = norm->split(); diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 6e586b0e99..d54adba89a 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -533,7 +533,7 @@ bool NodeTool::root_handler(GdkEvent* event) { } this->flashed_item = over_item; - SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE(); + SPCurve *c = SP_SHAPE(over_item)->getCurveForEdit(); if (!c) { break; // break out when curve doesn't exist diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index d317fa216e..3988ca544f 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -109,7 +109,7 @@ typedef enum { // code, those warnings are actually desired. They say "Hey! Fix this". We // definitely don't want to hide/ignore them. --JonCruz static const GtkTargetEntry ui_drop_target_entries [] = { - {"application/x-color", 0, APP_X_COLOR} + {g_strdup("application/x-color"), 0, APP_X_COLOR} }; static guint nui_drop_target_entries = G_N_ELEMENTS(ui_drop_target_entries); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index fb9afb8daa..d2939c7209 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -320,7 +320,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveBeforeLPE(); + SPCurve * c = shape->getCurveForEdit(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ @@ -328,7 +328,7 @@ static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c,0); + shape->setCurve(c, false); } break; } @@ -361,7 +361,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) if (dynamic_cast(lpe)) { SPShape * shape = dynamic_cast(lpeitem); if(shape){ - SPCurve * c = shape->getCurveBeforeLPE(); + SPCurve * c = shape->getCurveForEdit(); lpe->doEffect(c); lpeitem->setCurrentPathEffect(*i); if (lpelist.size() > 1){ @@ -369,7 +369,7 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) shape->setCurveBeforeLPE(c); } else { lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c,0); + shape->setCurve(c, false); } break; } -- GitLab