summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxof <jabier.arraiza@marker.es>2018-09-13 12:03:07 +0000
committerJabiertxof <jabier.arraiza@marker.es>2018-09-13 12:03:07 +0000
commitd7142b6c3a90b7606150dc65f658a6953a6006d9 (patch)
tree480ce011b2e549c80b1c66afbeebed9ced611f77 /src
parentFix horizontal scrolling direction when using smooth scrolling (diff)
downloadinkscape-d7142b6c3a90b7606150dc65f658a6953a6006d9.tar.gz
inkscape-d7142b6c3a90b7606150dc65f658a6953a6006d9.zip
fixes and improvementes to power clip and powermask
Diffstat (limited to 'src')
-rw-r--r--src/extension/internal/cairo-renderer.cpp15
-rw-r--r--src/live_effects/lpe-powerclip.cpp396
-rw-r--r--src/live_effects/lpe-powerclip.h9
-rw-r--r--src/live_effects/lpe-powermask.cpp35
-rw-r--r--src/live_effects/lpe-powermask.h1
-rw-r--r--src/object/sp-clippath.cpp9
-rw-r--r--src/object/sp-clippath.h18
-rw-r--r--src/object/sp-ellipse.cpp1
-rw-r--r--src/object/sp-item.cpp2
-rw-r--r--src/object/sp-item.h2
-rw-r--r--src/object/sp-lpe-item.cpp45
-rw-r--r--src/object/sp-mask.cpp7
-rw-r--r--src/object/sp-mask.h9
-rw-r--r--src/object/sp-path.cpp1
-rw-r--r--src/object/sp-spiral.cpp1
-rw-r--r--src/object/sp-star.cpp1
-rw-r--r--src/verbs.cpp2
17 files changed, 274 insertions, 280 deletions
diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp
index 32f42c3ce..83cb58e43 100644
--- a/src/extension/internal/cairo-renderer.cpp
+++ b/src/extension/internal/cairo-renderer.cpp
@@ -81,21 +81,6 @@
//#define TEST(_args) _args
#define TEST(_args)
-// FIXME: expose these from sp-clippath/mask.cpp
-struct SPClipPathView {
- SPClipPathView *next;
- unsigned int key;
- Inkscape::DrawingItem *arenaitem;
- Geom::OptRect bbox;
-};
-
-struct SPMaskView {
- SPMaskView *next;
- unsigned int key;
- Inkscape::DrawingItem *arenaitem;
- Geom::OptRect bbox;
-};
-
namespace Inkscape {
namespace Extension {
namespace Internal {
diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp
index 9e5da13cd..f4fb15dae 100644
--- a/src/live_effects/lpe-powerclip.cpp
+++ b/src/live_effects/lpe-powerclip.cpp
@@ -2,6 +2,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "live_effects/lpe-powerclip.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/lpeobject-reference.h"
#include <2geom/path-intersection.h>
#include <2geom/intersection-graph.h>
#include "display/curve.h"
@@ -14,6 +16,7 @@
#include "object/sp-clippath.h"
#include "object/sp-path.h"
#include "object/sp-shape.h"
+#include "object/sp-item.h"
#include "object/sp-item-group.h"
#include "object/uri.h"
@@ -39,7 +42,6 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject)
registerParameter(&is_inverse);
registerParameter(&message);
message.param_set_min_height(55);
- convert_shapes = false;
}
LPEPowerClip::~LPEPowerClip() = default;
@@ -90,85 +92,26 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){
clip_box.appendNew<Geom::LineSegment>(bottomright);
clip_box.appendNew<Geom::LineSegment>(bottomleft);
clip_box.close();
- //clip_box *= sp_lpe_item->i2dt_affine();
+
std::vector<SPObject*> clip_path_list = clip_path->childList(true);
for ( std::vector<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) {
SPObject * clip_data = *iter;
- SPObject * clip_to_path = nullptr;
- 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();
- SP_SHAPE(clip_data)->removeAllPathEffects(true);
- 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 = nullptr;
- 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);
- c->unref();
- }
-
- clip_path_node->setAttribute("transform", nullptr);
-
- 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);
- }
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(!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_str == (Glib::ustring)"true"){
- removeInverse(SP_ITEM(clip_data));
+ SPCurve * clipcurve = new SPCurve();
+ addInverse(SP_ITEM(clip_data), clipcurve, true);
+ } else if((!strcmp(is_inverse_str,"true") && !inverse && isVisible()) ||
+ (inverse && !is_visible && is_inverse_str == (Glib::ustring)"true"))
+ {
+ removeInverse(SP_ITEM(clip_data));
+ } else if(inverse && isVisible()) {
+ updateInverse(SP_ITEM(clip_data));
}
g_free(is_inverse_str);
}
+ } else if(!hide_clip) {
+ SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
+ item->removeCurrentPathEffect(false);
}
}
@@ -180,16 +123,35 @@ LPEPowerClip::doAfterEffect (SPLPEItem const* lpeitem){
}
void
-LPEPowerClip::addInverse (SPItem * clip_data){
+LPEPowerClip::addInverse (SPItem * clip_data, SPCurve * clipcurve, bool root){
gchar * is_inverse_str = is_inverse.param_getSVGValue();
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return;
+ }
+ SPObject *elemref = NULL;
+ if(root) {
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
+ SP_SHAPE(clip_data)->removeAllPathEffects(true);
+ Inkscape::XML::Node *clip_path_node = xml_doc->createElement("svg:path");
+ Inkscape::XML::Node *parent = clip_data->getRepr()->parent();
+ parent->appendChild(clip_path_node);
+ elemref = document->getObjectByRepr(clip_path_node);
+ elemref->setAttribute("style","fill-rule:evenodd");
+ elemref->setAttribute("id", (Glib::ustring("lpe_") + Glib::ustring(this->getLPEObj()->getId())).c_str());
+ }
if(!strcmp(is_inverse_str,"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);
+ addInverse(subitem, clipcurve, false);
+ if (root) {
+ Geom::Affine affine = SP_ITEM(clip_data)->transform;
+ clip_box *= affine;
+ }
}
- } else if (SP_IS_PATH(clip_data)) {
+ } else if (SP_IS_SHAPE(clip_data)) {
SPCurve * c = nullptr;
c = SP_SHAPE(clip_data)->getCurve();
if (c) {
@@ -200,33 +162,74 @@ LPEPowerClip::addInverse (SPItem * clip_data){
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);
- c->unref();
+ clipcurve->append(c, false);
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)) {
- Inkscape::Selection * sel = SP_ACTIVE_DESKTOP->getSelection();
- SPItem * item = sel->singleItem();
- if (item != nullptr) {
- sel->remove(item);
- sel->add(item);
- }
+ c->reset();
+ delete c;
+ }
+ Geom::Affine hidetrans = (Geom::Affine)Geom::Translate(0,999999);
+ SP_ITEM(clip_data)->doWriteTransform(hidetrans);
+ }
+ }
+ if(root) {
+ SPCurve * container = new SPCurve;
+ container->set_pathvector(clip_box);
+ clipcurve->append(container, false);
+ SP_SHAPE(elemref)->setCurve(clipcurve);
+ container->reset();
+ delete container;
+ }
+ g_free(is_inverse_str);
+}
+
+void
+LPEPowerClip::updateInverse (SPItem * clip_data) {
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return;
+ }
+ if(inverse && isVisible()) {
+ 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;
+ updateInverse(subitem);
+ }
+ } else if (SP_IS_SHAPE(clip_data)) {
+ SPObject *elemref = nullptr;
+ if (elemref = document->getObjectById(Glib::ustring("lpe_") + Glib::ustring(this->getLPEObj()->getId()))) {
+ SPCurve * c = nullptr;
+ c = SP_SHAPE(elemref)->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();
}
+ if(c_pv.size() > 1) {
+ c_pv.pop_back();
+ }
+ c_pv.push_back(clip_box);
+ c->set_pathvector(c_pv);
+ SP_SHAPE(elemref)->setCurve(c);
+ c->unref();
}
}
}
}
- g_free(is_inverse_str);
}
void
LPEPowerClip::removeInverse (SPItem * clip_data){
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return;
+ }
gchar * is_inverse_str = is_inverse.param_getSVGValue();
if(!strcmp(is_inverse_str,"true")) {
if (SP_IS_GROUP(clip_data)) {
@@ -235,90 +238,28 @@ LPEPowerClip::removeInverse (SPItem * clip_data){
SPItem *subitem = *iter;
removeInverse(subitem);
}
- } else if (SP_IS_PATH(clip_data)) {
- SPCurve * c = nullptr;
- 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);
- SP_SHAPE(clip_data)->setCurve(c);
- 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);
- }
- 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 != nullptr) {
- sel->remove(item);
- sel->add(item);
- }
- }
- }
+ } else if (SP_IS_SHAPE(clip_data)) {
+ Geom::Affine unhidetrans = (Geom::Affine)Geom::Translate(0,-999999);
+ SP_ITEM(clip_data)->doWriteTransform(unhidetrans);
+ gchar * is_inverse_str = is_inverse.param_getSVGValue();
+ if (strcmp(is_inverse_str, "false") != 0) {
+ is_inverse.param_setValue((Glib::ustring)"false", true);
}
}
+ SPObject *elemref = nullptr;
+ if (elemref = document->getObjectById(Glib::ustring("lpe_") + Glib::ustring(this->getLPEObj()->getId()))) {
+ elemref ->deleteObject(false);
+ }
}
g_free(is_inverse_str);
}
-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<Parameter *>::iterator it = param_vector.begin();
- while (it != param_vector.end()) {
- if ((*it)->widget_is_visible) {
- Parameter * param = *it;
- Gtk::Widget * widg = dynamic_cast<Gtk::Widget *>(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);
- if(Gtk::Widget* widg = defaultParamSet()) {
- vbox->pack_start(*widg, true, true, 2);
- }
- return dynamic_cast<Gtk::Widget *>(vbox);
-}
-
void
LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/)
{
SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject();
- if(!keep_paths) {
- if(clip_path) {
+ if(clip_path) {
+ if(!keep_paths) {
gchar * is_inverse_str = is_inverse.param_getSVGValue();
std::vector<SPObject*> clip_path_list = clip_path->childList(true);
for ( std::vector<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) {
@@ -328,9 +269,8 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/)
}
}
g_free(is_inverse_str);
- }
- } else {
- if (flatten && clip_path) {
+
+ } else if (flatten) {
clip_path->deleteObject();
}
}
@@ -338,16 +278,37 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/)
Geom::PathVector
LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){
- Geom::PathVector path_out = pathv_to_linear_and_cubic_beziers(path_in);
+ Geom::PathVector path_out = path_in;
+ SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject();
if (!hide_clip && flatten && isVisible()) {
- SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject();
- if(clip_path) {
- std::vector<SPObject*> clip_path_list = clip_path->childList(true);
- for ( std::vector<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) {
- SPObject * clip_data = *iter;
- flattenClip(SP_ITEM(clip_data), path_out);
+ path_out *= sp_item_transform_repr (sp_lpe_item).inverse();
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return path_out;
+ }
+ SPObject *elemref = nullptr;
+ if (elemref = document->getObjectById(Glib::ustring("lpe_") + Glib::ustring(this->getLPEObj()->getId()))) {
+ SPCurve * c = nullptr;
+ c = SP_SHAPE(elemref)->getCurve();
+ if (c) {
+ Geom::PathVector c_pv = c->get_pathvector();
+ c_pv *= sp_item_transform_repr (sp_lpe_item).inverse();
+ Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(c_pv, path_out);
+ if (pig && !c_pv.empty() && !path_in.empty()) {
+ path_out = pig->getIntersection();
+ }
+ c->unref();
+ }
+ } else {
+ if(clip_path) {
+ std::vector<SPObject*> clip_path_list = clip_path->childList(true);
+ for ( std::vector<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) {
+ SPObject * clip_data = *iter;
+ flattenClip(SP_ITEM(clip_data), path_out);
+ }
}
}
+ path_out *= sp_item_transform_repr (sp_lpe_item);
}
return path_out;
}
@@ -358,65 +319,22 @@ LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem)
doBeforeEffect(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<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 && 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<Parameter *>::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)
{
+ SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject();
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;
- flattenClip(subitem, path_in);
- }
- } else if (SP_IS_PATH(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;
+ flattenClip(subitem, path_in);
+ }
+ } else if (SP_IS_SHAPE(clip_data)) {
SPCurve * c = nullptr;
c = SP_SHAPE(clip_data)->getCurve();
if (c) {
Geom::PathVector c_pv = c->get_pathvector();
+ c_pv *= sp_item_transform_repr (sp_lpe_item).inverse();
Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(c_pv, path_in);
if (pig && !c_pv.empty() && !path_in.empty()) {
path_in = pig->getIntersection();
@@ -439,7 +357,35 @@ 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<LPEPowerClip *>(lpe)->convertShapes();
+ }
+ }
+ }
+}
+
+void sp_remove_powerclip(Inkscape::Selection *sel) {
+ if (!sel->isEmpty()) {
+ auto selList = sel->items();
+ for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) {
+ SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*i);
+ if (lpeitem) {
+ if (lpeitem->hasPathEffect() && lpeitem->pathEffectsEnabled()) {
+ for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->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;
+ }
+ Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe();
+ if (lpe->getName() == "powerclip") {
+ lpe->doOnRemove(lpeitem);
+ break;
+ }
+ }
+ }
}
}
}
diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h
index 2cd3943cc..6e95ab4ab 100644
--- a/src/live_effects/lpe-powerclip.h
+++ b/src/live_effects/lpe-powerclip.h
@@ -21,14 +21,12 @@ public:
void doBeforeEffect (SPLPEItem const* lpeitem) override;
Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override;
void doOnRemove (SPLPEItem const* /*lpeitem*/) override;
- Gtk::Widget * newWidget() override;
- //virtual void transform_multiply(Geom::Affine const& postmul, bool set);
void doOnVisibilityToggled(SPLPEItem const* lpeitem) override;
void doAfterEffect (SPLPEItem const* lpeitem) override;
- void addInverse (SPItem * clip_data);
+ void addInverse (SPItem * clip_data, SPCurve * clipcurve, bool root);
+ void updateInverse (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;
@@ -38,9 +36,10 @@ private:
MessageParam message;
Geom::Path clip_box;
Geom::Affine base;
- bool convert_shapes;
+ Geom::Affine lastapplyed;
};
+void sp_remove_powerclip(Inkscape::Selection *sel);
void sp_inverse_powerclip(Inkscape::Selection *sel);
} //namespace LivePathEffect
diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp
index 72cb75dab..54168fdb5 100644
--- a/src/live_effects/lpe-powermask.cpp
+++ b/src/live_effects/lpe-powermask.cpp
@@ -2,6 +2,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "live_effects/lpe-powermask.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/lpeobject-reference.h"
#include <2geom/path-intersection.h>
#include <2geom/intersection-graph.h>
#include "display/curve.h"
@@ -101,6 +103,9 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){
mask_box.close();
setMask();
}
+ } else if(!hide_mask) {
+ SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
+ item->removeCurrentPathEffect(false);
}
g_free(uri_str);
}
@@ -326,6 +331,36 @@ void sp_inverse_powermask(Inkscape::Selection *sel) {
}
}
+
+void sp_remove_powermask(Inkscape::Selection *sel) {
+ if (!sel->isEmpty()) {
+ auto selList = sel->items();
+ for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) {
+ SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*i);
+ if (lpeitem) {
+ if (lpeitem->hasPathEffect() && lpeitem->pathEffectsEnabled()) {
+ for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->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;
+ }
+ Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe();
+ if (lpe->getName() == "powermask") {
+ lpe->doOnRemove(lpeitem);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
}; //namespace LivePathEffect
}; /* namespace Inkscape */
diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h
index ecf448e53..397356614 100644
--- a/src/live_effects/lpe-powermask.h
+++ b/src/live_effects/lpe-powermask.h
@@ -36,6 +36,7 @@ private:
guint32 previous_color;
};
+void sp_remove_powermask(Inkscape::Selection *sel);
void sp_inverse_powermask(Inkscape::Selection *sel);
} //namespace LivePathEffect
diff --git a/src/object/sp-clippath.cpp b/src/object/sp-clippath.cpp
index 321f6a80f..f06ac2c11 100644
--- a/src/object/sp-clippath.cpp
+++ b/src/object/sp-clippath.cpp
@@ -15,8 +15,6 @@
#include <cstring>
#include <string>
-#include "display/drawing.h"
-#include "display/drawing-group.h"
#include "xml/repr.h"
#include "enums.h"
@@ -31,13 +29,6 @@
#include "sp-item.h"
#include "sp-defs.h"
-struct SPClipPathView {
- SPClipPathView *next;
- unsigned int key;
- Inkscape::DrawingItem *arenaitem;
- Geom::OptRect bbox;
-};
-
static SPClipPathView* sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::DrawingItem *arenaitem);
static SPClipPathView* sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view);
diff --git a/src/object/sp-clippath.h b/src/object/sp-clippath.h
index 57c3cf855..2c07fe5d1 100644
--- a/src/object/sp-clippath.h
+++ b/src/object/sp-clippath.h
@@ -15,16 +15,16 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#define SP_CLIPPATH(obj) (dynamic_cast<SPClipPath*>((SPObject*)obj))
-#define SP_IS_CLIPPATH(obj) (dynamic_cast<const SPClipPath*>((SPObject*)obj) != NULL)
-
-struct SPClipPathView;
-
#include <cstdio>
#include "sp-object-group.h"
+#include "display/drawing.h"
+#include "display/drawing-group.h"
#include "uri-references.h"
#include "xml/node.h"
+#define SP_CLIPPATH(obj) (dynamic_cast<SPClipPath*>((SPObject*)obj))
+#define SP_IS_CLIPPATH(obj) (dynamic_cast<const SPClipPath*>((SPObject*)obj) != NULL)
+
namespace Inkscape {
class Drawing;
@@ -32,6 +32,14 @@ class DrawingItem;
} // namespace Inkscape
+
+struct SPClipPathView {
+ SPClipPathView *next;
+ unsigned int key;
+ Inkscape::DrawingItem *arenaitem;
+ Geom::OptRect bbox;
+};
+
class SPClipPath : public SPObjectGroup {
public:
SPClipPath();
diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp
index 97ad7f74c..723c28625 100644
--- a/src/object/sp-ellipse.cpp
+++ b/src/object/sp-ellipse.cpp
@@ -501,6 +501,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
if (hasPathEffect() && pathEffectsEnabled() &&
(this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH) ||
+ this->hasPathEffectOfType(Inkscape::LivePathEffect::POWERCLIP) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_MANY) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_STROKES) ) )
{
diff --git a/src/object/sp-item.cpp b/src/object/sp-item.cpp
index e6f4c4239..0a8af14dc 100644
--- a/src/object/sp-item.cpp
+++ b/src/object/sp-item.cpp
@@ -1321,7 +1321,7 @@ void SPItem::adjust_stroke( gdouble ex )
/**
* Find out the inverse of previous transform of an item (from its repr)
*/
-static Geom::Affine sp_item_transform_repr (SPItem *item)
+Geom::Affine sp_item_transform_repr (SPItem *item)
{
Geom::Affine t_old(Geom::identity());
gchar const *t_attr = item->getRepr()->attribute("transform");
diff --git a/src/object/sp-item.h b/src/object/sp-item.h
index f6a6781e9..acdde5d56 100644
--- a/src/object/sp-item.h
+++ b/src/object/sp-item.h
@@ -418,6 +418,8 @@ Geom::Affine i2anc_affine(SPObject const *item, SPObject const *ancestor);
Geom::Affine i2i_affine(SPObject const *src, SPObject const *dest);
+Geom::Affine sp_item_transform_repr (SPItem *item);
+
/* fixme: - these are evil, but OK */
int sp_item_repr_compare_position(SPItem const *first, SPItem const *second);
diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp
index 37b2c11e8..d6eaf7b6e 100644
--- a/src/object/sp-lpe-item.cpp
+++ b/src/object/sp-lpe-item.cpp
@@ -201,6 +201,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip
}
if (this->hasPathEffect() && this->pathEffectsEnabled()) {
+ size_t path_effect_list_size = this->path_effect_list->size();
for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it)
{
LivePathEffectObject *lpeobj = (*it)->lpeobject;
@@ -211,10 +212,14 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip
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 (!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) {
return false;
}
+ if (path_effect_list_size != this->path_effect_list->size()) {
+ break;
+ }
}
}
return true;
@@ -462,6 +467,17 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths,
gchar *title = shape->title();
// remember description
gchar *desc = shape->desc();
+ // remember transformation
+ gchar const *transform_str = shape->getRepr()->attribute("transform");
+ // Mask
+ gchar const *mask_str = (gchar *) shape->getRepr()->attribute("mask");
+ // Clip path
+ gchar const *clip_str = (gchar *) shape->getRepr()->attribute("clip-path");
+
+ /* Rotation center */
+ gchar const *transform_center_x = shape->getRepr()->attribute("inkscape:transform-center-x");
+ gchar const *transform_center_y = shape->getRepr()->attribute("inkscape:transform-center-y");
+
// remember highlight color
guint32 highlight_color = 0;
if (shape->isHighlightSet())
@@ -476,6 +492,16 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths,
repr->setAttribute("id", id);
// restore class
repr->setAttribute("class", class_attr);
+ // restore transform
+ repr->setAttribute("transform", transform_str);
+ // restore clip
+ repr->setAttribute("clip-path", clip_str);
+ // restore mask
+ repr->setAttribute("mask", mask_str);
+ // restore transform_center_x
+ repr->setAttribute("inkscape:transform-center-x", transform_center_x);
+ // restore transform_center_y
+ repr->setAttribute("inkscape:transform-center-y", transform_center_y);
//restore d
repr->setAttribute("d", d_str);
//restore style
@@ -589,9 +615,9 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths)
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));
+ this->path_effect_list->remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list
+ std::cout << this->path_effect_list->size() << "this->path_effect_list11111" << std::endl;
+ this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list));
if (!keep_paths) {
// Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible.
if( SP_IS_GENERICELLIPSE(this)) {
@@ -612,9 +638,8 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths)
return;
}
}
- PathEffectList new_list = *this->path_effect_list;
std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i;
- for (i = new_list.begin(); i != new_list.end(); ++i) {
+ for (i = this->path_effect_list->begin(); i != this->path_effect_list->end(); ++i) {
Inkscape::LivePathEffect::LPEObjectReference *lperef = (*i);
if (!lperef) {
continue;
@@ -628,9 +653,8 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths)
}
}
}
- new_list.clear();
+ this->path_effect_list->clear();
this->getRepr()->setAttribute("inkscape:path-effect", nullptr);
-
if (!keep_paths) {
// Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible.
if (SP_IS_GENERICELLIPSE(this)) {
@@ -959,15 +983,14 @@ SPLPEItem::applyToClipPathOrMask(SPItem *clip_mask, SPItem* to, Inkscape::LivePa
}
success = false;
}
- Inkscape::XML::Node *repr = clip_mask->getRepr();
if (success && c) {
shape->setCurveInsync(c);
gchar *str = sp_svg_write_path(c->get_pathvector());
- repr->setAttribute("d", str);
+ shape->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")) {
+ if (gchar const * value = shape->getAttribute("d")) {
Geom::PathVector pv = sp_svg_read_pathv(value);
SPCurve *oldcurve = new (std::nothrow) SPCurve(pv);
if (oldcurve) {
diff --git a/src/object/sp-mask.cpp b/src/object/sp-mask.cpp
index 0d225d80a..277e35140 100644
--- a/src/object/sp-mask.cpp
+++ b/src/object/sp-mask.cpp
@@ -30,13 +30,6 @@
#include "sp-item.h"
#include "sp-mask.h"
-struct SPMaskView {
- SPMaskView *next;
- unsigned int key;
- Inkscape::DrawingItem *arenaitem;
- Geom::OptRect bbox;
-};
-
SPMaskView *sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, Inkscape::DrawingItem *arenaitem);
SPMaskView *sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view);
diff --git a/src/object/sp-mask.h b/src/object/sp-mask.h
index 5707e27d3..b1a1d1d3c 100644
--- a/src/object/sp-mask.h
+++ b/src/object/sp-mask.h
@@ -21,15 +21,20 @@
#define SP_MASK(obj) (dynamic_cast<SPMask*>((SPObject*)obj))
#define SP_IS_MASK(obj) (dynamic_cast<const SPMask*>((SPObject*)obj) != NULL)
-struct SPMaskView;
-
namespace Inkscape {
class Drawing;
class DrawingItem;
+
} // namespace Inkscape
+struct SPMaskView {
+ SPMaskView *next;
+ unsigned int key;
+ Inkscape::DrawingItem *arenaitem;
+ Geom::OptRect bbox;
+};
class SPMask : public SPObjectGroup {
public:
diff --git a/src/object/sp-path.cpp b/src/object/sp-path.cpp
index e2f6e6c99..f0e961d8c 100644
--- a/src/object/sp-path.cpp
+++ b/src/object/sp-path.cpp
@@ -325,6 +325,7 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) {
if (_curve_before_lpe && hasPathEffectRecursive()) {
if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH) ||
+ this->hasPathEffectOfType(Inkscape::LivePathEffect::POWERCLIP) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_MANY) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_STROKES) )
{
diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp
index e8109be0f..da4f18923 100644
--- a/src/object/sp-spiral.cpp
+++ b/src/object/sp-spiral.cpp
@@ -407,6 +407,7 @@ Geom::Affine SPSpiral::set_transform(Geom::Affine const &xform)
if (hasPathEffect() && pathEffectsEnabled() &&
(this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH) ||
+ this->hasPathEffectOfType(Inkscape::LivePathEffect::POWERCLIP) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_MANY) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_STROKES) ) )
{
diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp
index dc8ce4d91..fda39f4af 100644
--- a/src/object/sp-star.cpp
+++ b/src/object/sp-star.cpp
@@ -493,6 +493,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &xform)
if (hasPathEffect() && pathEffectsEnabled() &&
(this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH) ||
+ this->hasPathEffectOfType(Inkscape::LivePathEffect::POWERCLIP) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_MANY) ||
this->hasPathEffectOfType(Inkscape::LivePathEffect::FILL_BETWEEN_STROKES) ) )
{
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 17efe545b..fd3febc2c 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1637,6 +1637,7 @@ void ObjectVerb::perform( SPAction *action, void *data)
sel->editMask(false);
break;
case SP_VERB_OBJECT_UNSET_MASK:
+ Inkscape::LivePathEffect::sp_remove_powermask(sp_action_get_selection(action));
sel->unsetMask(false);
break;
case SP_VERB_OBJECT_SET_CLIPPATH:
@@ -1653,6 +1654,7 @@ void ObjectVerb::perform( SPAction *action, void *data)
sel->editMask(true);
break;
case SP_VERB_OBJECT_UNSET_CLIPPATH:
+ Inkscape::LivePathEffect::sp_remove_powerclip(sp_action_get_selection(action));
sel->unsetMask(true);
break;
default: