summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxof <jtx@jtx>2017-06-06 22:41:50 +0000
committerJabiertxof <jtx@jtx>2017-06-06 22:41:50 +0000
commitbfdef68f1e252a7e185fced8f8f0c0fd20b66e20 (patch)
tree0cdc5b1ffba7c7fe58141d6be8de4bfa4a35cf00 /src
parentStarting with powermask (diff)
downloadinkscape-bfdef68f1e252a7e185fced8f8f0c0fd20b66e20.tar.gz
inkscape-bfdef68f1e252a7e185fced8f8f0c0fd20b66e20.zip
Working on powermask
(bzr r15719)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-powermask.cpp293
-rw-r--r--src/live_effects/lpe-powermask.h12
2 files changed, 76 insertions, 229 deletions
diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp
index a98d2655f..bbe0dff40 100644
--- a/src/live_effects/lpe-powermask.cpp
+++ b/src/live_effects/lpe-powermask.cpp
@@ -10,7 +10,9 @@
#include "sp-mask.h"
#include "sp-path.h"
#include "sp-shape.h"
+#include "sp-defs.h"
#include "sp-item-group.h"
+#include "svg/svg.h"
#include "ui/tools-switch.h"
#include "path-chemistry.h"
@@ -22,17 +24,10 @@ namespace LivePathEffect {
LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject)
: Effect(lpeobject),
- inverse(_("Inverse mask"), _("Inverse mask"), "inverse", &wr, this, false),
- flatten(_("Flatten mask"), _("Flatten mask, see fill rule once convert to paths"), "flatten", &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)
+ inverse(_("Inverse mask"), _("Inverse mask"), "inverse", &wr, this, false)
{
registerParameter(&inverse);
- registerParameter(&flatten);
- registerParameter(&is_inverse);
- is_mask = false;
hide_mask = false;
- convert_shapes = false;
}
LPEPowerMask::~LPEPowerMask() {}
@@ -41,7 +36,7 @@ void
LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){
original_bbox(lpeitem);
const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("mask-path");
- SPMaskPath *mask_path = SP_ITEM(lpeitem)->mask_ref->getObject();
+ SPMask *mask = SP_ITEM(lpeitem)->mask_ref->getObject();
Geom::Point topleft = Geom::Point(boundingbox_X.min() - 5,boundingbox_Y.max() + 5);
Geom::Point topright = Geom::Point(boundingbox_X.max() + 5,boundingbox_Y.max() + 5);
Geom::Point bottomright = Geom::Point(boundingbox_X.max() + 5,boundingbox_Y.min() - 5);
@@ -52,147 +47,72 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){
mask_box.appendNew<Geom::LineSegment>(bottomright);
mask_box.appendNew<Geom::LineSegment>(bottomleft);
mask_box.close();
- //mask_path *= sp_lpe_item->i2dt_affine();
- if(mask_path) {
- is_mask = true;
- std::vector<SPObject*> mask_path_list = mask_path->childList(true);
- for ( std::vector<SPObject*>::const_iterator iter=mask_path_list.begin();iter!=mask_path_list.end();++iter) {
- SPObject * mask_data = *iter;
- SPObject * mask_to_path = NULL;
- if (SP_IS_SHAPE(mask_data) && !SP_IS_PATH(mask_data) && convert_shapes) {
- SPDocument * document = SP_ACTIVE_DOCUMENT;
- if (!document) {
- return;
- }
- Inkscape::XML::Document *xml_doc = document->getReprDoc();
- Inkscape::XML::Node *mask_path_node = sp_selected_item_to_curved_repr(SP_ITEM(mask_data), 0);
- // remember the position of the item
- gint pos = mask_data->getRepr()->position();
- // remember parent
- Inkscape::XML::Node *parent = mask_data->getRepr()->parent();
- // remember id
- char const *id = mask_data->getRepr()->attribute("id");
- // remember title
- gchar *title = mask_data->title();
- // remember description
- gchar *desc = mask_data->desc();
-
- // It's going to resurrect, so we delete without notifying listeners.
- mask_data->deleteObject(false);
-
- // restore id
- mask_path_node->setAttribute("id", id);
- // add the new repr to the parent
- parent->appendChild(mask_path_node);
- mask_to_path = document->getObjectByRepr(mask_path_node);
- if (title && mask_to_path) {
- mask_to_path->setTitle(title);
- g_free(title);
- }
- if (desc && mask_to_path) {
- mask_to_path->setDesc(desc);
- g_free(desc);
- }
- // move to the saved position
- mask_path_node->setPosition(pos > 0 ? pos : 0);
- Inkscape::GC::release(mask_path_node);
- mask_to_path->emitModified(SP_OBJECT_MODIFIED_CASCADE);
- }
- if( inverse && isVisible()) {
- if (mask_to_path) {
- addInverse(SP_ITEM(mask_to_path));
- } else {
- addInverse(SP_ITEM(mask_data));
- }
- } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") {
- if (mask_to_path) {
- removeInverse(SP_ITEM(mask_to_path));
- } else {
- removeInverse(SP_ITEM(mask_data));
- }
- }
- }
- } else {
- is_mask = false;
+ //mask *= sp_lpe_item->i2dt_affine();
+ if(mask) {
+ setInverse();
}
}
void
-LPEPowerMask::addInverse (SPItem * mask_data){
- if (SP_IS_GROUP(mask_data)) {
- std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(mask_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(mask_data)) {
- SPCurve * c = NULL;
- c = SP_SHAPE(mask_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(mask_box);
- if (dir_a == dir_b) {
- mask_box = mask_box.reversed();
- }
- c_pv.push_back(mask_box);
- c->set_pathvector(c_pv);
- SP_SHAPE(mask_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);
- }
- }
- }
- }
+LPEPowerMask::setInverse(){
+ SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject();
+ SPObject *elemref = NULL;
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if(!document || !mask) {
+ return;
}
-}
-
-void
-LPEPowerMask::removeInverse (SPItem * mask_data){
- if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") {
- if (SP_IS_GROUP(mask_data)) {
- std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(mask_data));
- for ( std::vector<SPItem*>::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) {
- SPItem *subitem = *iter;
- removeInverse(subitem);
- }
- } else if (SP_IS_PATH(mask_data)) {
- SPCurve * c = NULL;
- c = SP_SHAPE(mask_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(mask_data)->setCurve(c, TRUE);
- c->unref();
- 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 != NULL) {
- sel->remove(item);
- sel->add(item);
- }
- }
- }
- }
- }
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
+ Inkscape::XML::Node *box = NULL;
+ Inkscape::XML::Node *filter = NULL;
+ SPDefs * defs = document->getDefs();
+ if (inverse) {
+// if (!(elemref = document->getObjectById((Glib::ustring)mask->getId() + (Glib::ustring)"_transparentbox"))) {
+// std::vector<SPObject*> mask_list = mask->childList(true);
+// box = xml_doc->createElement("svg:path");
+// box->setAttribute("id", (Glib::ustring)mask->getId() + (Glib::ustring)"_transparentbox");
+// box->setAttribute("style", "fill:#000");
+// gchar * box_str = sp_svg_write_path( mask_box );
+// box->setAttribute("d" , box_str);
+// g_free(box_str);
+// elemref = mask->appendChildRepr(box);
+// box->setPosition(mask_list.size());
+// Inkscape::GC::release(box);
+// mask_list.clear();
+// }
+// if (!(elemref = document->getObjectById((Glib::ustring)mask->getId() + (Glib::ustring)"_inverse"))) {
+// filter = xml_doc->createElement("svg:filter");
+// filter->setAttribute("id", (Glib::ustring)mask->getId() + (Glib::ustring)"_inverse");
+// filter->setAttribute("color-interpolation-filters", "sRGB");
+// filter->setAttribute("height", "100");
+// filter->setAttribute("width", "100");
+// filter->setAttribute("x", "-50");
+// filter->setAttribute("y", "-50");
+// Inkscape::XML::Node *primitive1 = xml_doc->createElement("svg:feColorMatrix");
+// primitive1->setAttribute("id", (Glib::ustring)mask->getId() + (Glib::ustring)"_primitive1");
+// primitive1->setAttribute("values", "1");
+// primitive1->setAttribute("type", "saturate");
+// primitive1->setAttribute("result", "fbSourceGraphic");
+// Inkscape::XML::Node *primitive2 = xml_doc->createElement("svg:feColorMatrix");
+// primitive2->setAttribute("id", (Glib::ustring)mask->getId() + (Glib::ustring)"_primitive2");
+// primitive2->setAttribute("values", "-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 ");
+// primitive2->setAttribute("in", "fbSourceGraphic");
+// elemref = defs->appendChildRepr(filter);
+// filter->appendChild(primitive1);
+// filter->appendChild(primitive2);
+// Inkscape::GC::release(filter);
+// Inkscape::GC::release(primitive1);
+// Inkscape::GC::release(primitive2);
+// }
+// mask->getRepr()->setAttribute("css", (Glib::ustring)"filter:#" + (Glib::ustring)mask->getId() + (Glib::ustring)"_inverse");
+ } else {
+// if ((elemref = document->getObjectById((Glib::ustring)mask->getId() + (Glib::ustring)"_transparentbox"))) {
+// elemref->deleteObject(true);
+// }
+
+// if ((elemref = document->getObjectById((Glib::ustring)mask->getId() + (Glib::ustring)"_inverse"))) {
+// elemref->deleteObject(true);
+// }
+ //mask->getRepr()->setAttribute("css", NULL);
}
}
@@ -200,13 +120,13 @@ void
LPEPowerMask::toggleMask() {
SPItem * item = SP_ITEM(sp_lpe_item);
if (item) {
- SPMaskPath *mask_path = item->mask_ref->getObject();
- if (mask_path) {
+ SPMask *mask = item->mask_ref->getObject();
+ if (mask) {
hide_mask = !hide_mask;
if(hide_mask) {
SPItemView *v;
for (v = item->display; v != NULL; v = v->next) {
- mask_path->hide(v->arenaitem->key());
+ mask->sp_mask_hide(v->arenaitem->key());
}
} else {
Geom::OptRect bbox = item->geometricBounds();
@@ -214,24 +134,18 @@ LPEPowerMask::toggleMask() {
if (!v->arenaitem->key()) {
v->arenaitem->setKey(SPItem::display_key_new(3));
}
- Inkscape::DrawingItem *ai = mask_path->show(
+ Inkscape::DrawingItem *ai = mask->sp_mask_show(
v->arenaitem->drawing(),
v->arenaitem->key());
v->arenaitem->setMask(ai);
- mask_path->setBBox(v->arenaitem->key(), bbox);
+ mask->sp_mask_set_bbox(v->arenaitem->key(), bbox);
}
}
- mask_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
}
}
-void
-LPEPowerMask::convertShapes() {
- convert_shapes = true;
- sp_lpe_item_update_patheffect(SP_LPE_ITEM(sp_lpe_item), false, false);
-}
-
Gtk::Widget *
LPEPowerMask::newWidget()
{
@@ -270,74 +184,17 @@ LPEPowerMask::newWidget()
toggle_button->set_size_request(140,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 masks to paths, undoable"))));
- topaths_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEPowerMask::convertShapes));
- topaths_button->set_size_request(200,30);
- vbox->pack_start(*hbox2, true,true,2);
- hbox2->pack_start(*topaths_button, false, false,2);
return dynamic_cast<Gtk::Widget *>(vbox);
}
void
LPEPowerMask::doOnRemove (SPLPEItem const* /*lpeitem*/)
{
- SPMaskPath *mask_path = SP_ITEM(sp_lpe_item)->mask_ref->getObject();
+ SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject();
if(!keep_paths) {
- if(mask_path) {
- is_mask = true;
- std::vector<SPObject*> mask_path_list = mask_path->childList(true);
- for ( std::vector<SPObject*>::const_iterator iter=mask_path_list.begin();iter!=mask_path_list.end();++iter) {
- SPObject * mask_data = *iter;
- if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") {
- removeInverse(SP_ITEM(mask_data));
- is_inverse.param_setValue((Glib::ustring)"false");
- }
- }
- }
- } else {
- if (flatten && mask_path) {
- mask_path->deleteObject();
- sp_lpe_item->getRepr()->setAttribute("mask-path", NULL);
- }
- }
-}
-
-Geom::PathVector
-LPEPowerMask::doEffect_path(Geom::PathVector const & path_in){
- Geom::PathVector path_out = pathv_to_linear_and_cubic_beziers(path_in);
- if (flatten && is_mask && isVisible()) {
- SPMaskPath *mask_path = SP_ITEM(sp_lpe_item)->mask_ref->getObject();
- if(mask_path) {
- std::vector<SPObject*> mask_path_list = mask_path->childList(true);
- for ( std::vector<SPObject*>::const_iterator iter=mask_path_list.begin();iter!=mask_path_list.end();++iter) {
- SPObject * mask_data = *iter;
- flattenMask(SP_ITEM(mask_data), path_out);
- }
- }
- }
- return path_out;
-}
-
-void
-LPEPowerMask::flattenMask(SPItem * mask_data, Geom::PathVector &path_in)
-{
- if (SP_IS_GROUP(mask_data)) {
- std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(mask_data));
- for ( std::vector<SPItem*>::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) {
- SPItem *subitem = *iter;
- flattenMask(subitem, path_in);
- }
- } else if (SP_IS_PATH(mask_data)) {
- SPCurve * c = NULL;
- c = SP_SHAPE(mask_data)->getCurve();
- if (c) {
- Geom::PathVector c_pv = c->get_pathvector();
- Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(c_pv, path_in);
- if (pig && !c_pv.empty() && !path_in.empty()) {
- path_in = pig->getIntersection();
- }
- c->unref();
+ if(mask) {
+ inverse.param_setValue(false);
+ setInverse();
}
}
}
diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h
index 933eeefb1..4038f207e 100644
--- a/src/live_effects/lpe-powermask.h
+++ b/src/live_effects/lpe-powermask.h
@@ -20,24 +20,14 @@ public:
LPEPowerMask(LivePathEffectObject *lpeobject);
virtual ~LPEPowerMask();
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
- virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in);
- //virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem);
virtual void doOnRemove (SPLPEItem const* /*lpeitem*/);
virtual Gtk::Widget * newWidget();
void toggleMask();
- void addInverse (SPItem * mask_data);
- void removeInverse (SPItem * mask_data);
- void flattenMask(SPItem * mask_data, Geom::PathVector &path_in);
- void convertShapes();
+ void setInverse();
private:
BoolParam inverse;
- BoolParam flatten;
- HiddenParam is_inverse;
Geom::Path mask_box;
- bool is_mask;
- bool convert_shapes;
bool hide_mask;
- bool previous_hide_mask;
};
} //namespace LivePathEffect