diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | src/live_effects/effect.cpp | 1 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerclip.cpp | 127 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerclip.h | 6 | ||||
| -rw-r--r-- | src/live_effects/lpe-powermask.cpp | 49 | ||||
| -rw-r--r-- | src/live_effects/lpe-powermask.h | 2 | ||||
| -rw-r--r-- | src/sp-item.cpp | 7 | ||||
| -rw-r--r-- | src/sp-path.cpp | 3 |
8 files changed, 148 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore index 619692120..279750420 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ share/palettes/palettes.h share/patterns/patterns.svg.h share/symbols/symbols.h share/templates/templates.h +doxygen_warnings.log +doxygen/ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d555c277b..c817f5caa 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -981,6 +981,7 @@ Effect::resetDefaults(SPItem const* /*item*/) } } +//Activate handle your transform filling your effect on SPPath.cpp void Effect::transform_multiply(Geom::Affine const& postmul, bool set) { diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index d33e05176..b83c50ea0 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -24,12 +24,15 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) : Effect(lpeobject), inverse(_("Inverse clip"), _("Inverse clip"), "inverse", &wr, this, false), flatten(_("Flatten clip"), _("Flatten clip, see fill rule once convert to paths"), "flatten", &wr, this, false), + //loock(_("Lock clip"), _("Lock clip"), "lock", &wr, this, false), //tooltip empty to no show in default param set is_inverse("Store the last inverse apply", "", "is_inverse", &wr, this, "false", false) { registerParameter(&inverse); registerParameter(&flatten); registerParameter(&is_inverse); + //registerParameter(&lock); + //lock.param_setValue(false); is_clip = false; hide_clip = false; convert_shapes = false; @@ -52,7 +55,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ clip_box.appendNew<Geom::LineSegment>(bottomleft); clip_box.close(); //clip_path *= sp_lpe_item->i2dt_affine(); - if(clip_path) { + if (clip_path) { is_clip = true; const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); std::vector<SPObject*> clip_path_list = clip_path->childList(true); @@ -98,13 +101,13 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ Inkscape::GC::release(clip_path_node); clip_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); } - if( 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(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true" && !inverse && isVisible()) { if (clip_to_path) { removeInverse(SP_ITEM(clip_to_path)); } else { @@ -119,39 +122,38 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ void LPEPowerClip::addInverse (SPItem * clip_data){ - if (SP_IS_GROUP(clip_data)) { - std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(clip_data)); - for ( std::vector<SPItem*>::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { - SPItem *subitem = *iter; - addInverse(subitem); - } - } else if (SP_IS_PATH(clip_data)) { - SPCurve * c = NULL; - c = SP_SHAPE(clip_data)->getCurve(); - if (c) { - Geom::PathVector c_pv = c->get_pathvector(); - if(c_pv.size() > 1 && is_inverse.param_getSVGValue() == (Glib::ustring)"true") { - c_pv.pop_back(); - } - //TODO: this can be not correct but no better way - bool dir_a = Geom::path_direction(c_pv[0]); - bool dir_b = Geom::path_direction(clip_box); - if (dir_a == dir_b) { - clip_box = clip_box.reversed(); + if(is_inverse.param_getSVGValue() == (Glib::ustring)"false") { + if (SP_IS_GROUP(clip_data)) { + std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(clip_data)); + for ( std::vector<SPItem*>::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + SPItem *subitem = *iter; + addInverse(subitem); } - c_pv.push_back(clip_box); - c->set_pathvector(c_pv); - SP_SHAPE(clip_data)->setCurve(c, TRUE); - c->unref(); - is_inverse.param_setValue((Glib::ustring)"true", true); - 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); + } else if (SP_IS_PATH(clip_data)) { + SPCurve * c = NULL; + 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 + bool dir_a = Geom::path_direction(c_pv[0]); + bool dir_b = Geom::path_direction(clip_box); + if (dir_a == dir_b) { + clip_box = clip_box.reversed(); + } + c_pv.push_back(clip_box); + c->set_pathvector(c_pv); + SP_SHAPE(clip_data)->setCurve(c, TRUE); + c->unref(); + is_inverse.param_setValue((Glib::ustring)"true", true); + 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); + } } } } @@ -160,6 +162,11 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } void +LPEPowerClip::doEffect (SPCurve * curve) +{ +} + +void LPEPowerClip::removeInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { if (SP_IS_GROUP(clip_data)) { @@ -258,19 +265,18 @@ LPEPowerClip::newWidget() } } } - ++it; } Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); Gtk::Button * toggle_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Toggle clip visibiliy")))); toggle_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEPowerClip::toggleClip)); - toggle_button->set_size_request(140,30); + toggle_button->set_size_request(180,30); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*toggle_button, false, false,2); Gtk::HBox * hbox2 = 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(200,30); + topaths_button->set_size_request(220,30); vbox->pack_start(*hbox2, true,true,2); hbox2->pack_start(*topaths_button, false, false,2); return dynamic_cast<Gtk::Widget *>(vbox); @@ -288,7 +294,6 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) SPObject * clip_data = *iter; if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { removeInverse(SP_ITEM(clip_data)); - is_inverse.param_setValue((Glib::ustring)"false"); } } } @@ -316,6 +321,50 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ return path_out; } +//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 (is_clip && lock) { +// std::vector<SPObject*> 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<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) { +// SPItem * clip_data = SP_ITEM(*iter); +// if(inverse && is_clip && 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 && is_clip && lock) { +// doBeforeEffect(sp_lpe_item); +// } +// } +// } +// //cycle through all parameters. Most parameters will not need transformation, but path and point params +// for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { +// Parameter * param = *it; +// param->param_transform_multiply(postmul, set); +// } +// toggleClip(); +// toggleClip(); +//} + void LPEPowerClip::flattenClip(SPItem * clip_data, Geom::PathVector &path_in) { diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index e70ec2c9c..adaa8b7a1 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -20,9 +20,11 @@ public: virtual ~LPEPowerClip(); virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); - //virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); + virtual void doEffect (SPCurve * curve); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); + //virtual void transform_multiply(Geom::Affine const& postmul, bool set); + void toggleClip(); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); @@ -31,8 +33,10 @@ public: private: BoolParam inverse; BoolParam flatten; + // BoolParam lock; HiddenParam is_inverse; Geom::Path clip_box; + Geom::Affine base; bool is_clip; bool convert_shapes; bool hide_clip; diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index decfa842d..434ad6dd4 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -26,15 +26,18 @@ namespace LivePathEffect { LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) : Effect(lpeobject), invert(_("Invert mask"), _("Invert mask"), "invert", &wr, this, false), - wrap(_("Wrap clip data"), _("Wrap clip data allowing previous filters"), "wrap", &wr, this, false), + wrap(_("Wrap mask data"), _("Wrap mask data allowing previous filters"), "wrap", &wr, this, false), background(_("Add background to mask"), _("Add background to mask"), "background", &wr, this, false), + //lock(_("Lock mask"), _("Lock mask"), "lock", &wr, this, false), background_style(_("Background Style"), _("CSS to background"), "background_style", &wr, this,"fill:#ffffff;opacity:1;") { registerParameter(&invert); registerParameter(&wrap); + //registerParameter(&lock); registerParameter(&background); registerParameter(&background_style); + //lock.param_setValue(false); background_style.param_hide_canvas_text(); hide_mask = false; } @@ -190,15 +193,23 @@ LPEPowerMask::setMask(){ elemref->deleteObject(true); } if (background && is_visible) { - box = xml_doc->createElement("svg:path"); - box->setAttribute("id", box_id.c_str()); + bool exist = true; + if (!(elemref = document->getObjectById(box_id))) { + box = xml_doc->createElement("svg:path"); + box->setAttribute("id", box_id.c_str()); + exist = false; + } box->setAttribute("style", background_style.param_getSVGValue()); gchar * box_str = sp_svg_write_path( mask_box ); box->setAttribute("d" , box_str); g_free(box_str); - elemref = mask->appendChildRepr(box); + if (!exist) { + elemref = mask->appendChildRepr(box); + Inkscape::GC::release(box); + } box->setPosition(1); - Inkscape::GC::release(box); + } else if ((elemref = document->getObjectById(box_id))) { + elemref->deleteObject(true); } mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -235,6 +246,7 @@ LPEPowerMask::toggleMask() { Inkscape::DrawingItem *ai = mask->sp_mask_show( v->arenaitem->drawing(), v->arenaitem->key()); + bbox.unionWith(ai->geometricBounds()); v->arenaitem->setMask(ai); mask->sp_mask_set_bbox(v->arenaitem->key(), bbox); } @@ -244,6 +256,33 @@ LPEPowerMask::toggleMask() { } } +//void +//LPEPowerMask::transform_multiply(Geom::Affine const& postmul, bool set) +//{ +// SPMask *mask_path = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); +// if (mask_path && lock) { +// SPMask *mask_path = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); +// std::vector<SPObject*> mask_path_list = mask_path->childList(true); +// Glib::ustring mask_id = (Glib::ustring)mask_path->getId(); +// Glib::ustring box_id = mask_id + (Glib::ustring)"_box"; +// for ( std::vector<SPObject*>::const_iterator iter=mask_path_list.begin();iter!=mask_path_list.end();++iter) { +// SPObject * mask_data = *iter; +// if (! strcmp(mask_data->getId(), box_id.c_str())){ +// continue; +// } +// SP_ITEM(mask_data)->transform *= postmul.inverse(); +// } +// } +// //cycle through all parameters. Most parameters will not need transformation, but path and point params +// for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { +// Parameter * param = *it; +// param->param_transform_multiply(postmul, set); +// } +// sp_lpe_item_update_patheffect(SP_LPE_ITEM(sp_lpe_item), false, false); +//} + + + Gtk::Widget * LPEPowerMask::newWidget() { diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index ce6166a72..cd36b3b37 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -23,12 +23,14 @@ public: virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); + //virtual void transform_multiply(Geom::Affine const& postmul, bool set); void toggleMask(); void setMask(); private: BoolParam invert; BoolParam wrap; BoolParam background; + //BoolParam lock; TextParam background_style; Geom::Path mask_box; bool hide_mask; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 368f8896c..4f3c7d283 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1373,7 +1373,7 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af // Within text, we do not fork gradients, and so must not recurse to avoid double compensation; // also we do not recurse into clones, because a clone's child is the ghost of its original - // we must not touch it - if (!(this && (dynamic_cast<SPText *>(this) || dynamic_cast<SPUse *>(this)))) { + if (!(dynamic_cast<SPText *>(this) || dynamic_cast<SPUse *>(this))) { for (auto& o: children) { SPItem *item = dynamic_cast<SPItem *>(&o); if (item) { @@ -1401,7 +1401,6 @@ void SPItem::adjust_livepatheffect (Geom::Affine const &postmul, bool set) SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(this); if ( lpeitem && lpeitem->hasPathEffect() ) { lpeitem->forkPathEffectsIfNecessary(); - // now that all LPEs are forked_if_necessary, we can apply the transform PathEffectList effect_list = lpeitem->getEffectList(); for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); ++it) @@ -1496,6 +1495,10 @@ void SPItem::doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &tra freeze_stroke_width_recursive(false); } } else { + SPLPEItem * lpeitem = SP_LPE_ITEM(this); + if (lpeitem && lpeitem->hasPathEffectRecursive()) { + lpeitem->adjust_livepatheffect(transform_attr); + } if (freeze_stroke_width) { freeze_stroke_width_recursive(false); if (compensate) { diff --git a/src/sp-path.cpp b/src/sp-path.cpp index c6ec5559e..bb76eb73f 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -289,7 +289,6 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { if (!_curve) { // 0 nodes, nothing to transform return Geom::identity(); } - // Transform the original-d path if this is a valid LPE this, other else the (ordinary) path if (_curve_before_lpe && hasPathEffectRecursive()) { if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || @@ -297,7 +296,7 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) { this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_MANY) || this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_STROKES) ) { - // if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' + // if path has this LPE applied, don't write the transform to the pathdata, but write it 'unoptimized' // also if the effect is type BEND PATH to fix bug #179842 this->adjust_livepatheffect(transform); return transform; |
