summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2017-06-24 17:45:12 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-06-24 17:45:12 +0000
commite1b08bb2e05c407f3e524e5d9f7b63ae88e15f6c (patch)
tree650aaeb95a2468fdbdc3401530e8a825c7c4a3d1 /src
parentUpdating to master (diff)
downloadinkscape-e1b08bb2e05c407f3e524e5d9f7b63ae88e15f6c.tar.gz
inkscape-e1b08bb2e05c407f3e524e5d9f7b63ae88e15f6c.zip
Working with powerclip and powermask
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect.cpp1
-rw-r--r--src/live_effects/lpe-powerclip.cpp127
-rw-r--r--src/live_effects/lpe-powerclip.h6
-rw-r--r--src/live_effects/lpe-powermask.cpp49
-rw-r--r--src/live_effects/lpe-powermask.h2
-rw-r--r--src/sp-item.cpp7
-rw-r--r--src/sp-path.cpp3
7 files changed, 146 insertions, 49 deletions
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;