From 2c160c193b9767df8448ec3d018c3d6225a4ec63 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 27 May 2017 12:23:25 +0200 Subject: Change bad named vars (bzr r15703.1.1) --- src/live_effects/effect.cpp | 2 +- src/live_effects/effect.h | 2 +- src/live_effects/lpe-copy_rotate.cpp | 4 ++-- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- src/live_effects/lpe-measure-line.cpp | 4 ++-- src/live_effects/lpe-mirror_symmetry.cpp | 4 ++-- src/live_effects/parameter/bool.cpp | 6 +++--- src/live_effects/parameter/bool.h | 4 ++-- src/live_effects/parameter/hidden.cpp | 6 ++++-- src/live_effects/parameter/hidden.h | 5 +++-- src/live_effects/parameter/parameter.cpp | 6 +++--- src/live_effects/parameter/parameter.h | 4 ++-- src/sp-lpe-item.cpp | 2 +- 13 files changed, 27 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index a4b44b1a9..23a4c9f3d 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -355,7 +355,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) 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), - erase_extra_objects(true), + keep_paths(false), lpeobj(lpeobject), concatenate_before_pwd2(false), sp_lpe_item(NULL), diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 60ee8d98f..cc0d53f12 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -132,7 +132,7 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_mask; - bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE + bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE bool upd_params; BoolParam is_visible; SPCurve * sp_curve; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index ff24b46da..2364f4f66 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -722,8 +722,8 @@ LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); return; } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 08ceab3c3..a2f0b829d 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -38,7 +38,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) 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"), + "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", diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index f7892cbe7..f18ba2dcd 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -674,8 +674,8 @@ LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); items.clear(); return; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index bd3dedc86..9c2b876db 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -350,8 +350,8 @@ LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); return; } diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 3184bfa80..d9e8ecc90 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -21,8 +21,8 @@ namespace LivePathEffect { BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value , bool no_widget) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), hide_widget(no_widget) + Effect* effect, bool default_value , bool is_visible) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), widget_is_visible(is_visible) { } @@ -65,7 +65,7 @@ BoolParam::param_getSVGValue() const Gtk::Widget * BoolParam::param_newWidget() { - if(!hide_widget){ + if(widget_is_visible){ Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( new Inkscape::UI::Widget::RegisteredCheckButton( param_label, param_tooltip, diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index 39f328eaa..86681e764 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -26,7 +26,7 @@ public: Inkscape::UI::Widget::Registry* wr, Effect* effect, bool default_value = false, - bool no_widget = false); + bool widget_is_visible = true); virtual ~BoolParam(); virtual Gtk::Widget * param_newWidget(); @@ -40,6 +40,7 @@ public: virtual void param_update_default(const gchar * default_value); bool get_value() const { return value; }; inline operator bool() const { return value; }; + bool widget_is_visible; private: BoolParam(const BoolParam&); @@ -47,7 +48,6 @@ private: bool value; bool defvalue; - bool hide_widget; }; diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 2f218847a..95735d50f 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -22,10 +22,12 @@ namespace LivePathEffect { HiddenParam::HiddenParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const Glib::ustring default_value ) + Effect* effect, const Glib::ustring default_value, bool is_visible) : Parameter(label, tip, key, wr, effect), value(default_value), - defvalue(default_value) + defvalue(default_value), + //This last is to allow set or unset default parameters on hidden ones + widget_is_visible(is_visible) { } diff --git a/src/live_effects/parameter/hidden.h b/src/live_effects/parameter/hidden.h index d565272b6..f07dd9edc 100644 --- a/src/live_effects/parameter/hidden.h +++ b/src/live_effects/parameter/hidden.h @@ -29,7 +29,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - const Glib::ustring default_value = ""); + const Glib::ustring default_value = "", + bool widget_is_visible = false); virtual ~HiddenParam() {} virtual Gtk::Widget * param_newWidget(); @@ -42,7 +43,7 @@ public: virtual void param_update_default(const gchar * default_value); const Glib::ustring get_value() const { return value; }; - + bool widget_is_visible; private: HiddenParam(const HiddenParam&); HiddenParam& operator=(const HiddenParam&); diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 45f46a0a7..cc7b476d7 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -55,7 +55,7 @@ void Parameter::write_to_SVG(void) */ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, gdouble default_value, bool no_widget) + Effect* effect, gdouble default_value, bool is_visible) : Parameter(label, tip, key, wr, effect), value(default_value), min(-SCALARPARAM_G_MAXDOUBLE), @@ -67,7 +67,7 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, inc_page(1), add_slider(false), overwrite_widget(false), - hide_widget(no_widget) + widget_is_visible(is_visible) { } @@ -172,7 +172,7 @@ ScalarParam::param_overwrite_widget(bool overwrite_widget) Gtk::Widget * ScalarParam::param_newWidget() { - if(!hide_widget){ + if(widget_is_visible){ Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index ee1d2d547..bdba9f860 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -104,7 +104,7 @@ public: Inkscape::UI::Widget::Registry* wr, Effect* effect, gdouble default_value = 1.0, - bool no_widget = false); + bool widget_is_visible = true); virtual ~ScalarParam(); virtual bool param_readSVGValue(const gchar * strvalue); @@ -125,6 +125,7 @@ public: virtual Gtk::Widget * param_newWidget(); inline operator gdouble() const { return value; }; + bool widget_is_visible; protected: gdouble value; @@ -137,7 +138,6 @@ protected: double inc_page; bool add_slider; bool overwrite_widget; - bool hide_widget; private: ScalarParam(const ScalarParam&); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index efb1f4353..b08772826 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -519,7 +519,7 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj) { Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - lpe->erase_extra_objects = false; + lpe->keep_paths = true; } } } -- cgit v1.2.3 From 9867bcf966bf0a52333fd3c129d94d3afa4baa55 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 27 May 2017 14:00:01 +0200 Subject: More fixes to LPE (bzr r15703.1.2) --- src/live_effects/lpe-bspline.cpp | 4 +-- src/live_effects/lpe-copy_rotate.cpp | 15 +++++----- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- src/live_effects/lpe-measure-line.cpp | 35 ++++++++++++------------ src/live_effects/lpe-mirror_symmetry.cpp | 38 ++------------------------ src/live_effects/lpe-mirror_symmetry.h | 1 - src/live_effects/lpe-transform_2pts.cpp | 4 +-- src/live_effects/parameter/bool.cpp | 4 +-- src/live_effects/parameter/bool.h | 4 +-- src/live_effects/parameter/hidden.cpp | 5 ++-- src/live_effects/parameter/hidden.h | 2 +- src/live_effects/parameter/parameter.cpp | 11 ++++---- src/live_effects/parameter/parameter.h | 9 +++--- src/live_effects/parameter/satellitesarray.cpp | 1 + 14 files changed, 47 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index dbd67beda..721a4ecab 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -44,12 +44,12 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); - weight.param_overwrite_widget(true); + weight.param_set_undo(false); steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); - steps.param_overwrite_widget(true); + steps.param_set_undo(false); helper_size.param_set_range(0.0, 999.0); helper_size.param_set_increments(1, 1); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 2364f4f66..551cf1bf9 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -96,6 +96,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : previous_num_copies = num_copies; previous_origin = Geom::Point(0,0); previous_start_point = Geom::Point(0,0); + starting_point.param_widget_is_visible(false); reset = false; } @@ -319,14 +320,12 @@ Gtk::Widget * LPECopyRotate::newWidget() Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); if (widg) { - if (param->param_key != "starting_point") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); } } } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index a2f0b829d..11298bcbe 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -80,7 +80,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) radius.param_set_range(0.0, Geom::infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); - radius.param_overwrite_widget(true); + 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); diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index f18ba2dcd..99828aef8 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -141,6 +141,7 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_digits(2); start_stored = Geom::Point(0,0); end_stored = Geom::Point(0,0); + id_origin.param_widget_is_visible(false); } LPEMeasureLine::~LPEMeasureLine() {} @@ -700,24 +701,22 @@ Gtk::Widget *LPEMeasureLine::newWidget() while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; - if (param->param_key != "id_origin") { - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "dimline_format" && - param->param_key != "helperlines_format" && - param->param_key != "arrows_format" && - param->param_key != "anotation_format") { - vbox->pack_start(*widg, true, true, 2); - } else { - vbox_expander->pack_start(*widg, true, true, 2); - } - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "dimline_format" && + param->param_key != "helperlines_format" && + param->param_key != "arrows_format" && + param->param_key != "anotation_format") { + vbox->pack_start(*widg, true, true, 2); + } else { + vbox_expander->pack_start(*widg, true, true, 2); + } + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); } } } diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 9c2b876db..8e68c483c 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -78,6 +78,8 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : 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); } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -304,42 +306,6 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) } } -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; - if (param->param_key == "id_origin" || param->param_key == "center_point") { - ++it; - continue; - } - 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); -} - //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 07bb3d4fc..e98c83f2b 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -46,7 +46,6 @@ 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); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneD(SPObject *orig, SPObject *dest, bool live, bool root); diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index f4d233d56..ab05b880c 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -64,9 +64,9 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : registerParameter(&lock_angle); first_knot.param_make_integer(true); - first_knot.param_overwrite_widget(true); + first_knot.param_set_undo(false); last_knot.param_make_integer(true); - last_knot.param_overwrite_widget(true); + last_knot.param_set_undo(false); helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index d9e8ecc90..954947cf4 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -21,8 +21,8 @@ namespace LivePathEffect { BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value , bool is_visible) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), widget_is_visible(is_visible) + Effect* effect, bool default_value) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) { } diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index 86681e764..417752050 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -25,8 +25,7 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - bool default_value = false, - bool widget_is_visible = true); + bool default_value = false); virtual ~BoolParam(); virtual Gtk::Widget * param_newWidget(); @@ -40,7 +39,6 @@ public: virtual void param_update_default(const gchar * default_value); bool get_value() const { return value; }; inline operator bool() const { return value; }; - bool widget_is_visible; private: BoolParam(const BoolParam&); diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 95735d50f..6d0e7f58f 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -25,10 +25,9 @@ HiddenParam::HiddenParam( const Glib::ustring& label, const Glib::ustring& tip, Effect* effect, const Glib::ustring default_value, bool is_visible) : Parameter(label, tip, key, wr, effect), value(default_value), - defvalue(default_value), - //This last is to allow set or unset default parameters on hidden ones - widget_is_visible(is_visible) + defvalue(default_value) { + param_widget_is_visible(is_visible); } void diff --git a/src/live_effects/parameter/hidden.h b/src/live_effects/parameter/hidden.h index f07dd9edc..387071e53 100644 --- a/src/live_effects/parameter/hidden.h +++ b/src/live_effects/parameter/hidden.h @@ -43,7 +43,7 @@ public: virtual void param_update_default(const gchar * default_value); const Glib::ustring get_value() const { return value; }; - bool widget_is_visible; + private: HiddenParam(const HiddenParam&); HiddenParam& operator=(const HiddenParam&); diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index cc7b476d7..2f73488aa 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -55,7 +55,7 @@ void Parameter::write_to_SVG(void) */ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, gdouble default_value, bool is_visible) + Effect* effect, gdouble default_value) : Parameter(label, tip, key, wr, effect), value(default_value), min(-SCALARPARAM_G_MAXDOUBLE), @@ -66,8 +66,7 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, inc_step(0.1), inc_page(1), add_slider(false), - overwrite_widget(false), - widget_is_visible(is_visible) + _set_undo(true) { } @@ -164,9 +163,9 @@ ScalarParam::param_make_integer(bool yes) } void -ScalarParam::param_overwrite_widget(bool overwrite_widget) +ScalarParam::param_set_undo(bool set_undo) { - this->overwrite_widget = overwrite_widget; + _set_undo = set_undo; } Gtk::Widget * @@ -184,7 +183,7 @@ ScalarParam::param_newWidget() if (add_slider) { rsu->addSlider(); } - if(!overwrite_widget){ + if(_set_undo){ rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } return dynamic_cast (rsu); diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index bdba9f860..7ab7e30dd 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -57,6 +57,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted. virtual gchar * param_getSVGValue() const = 0; + virtual void param_widget_is_visible(bool is_visible) {widget_is_visible = is_visible;} void write_to_SVG(); virtual void param_set_default() = 0; @@ -103,8 +104,7 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - gdouble default_value = 1.0, - bool widget_is_visible = true); + gdouble default_value = 1.0); virtual ~ScalarParam(); virtual bool param_readSVGValue(const gchar * strvalue); @@ -121,11 +121,10 @@ public: void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; }; double param_get_max() { return max; }; double param_get_min() { return min; }; - void param_overwrite_widget(bool overwrite_widget); + void param_set_undo(bool set_undo); virtual Gtk::Widget * param_newWidget(); inline operator gdouble() const { return value; }; - bool widget_is_visible; protected: gdouble value; @@ -137,7 +136,7 @@ protected: double inc_step; double inc_page; bool add_slider; - bool overwrite_widget; + bool _set_undo; private: ScalarParam(const ScalarParam&); diff --git a/src/live_effects/parameter/satellitesarray.cpp b/src/live_effects/parameter/satellitesarray.cpp index 7626317a1..ce4da243e 100644 --- a/src/live_effects/parameter/satellitesarray.cpp +++ b/src/live_effects/parameter/satellitesarray.cpp @@ -37,6 +37,7 @@ SatellitesArrayParam::SatellitesArrayParam(const Glib::ustring &label, _current_zoom = 0; _effectType = FILLET_CHAMFER; _last_pathvector_satellites = NULL; + param_widget_is_visible(false); } -- cgit v1.2.3 From dc565882efdb6da2d813390cddee69818d2dac5e Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 27 May 2017 22:26:45 +0200 Subject: Allow LPE clip or mask hasent effect applied (bzr r15703.1.3) --- src/sp-lpe-item.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index b08772826..68f9843d5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -220,6 +220,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip if (!curve) { return false; } + bool has_lpe_clipmask = false; if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { @@ -245,6 +246,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip // yet, we don't alter the path return false; } + if (lpe->apply_to_clippath_and_mask) { + has_lpe_clipmask = true; + } if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere if (current) { @@ -272,7 +276,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } } } - if(!SP_IS_GROUP(this) && !is_clip_or_mask){ + if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_lpe_clipmask){ this->apply_to_clippath(this); this->apply_to_mask(this); } -- cgit v1.2.3 From 07dc06a89868df632ea08117add317ac123f6ced Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 07:40:43 +0200 Subject: Force not original-d if the clip-path or mask has not a LPE allowed to change it (bzr r15703.1.4) --- src/live_effects/parameter/path.cpp | 104 +++++++++++++++++++++--------------- src/live_effects/parameter/path.h | 6 ++- src/sp-lpe-item.cpp | 92 +++++++++++++++++++++++-------- src/sp-lpe-item.h | 2 + 4 files changed, 140 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 6e90c9279..54f5d93e8 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -69,7 +69,10 @@ PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip, defvalue = g_strdup(default_value); param_readSVGValue(defvalue); oncanvas_editable = true; - + _edit_button = true; + _copy_button = true; + _paste_button = true; + _link_button = true; ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &PathParam::ref_changed)); } @@ -167,6 +170,15 @@ PathParam::param_getSVGValue() const } } +void +PathParam::set_buttons(bool edit_button, bool copy_button, bool paste_button, bool link_button) +{ + _edit_button = edit_button; + _copy_button = copy_button; + _paste_button = paste_button; + _link_button = link_button; +} + Gtk::Widget * PathParam::param_newWidget() { @@ -175,47 +187,55 @@ PathParam::param_newWidget() Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label)); static_cast(_widget)->pack_start(*pLabel, true, true); pLabel->set_tooltip_text(param_tooltip); - - Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("tool-node-editor"), Inkscape::ICON_SIZE_BUTTON) ); - Gtk::Button * pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Edit on-canvas")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-copy"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_copy_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Copy path")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Paste path")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to path on clipboard")); - + Gtk::Widget * pIcon = NULL; + Gtk::Button * pButton = NULL; + if (_edit_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("tool-node-editor"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Edit on-canvas")); + } + + if (_copy_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-copy"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_copy_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Copy path")); + } + + if (_paste_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Paste path")); + } + if (_link_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Link to path on clipboard")); + } + static_cast(_widget)->show_all_children(); return dynamic_cast (_widget); diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h index 5381a6b36..ff5e4f1b8 100644 --- a/src/live_effects/parameter/path.h +++ b/src/live_effects/parameter/path.h @@ -44,7 +44,7 @@ public: void param_set_and_write_default(); void set_new_value (Geom::PathVector const &newpath, bool write_to_svg); void set_new_value (Geom::Piecewise > const &newpath, bool write_to_svg); - + void set_buttons(bool edit_button, bool copy_button, bool paste_button, bool link_button); virtual void param_editOncanvas(SPItem * item, SPDesktop * dt); virtual void param_setup_nodepath(Inkscape::NodePath::Path *np); virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); @@ -91,6 +91,10 @@ protected: gchar * defvalue; private: + bool _edit_button; + bool _copy_button; + bool _paste_button; + bool _link_button; PathParam(const PathParam&); PathParam& operator=(const PathParam&); }; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 68f9843d5..d1f1697a8 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -212,6 +212,47 @@ 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; + } + } + } + } + std::cout << has_clipormask_lpe << "has_clipormask_lpe\n"; + 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. */ @@ -220,7 +261,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip if (!curve) { return false; } - bool has_lpe_clipmask = 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) { @@ -247,7 +288,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip return false; } if (lpe->apply_to_clippath_and_mask) { - has_lpe_clipmask = true; + 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 @@ -276,7 +317,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } } } - if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_lpe_clipmask){ + if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_clipormask_lpe){ this->apply_to_clippath(this); this->apply_to_mask(this); } @@ -370,9 +411,8 @@ static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - if (SP_IS_GROUP(lpeitem)) { - if (!lpeitem->hasPathEffectRecursive()) { + if (!lpeitem->hasPathEffectOnClipOrMaskRecursive()) { SPMask * mask = lpeitem->mask_ref->getObject(); if(mask) { @@ -391,24 +431,24 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem)); } } - } - else if (SP_IS_PATH(lpeitem)) { + } else if (SP_IS_PATH(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - if (!lpeitem->hasPathEffectRecursive() && 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())); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); - } + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clip_path = lpeitem->clip_ref->getObject(); + if(clip_path) { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + } + mask = dynamic_cast(lpeitem->parent); + clip_path = dynamic_cast(lpeitem->parent); + if ((!lpeitem->hasPathEffectRecursive() && repr->attribute("inkscape:original-d")) || + ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMask() && repr->attribute("inkscape:original-d"))) + { repr->setAttribute("d", repr->attribute("inkscape:original-d")); repr->setAttribute("inkscape:original-d", NULL); - } - else { + } else { sp_lpe_item_update_patheffect(lpeitem, true, true); } } @@ -462,7 +502,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 && !hasPathEffectOnClipOrMask()) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clip_path = clip_ref->getObject(); + if(clip_path && !hasPathEffectOnClipOrMask()) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + } //fix bug 1219324 if (SP_ACTIVE_DESKTOP ) { Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; @@ -649,6 +698,7 @@ bool SPLPEItem::hasPathEffectRecursive() const return hasPathEffect(); } } + void SPLPEItem::apply_to_clippath(SPItem *item) { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 0f198c49c..d5d4e118b 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -70,6 +70,8 @@ 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 pathEffectsEnabled() const; -- cgit v1.2.3 From 0e48d3acb1c3ae038cf4ecda45cf482bb3177a0a Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 08:10:29 +0200 Subject: Remove original-d from clip and mask LPE if keep paths (bzr r15703.1.5) --- src/sp-lpe-item.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index d1f1697a8..7dcbc4311 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); +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); @@ -408,7 +408,7 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) } static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) { g_return_if_fail(lpeitem != NULL); if (SP_IS_GROUP(lpeitem)) { @@ -416,37 +416,39 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) SPMask * mask = lpeitem->mask_ref->getObject(); if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + 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())); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); } } 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)); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), 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())); + 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())); + 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->hasPathEffectOnClipOrMask() && repr->attribute("inkscape:original-d"))) + ((mask || clip_path) && !lpeitem->hasPathEffectOnClipOrMaskRecursive() && repr->attribute("inkscape:original-d"))) { - repr->setAttribute("d", repr->attribute("inkscape:original-d")); + if (!keep_paths) { + repr->setAttribute("d", repr->attribute("inkscape:original-d")); + } repr->setAttribute("inkscape:original-d", NULL); } else { sp_lpe_item_update_patheffect(lpeitem, true, true); @@ -503,14 +505,14 @@ 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 && !hasPathEffectOnClipOrMask()) + if(mask && !hasPathEffectOnClipOrMaskRecursive()) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()), false); } SPClipPath * clip_path = clip_ref->getObject(); - if(clip_path && !hasPathEffectOnClipOrMask()) + if(clip_path && !hasPathEffectOnClipOrMaskRecursive()) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), false); } //fix bug 1219324 if (SP_ACTIVE_DESKTOP ) { @@ -552,9 +554,8 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) 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); } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); } /** @@ -584,9 +585,8 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) 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); } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); } void SPLPEItem::downCurrentPathEffect() @@ -607,7 +607,7 @@ void SPLPEItem::downCurrentPathEffect() this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - sp_lpe_item_cleanup_original_path_recursive(this); + sp_lpe_item_cleanup_original_path_recursive(this, false); } void SPLPEItem::upCurrentPathEffect() @@ -626,7 +626,7 @@ void SPLPEItem::upCurrentPathEffect() this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - sp_lpe_item_cleanup_original_path_recursive(this); + 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= */ @@ -854,7 +854,7 @@ void SPLPEItem::remove_child(Inkscape::XML::Node * child) { 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)); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild), false); } } -- cgit v1.2.3 From 117bfe6d616a1b34d4afeb976b708363206aef71 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 08:59:50 +0200 Subject: Remove dabug line (bzr r15703.1.6) --- src/sp-lpe-item.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 7dcbc4311..d920909f9 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -239,7 +239,6 @@ bool SPLPEItem::hasPathEffectOnClipOrMask() const } } } - std::cout << has_clipormask_lpe << "has_clipormask_lpe\n"; return has_clipormask_lpe; } -- cgit v1.2.3 From b7b7cec5f8828c5d949b9eb2bea6d9f16ce77a7c Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 09:15:03 +0200 Subject: Allow doOnRemove in all LPE (bzr r15703.1.7) --- src/sp-lpe-item.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index d920909f9..83cf408a4 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -129,12 +129,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe) || - dynamic_cast(lpe) || - dynamic_cast(lpe) ) - { - lpe->doOnRemove(this); - } + lpe->doOnRemove(this); } (*it)->unlink(); delete *it; -- cgit v1.2.3 From 723a528815298cdf6989c03fcdbaa8ad20914571 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 12:46:10 +0200 Subject: Add a new value to LPE 'is_load' to know the lpe is just load, no previous values set yet to not LPE stored values when loading a previous file (bzr r15703.1.8) --- src/live_effects/effect.cpp | 2 ++ src/live_effects/effect.h | 1 + src/live_effects/lpe-copy_rotate.cpp | 1 + src/live_effects/lpe-mirror_symmetry.cpp | 1 + 4 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 23a4c9f3d..3a628b243 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -356,6 +356,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) 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), @@ -511,6 +512,7 @@ Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) { + is_load = false; } void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index cc0d53f12..e353eba23 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -133,6 +133,7 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_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; SPCurve * sp_curve; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 551cf1bf9..b29b5e493 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -109,6 +109,7 @@ void LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) { if (split_items) { + is_load = false; SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 8e68c483c..3fcc4ae3d 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -89,6 +89,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { + is_load = false; SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; -- cgit v1.2.3 From 63925693eb0141d1f589f86f967536918e7b17f6 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sun, 28 May 2017 12:57:28 +0200 Subject: Fix bug on crash if undefined LPE load (bzr r15703.1.9) --- src/sp-lpe-item.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 83cf408a4..35e7dfa3e 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -129,7 +129,9 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - lpe->doOnRemove(this); + if (lpe) { + lpe->doOnRemove(this); + } } (*it)->unlink(); delete *it; -- cgit v1.2.3 From 822154dfcb9fe3777f32aa27b9bae4480a1417c2 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 29 May 2017 02:09:29 +0200 Subject: Fix bug #1694111 also fixes noumerous bugfixes on LPE undo. And shapes are improved to only perform path effet one time each Fixed bugs: - https://launchpad.net/bugs/1694111 (bzr r15703.1.10) --- src/live_effects/effect.cpp | 11 ++++++++--- src/live_effects/lpe-copy_rotate.cpp | 9 ++++----- src/live_effects/lpe-mirror_symmetry.cpp | 1 + src/live_effects/lpeobject.cpp | 1 + src/sp-ellipse.cpp | 10 ++++++++-- src/sp-ellipse.h | 2 +- src/sp-lpe-item.cpp | 34 +++++++++++++------------------- src/sp-spiral.cpp | 10 ++++++++-- src/sp-spiral.h | 2 +- src/sp-star.cpp | 10 ++++++++-- src/sp-star.h | 2 +- 11 files changed, 55 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3a628b243..21136353c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -452,10 +452,13 @@ Effect::processObjects(LpeAction lpe_action) std::vector item_selected; SPCSSAttr *css; Glib::ustring css_str; + SPItem *item = SP_ITEM(elemref); switch (lpe_action){ case LPE_TO_OBJECTS: - if (SP_ITEM(elemref)->isHidden()) { - elemref->deleteObject(); + 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); @@ -465,7 +468,9 @@ Effect::processObjects(LpeAction lpe_action) break; case LPE_ERASE: - elemref->deleteObject(); + sp_object_ref(item, 0 ); + item->deleteObject(true); + sp_object_unref(item); break; case LPE_VISIBILITY: diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index b29b5e493..3abcbf217 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -199,15 +199,13 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } } 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) { + if (SP_IS_PATH(dest) && shape) { SPCurve *c = NULL; if (root) { c = new SPCurve(); @@ -216,7 +214,7 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo c = shape->getCurve(); } if (c) { - path->setCurve(c, TRUE); + SP_PATH(dest)->setCurve(c, TRUE); c->unref(); } else { dest->getRepr()->setAttribute("d", NULL); @@ -725,6 +723,7 @@ LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) //set "keep paths" hook on sp-lpe-item.cpp if (keep_paths) { processObjects(LPE_TO_OBJECTS); + items.clear(); return; } processObjects(LPE_ERASE); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 3fcc4ae3d..5d80d65fe 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -320,6 +320,7 @@ LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) //set "keep paths" hook on sp-lpe-item.cpp if (keep_paths) { processObjects(LPE_TO_OBJECTS); + items.clear(); return; } processObjects(LPE_ERASE); diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp index b5b27c984..ca3ae46e0 100644 --- a/src/live_effects/lpeobject.cpp +++ b/src/live_effects/lpeobject.cpp @@ -112,6 +112,7 @@ void LivePathEffectObject::set(unsigned key, gchar const *value) { this->effecttype_set = true; } else { this->effecttype = Inkscape::LivePathEffect::INVALID_LPE; + this->lpe = NULL; this->effecttype_set = false; } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 5dfc60f1a..30c1096ca 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -408,7 +408,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()) { @@ -475,6 +475,12 @@ 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)*/ + if(this->getCurveBeforeLPE()) { + if(!force && this->getCurveBeforeLPE()->get_pathvector() == curve->get_pathvector()) { + curve->unref(); + return; + } + } this->setCurveInsync(curve, TRUE); this->setCurveBeforeLPE(curve); @@ -617,7 +623,7 @@ void SPGenericEllipse::modified(guint flags) void SPGenericEllipse::update_patheffect(bool write) { - this->set_shape(); + this->set_shape(true); if (write) { Inkscape::XML::Node *repr = this->getRepr(); diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index dafece625..a879c596d 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(); + 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; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 35e7dfa3e..be886bdd2 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -122,17 +122,8 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { 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() ) - { - if (!value) { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (lpe) { - lpe->doOnRemove(this); - } - } + 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); @@ -539,11 +530,11 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) 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->path_effect_list = new_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. @@ -563,15 +554,18 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) if (path_effect_list->empty()) { return; } - - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - lpe->keep_paths = true; - } + } + for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); + lpe->keep_paths = keep_paths; + lpe->doOnRemove(this); } + (*it)->unlink(); + delete *it; + it = this->path_effect_list->erase(it); } this->getRepr()->setAttribute("inkscape:path-effect", NULL); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 57eb918fe..d75db3daa 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -197,7 +197,7 @@ void SPSpiral::update(SPCtx *ctx, guint flags) { } void SPSpiral::update_patheffect(bool write) { - this->set_shape(); + this->set_shape(true); if (write) { Inkscape::XML::Node *repr = this->getRepr(); @@ -310,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"); @@ -365,6 +365,12 @@ void SPSpiral::set_shape() { /* 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()) { + c->unref(); + return; + } + } setCurveInsync( c, TRUE); setCurveBeforeLPE( c ); diff --git a/src/sp-spiral.h b/src/sp-spiral.h index 94724685c..ebf4c9e28 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(); + virtual void set_shape(bool force = false); virtual void update_patheffect(bool write); private: diff --git a/src/sp-star.cpp b/src/sp-star.cpp index d112962a2..d7ee352c7 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -223,7 +223,7 @@ void SPStar::update(SPCtx *ctx, guint flags) { } void SPStar::update_patheffect(bool write) { - this->set_shape(); + this->set_shape(true); if (write) { Inkscape::XML::Node *repr = this->getRepr(); @@ -363,7 +363,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) @@ -446,6 +446,12 @@ void SPStar::set_shape() { /* 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()) { + c->unref(); + return; + } + } this->setCurveInsync( c, TRUE); this->setCurveBeforeLPE( c ); diff --git a/src/sp-star.h b/src/sp-star.h index 1ebe3298a..4519de869 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(); + virtual void set_shape(bool force = false); virtual Geom::Affine set_transform(Geom::Affine const& xform); }; -- cgit v1.2.3 From 802385842d5a2fbe8def45b72ce433260720c954 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 29 May 2017 02:11:53 +0200 Subject: Initial release (bzr r15704) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 9 +- src/live_effects/effect.h | 3 +- src/live_effects/lpe-bspline.cpp | 4 +- src/live_effects/lpe-copy_rotate.cpp | 20 +- src/live_effects/lpe-fillet-chamfer.cpp | 4 +- src/live_effects/lpe-measure-line.cpp | 39 ++-- src/live_effects/lpe-mirror_symmetry.cpp | 43 +--- src/live_effects/lpe-mirror_symmetry.h | 1 - src/live_effects/lpe-powerclip.cpp | 297 +++++++++++++++++++++++++ src/live_effects/lpe-powerclip.h | 47 ++++ src/live_effects/lpe-transform_2pts.cpp | 4 +- src/live_effects/parameter/bool.cpp | 6 +- src/live_effects/parameter/bool.h | 4 +- src/live_effects/parameter/hidden.cpp | 8 +- src/live_effects/parameter/hidden.h | 5 +- src/live_effects/parameter/parameter.cpp | 13 +- src/live_effects/parameter/parameter.h | 9 +- src/live_effects/parameter/path.cpp | 104 +++++---- src/live_effects/parameter/path.h | 6 +- src/live_effects/parameter/satellitesarray.cpp | 1 + src/live_effects/parameter/satellitesarray.h | 1 + src/sp-lpe-item.cpp | 130 +++++++---- src/sp-lpe-item.h | 2 + src/ui/tools/node-tool.cpp | 7 +- 26 files changed, 587 insertions(+), 183 deletions(-) create mode 100644 src/live_effects/lpe-powerclip.cpp create mode 100644 src/live_effects/lpe-powerclip.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index c2f434f50..e1e5cab4c 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -36,6 +36,7 @@ set(live_effects_SRC lpe-perp_bisector.cpp lpe-perspective-envelope.cpp lpe-perspective_path.cpp + lpe-powerclip.cpp lpe-powerstroke.cpp lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp @@ -121,6 +122,7 @@ set(live_effects_SRC lpe-perspective-envelope.h lpe-perspective_path.h lpe-powerstroke-interpolators.h + lpe-powerclip.h lpe-powerstroke.h lpe-recursiveskeleton.h lpe-rough-hatches.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index a6920c1fb..700564334 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -49,6 +49,7 @@ enum EffectType { BOUNDING_BOX, MEASURE_LINE, FILLET_CHAMFER, + POWERCLIP, DOEFFECTSTACK_TEST, ANGLE_BISECTOR, CIRCLE_WITH_RADIUS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index a4b44b1a9..50976188a 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -47,6 +47,7 @@ #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-powerstroke.h" #include "live_effects/lpe-recursiveskeleton.h" #include "live_effects/lpe-roughen.h" @@ -124,6 +125,7 @@ const Util::EnumData LPETypeData[] = { /* 9.93 */ {MEASURE_LINE, N_("Measure Line"), "measure_line"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, + {POWERCLIP, N_("Power clip"), "powerclip"}, #ifdef LPE_ENABLE_TEST_EFFECTS {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"}, {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"}, @@ -302,6 +304,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case FILLET_CHAMFER: neweffect = static_cast ( new LPEFilletChamfer(lpeobj) ); break; + case POWERCLIP: + neweffect = static_cast ( new LPEPowerClip(lpeobj) ); + break; case ROUGHEN: neweffect = static_cast ( new LPERoughen(lpeobj) ); break; @@ -355,7 +360,8 @@ Effect::Effect(LivePathEffectObject *lpeobject) 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), - erase_extra_objects(true), + keep_paths(false), + is_load(true), lpeobj(lpeobject), concatenate_before_pwd2(false), sp_lpe_item(NULL), @@ -511,6 +517,7 @@ Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) { + is_load = false; } void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 60ee8d98f..e353eba23 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -132,7 +132,8 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_mask; - bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE + 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; SPCurve * sp_curve; diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index dbd67beda..721a4ecab 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -44,12 +44,12 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); - weight.param_overwrite_widget(true); + weight.param_set_undo(false); steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); - steps.param_overwrite_widget(true); + steps.param_set_undo(false); helper_size.param_set_range(0.0, 999.0); helper_size.param_set_increments(1, 1); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index ff24b46da..b29b5e493 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -96,6 +96,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : previous_num_copies = num_copies; previous_origin = Geom::Point(0,0); previous_start_point = Geom::Point(0,0); + starting_point.param_widget_is_visible(false); reset = false; } @@ -108,6 +109,7 @@ void LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem) { if (split_items) { + is_load = false; SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; @@ -319,14 +321,12 @@ Gtk::Widget * LPECopyRotate::newWidget() Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); Glib::ustring *tip = param->param_getTooltip(); if (widg) { - if (param->param_key != "starting_point") { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); } } } @@ -722,8 +722,8 @@ LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); return; } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 08ceab3c3..11298bcbe 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -38,7 +38,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) 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"), + "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", @@ -80,7 +80,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) radius.param_set_range(0.0, Geom::infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); - radius.param_overwrite_widget(true); + 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); diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index f7892cbe7..99828aef8 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -141,6 +141,7 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : helpline_overlap.param_set_digits(2); start_stored = Geom::Point(0,0); end_stored = Geom::Point(0,0); + id_origin.param_widget_is_visible(false); } LPEMeasureLine::~LPEMeasureLine() {} @@ -674,8 +675,8 @@ LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMeasureLine::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); items.clear(); return; @@ -700,24 +701,22 @@ Gtk::Widget *LPEMeasureLine::newWidget() while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; - if (param->param_key != "id_origin") { - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - if (param->param_key != "dimline_format" && - param->param_key != "helperlines_format" && - param->param_key != "arrows_format" && - param->param_key != "anotation_format") { - vbox->pack_start(*widg, true, true, 2); - } else { - vbox_expander->pack_start(*widg, true, true, 2); - } - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "dimline_format" && + param->param_key != "helperlines_format" && + param->param_key != "arrows_format" && + param->param_key != "anotation_format") { + vbox->pack_start(*widg, true, true, 2); + } else { + vbox_expander->pack_start(*widg, true, true, 2); + } + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); } } } diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index bd3dedc86..3fcc4ae3d 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -78,6 +78,8 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : 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); } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -87,6 +89,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() void LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) { + is_load = false; SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { return; @@ -304,42 +307,6 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform) } } -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; - if (param->param_key == "id_origin" || param->param_key == "center_point") { - ++it; - continue; - } - 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); -} - //TODO: Migrate the tree next function to effect.cpp/h to avoid duplication void LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) @@ -350,8 +317,8 @@ LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //unset "erase_extra_objects" hook on sp-lpe-item.cpp - if (!erase_extra_objects) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { processObjects(LPE_TO_OBJECTS); return; } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 07bb3d4fc..e98c83f2b 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -46,7 +46,6 @@ 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); // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); void cloneD(SPObject *orig, SPObject *dest, bool live, bool root); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp new file mode 100644 index 000000000..a3a827ec4 --- /dev/null +++ b/src/live_effects/lpe-powerclip.cpp @@ -0,0 +1,297 @@ +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "live_effects/lpe-powerclip.h" +#include <2geom/path-intersection.h> +#include <2geom/intersection-graph.h> +#include "display/drawing-item.h" +#include "display/curve.h" +#include "helper/geom.h" +#include "sp-clippath.h" +#include "sp-path.h" +#include "sp-shape.h" +#include "sp-item-group.h" +#include "ui/tools-switch.h" +#include "path-chemistry.h" + +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +namespace Inkscape { +namespace LivePathEffect { + +LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + hide_clip(_("Hide clip"), _("Hide clip"), "hide_clip", &wr, this, false), + inverse(_("Inverse clip"), _("Inverse clip"), "inverse", &wr, this, false), + flatten(_("Flatten clip"), _("Flatten clip"), "flatten", &wr, this, false), + fillrule(_("Set/unset evenodd fill rule"), _("Set/unset evenodd fill rule (this is overwriting your current value)."), "fillrule", &wr, this, false), + convert_shapes(_("Convert clip shapes to paths"), _("Convert clip shapes to paths (this is overwriting your current value)."), "convert_shapes", &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(&hide_clip); + registerParameter(&inverse); + registerParameter(&flatten); + registerParameter(&fillrule); + registerParameter(&convert_shapes); + registerParameter(&is_inverse); + is_clip = false; + previous_fillrule = fillrule; +} + +LPEPowerClip::~LPEPowerClip() {} + +void +LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ + original_bbox(lpeitem); + const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); + SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); + SPItem * item = SP_ITEM(lpeitem); + if(hide_clip) { + SPItemView *v; + for (v = item->display; v != NULL; v = v->next) { + clip_path->hide(v->arenaitem->key()); + } + Geom::OptRect bbox = item->geometricBounds(); + clip_path->setBBox(v->arenaitem->key(), bbox); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } else if (!hide_clip) { + Geom::OptRect bbox = item->geometricBounds(); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); + } + Inkscape::DrawingItem *ai = clip_path->show( + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setClip(ai); + clip_path->setBBox(v->arenaitem->key(), bbox); + clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + 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); + Geom::Point bottomleft = Geom::Point(boundingbox_X.min() - 5,boundingbox_Y.min() - 5); + clip_box.clear(); + clip_box.start(topleft); + clip_box.appendNew(topright); + clip_box.appendNew(bottomright); + clip_box.appendNew(bottomleft); + clip_box.close(); + //clip_path *= sp_lpe_item->i2dt_affine(); + if(clip_path) { + is_clip = true; + 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 (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(); + const char * id = clip_data->getId(); + Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(SP_ITEM(clip_data), 0); + clip_data->updateRepr(xml_doc, clip_path_node, SP_OBJECT_WRITE_ALL); + clip_data->getRepr()->setAttribute("id", id); + clip_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); + std::cout << "toshapes\n"; + } + if( inverse && isVisible()) { + addInverse(SP_ITEM(clip_data)); + } else if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + removeInverse(SP_ITEM(clip_data)); + } + } + } else { + is_clip = false; + } +} + +void +LPEPowerClip::addInverse (SPItem * clip_data){ + 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 (SP_IS_PATH(clip_data)) { + setFillRule(clip_data); + SPCurve * c = NULL; + c = SP_SHAPE(clip_data)->getCurve(); + if (c) { + Geom::PathVector c_pv = c->get_pathvector(); + if(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(); + } + 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); +// } +// } +// } + } + } +} + +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)); + 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)) { + setFillRule(clip_data); + SPCurve * c = NULL; + c = SP_SHAPE(clip_data)->getCurve(); + if (c) { + Geom::PathVector c_pv = c->get_pathvector(); + c_pv.pop_back(); + c->set_pathvector(c_pv); + SP_SHAPE(clip_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); +// } +// } +// } + } + } + } +} + +void +LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + SPClipPath *clip_path = SP_ITEM(sp_lpe_item)->clip_ref->getObject(); + if(!keep_paths) { + if(clip_path) { + is_clip = true; + 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") { + removeInverse(SP_ITEM(clip_data)); + is_inverse.param_setValue((Glib::ustring)"false"); + } + } + } + } else { + if (flatten && clip_path) { + clip_path->deleteObject(); + sp_lpe_item->getRepr()->setAttribute("clip-path", NULL); + } + } +} + +Geom::PathVector +LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ + Geom::PathVector path_out = pathv_to_linear_and_cubic_beziers(path_in); + if (flatten && is_clip && isVisible()) { + SPClipPath *clip_path = SP_ITEM(sp_lpe_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; + flattenClip(SP_ITEM(clip_data), path_out); + } + } + } + return path_out; +} + +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)); + 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)) { + if (!SP_IS_PATH(clip_data) && convert_shapes) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + const char * id = clip_data->getId(); + Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(clip_data, 0); + clip_data->updateRepr(xml_doc, clip_path_node, SP_OBJECT_WRITE_ALL); + clip_data->getRepr()->setAttribute("id", id); + } + SPCurve * c = NULL; + 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); + if (pig && !c_pv.empty() && !path_in.empty()) { + path_in = pig->getIntersection(); + } + c->unref(); + } + } +} + +void +LPEPowerClip::setFillRule(SPItem * clip_data) +{ + if (previous_fillrule != fillrule) { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, clip_data->getRepr()->attribute("style")); + if (fillrule) { + sp_repr_css_set_property (css, "fill-rule", "evenodd"); + } else { + sp_repr_css_set_property (css, "fill-rule", "nonzero"); + } + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + clip_data->getRepr()->setAttribute("style", css_str.c_str()); + previous_fillrule = fillrule; + } +} + +}; //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-powerclip.h b/src/live_effects/lpe-powerclip.h new file mode 100644 index 000000000..8ff8111e8 --- /dev/null +++ b/src/live_effects/lpe-powerclip.h @@ -0,0 +1,47 @@ +#ifndef INKSCAPE_LPE_POWERCLIP_H +#define INKSCAPE_LPE_POWERCLIP_H + +/* + * Inkscape::LPEPowerClip + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/hidden.h" +#include "live_effects/parameter/path.h" +#include "live_effects/lpegroupbbox.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEPowerClip : public Effect, GroupBBoxEffect { +public: + LPEPowerClip(LivePathEffectObject *lpeobject); + 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 doOnRemove (SPLPEItem const* /*lpeitem*/); + void addInverse (SPItem * clip_data); + void removeInverse (SPItem * clip_data); + void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); + void setFillRule(SPItem * clip_data); +protected: + //virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); + +private: + BoolParam hide_clip; + BoolParam inverse; + BoolParam flatten; + BoolParam fillrule; + BoolParam convert_shapes; + HiddenParam is_inverse; + Geom::Path clip_box; + bool is_clip; + bool previous_fillrule; +}; + +} //namespace LivePathEffect +} //namespace Inkscape +#endif diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index f4d233d56..ab05b880c 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -64,9 +64,9 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : registerParameter(&lock_angle); first_knot.param_make_integer(true); - first_knot.param_overwrite_widget(true); + first_knot.param_set_undo(false); last_knot.param_make_integer(true); - last_knot.param_overwrite_widget(true); + last_knot.param_set_undo(false); helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 3184bfa80..954947cf4 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -21,8 +21,8 @@ namespace LivePathEffect { BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value , bool no_widget) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), hide_widget(no_widget) + Effect* effect, bool default_value) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) { } @@ -65,7 +65,7 @@ BoolParam::param_getSVGValue() const Gtk::Widget * BoolParam::param_newWidget() { - if(!hide_widget){ + if(widget_is_visible){ Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( new Inkscape::UI::Widget::RegisteredCheckButton( param_label, param_tooltip, diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index 39f328eaa..417752050 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -25,8 +25,7 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - bool default_value = false, - bool no_widget = false); + bool default_value = false); virtual ~BoolParam(); virtual Gtk::Widget * param_newWidget(); @@ -47,7 +46,6 @@ private: bool value; bool defvalue; - bool hide_widget; }; diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 2f218847a..e8c55ebd3 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -22,11 +22,12 @@ namespace LivePathEffect { HiddenParam::HiddenParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const Glib::ustring default_value ) + Effect* effect, const Glib::ustring default_value, bool is_visible) : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) { + param_widget_is_visible(is_visible); } void @@ -65,9 +66,12 @@ HiddenParam::param_newWidget() } void -HiddenParam::param_setValue(const Glib::ustring newvalue) +HiddenParam::param_setValue(const Glib::ustring newvalue, bool write) { value = newvalue; + if (write) { + param_write_to_repr(value.c_str()); + } } } /* namespace LivePathEffect */ diff --git a/src/live_effects/parameter/hidden.h b/src/live_effects/parameter/hidden.h index d565272b6..c3fba5575 100644 --- a/src/live_effects/parameter/hidden.h +++ b/src/live_effects/parameter/hidden.h @@ -29,7 +29,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - const Glib::ustring default_value = ""); + const Glib::ustring default_value = "", + bool widget_is_visible = false); virtual ~HiddenParam() {} virtual Gtk::Widget * param_newWidget(); @@ -37,7 +38,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue); virtual gchar * param_getSVGValue() const; - void param_setValue(Glib::ustring newvalue); + void param_setValue(Glib::ustring newvalue, bool write = false); virtual void param_set_default(); virtual void param_update_default(const gchar * default_value); diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 45f46a0a7..2f73488aa 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -55,7 +55,7 @@ void Parameter::write_to_SVG(void) */ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, gdouble default_value, bool no_widget) + Effect* effect, gdouble default_value) : Parameter(label, tip, key, wr, effect), value(default_value), min(-SCALARPARAM_G_MAXDOUBLE), @@ -66,8 +66,7 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, inc_step(0.1), inc_page(1), add_slider(false), - overwrite_widget(false), - hide_widget(no_widget) + _set_undo(true) { } @@ -164,15 +163,15 @@ ScalarParam::param_make_integer(bool yes) } void -ScalarParam::param_overwrite_widget(bool overwrite_widget) +ScalarParam::param_set_undo(bool set_undo) { - this->overwrite_widget = overwrite_widget; + _set_undo = set_undo; } Gtk::Widget * ScalarParam::param_newWidget() { - if(!hide_widget){ + if(widget_is_visible){ Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); @@ -184,7 +183,7 @@ ScalarParam::param_newWidget() if (add_slider) { rsu->addSlider(); } - if(!overwrite_widget){ + if(_set_undo){ rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } return dynamic_cast (rsu); diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index ee1d2d547..7ab7e30dd 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -57,6 +57,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted. virtual gchar * param_getSVGValue() const = 0; + virtual void param_widget_is_visible(bool is_visible) {widget_is_visible = is_visible;} void write_to_SVG(); virtual void param_set_default() = 0; @@ -103,8 +104,7 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - gdouble default_value = 1.0, - bool no_widget = false); + gdouble default_value = 1.0); virtual ~ScalarParam(); virtual bool param_readSVGValue(const gchar * strvalue); @@ -121,7 +121,7 @@ public: void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; }; double param_get_max() { return max; }; double param_get_min() { return min; }; - void param_overwrite_widget(bool overwrite_widget); + void param_set_undo(bool set_undo); virtual Gtk::Widget * param_newWidget(); inline operator gdouble() const { return value; }; @@ -136,8 +136,7 @@ protected: double inc_step; double inc_page; bool add_slider; - bool overwrite_widget; - bool hide_widget; + bool _set_undo; private: ScalarParam(const ScalarParam&); diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 6e90c9279..54f5d93e8 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -69,7 +69,10 @@ PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip, defvalue = g_strdup(default_value); param_readSVGValue(defvalue); oncanvas_editable = true; - + _edit_button = true; + _copy_button = true; + _paste_button = true; + _link_button = true; ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &PathParam::ref_changed)); } @@ -167,6 +170,15 @@ PathParam::param_getSVGValue() const } } +void +PathParam::set_buttons(bool edit_button, bool copy_button, bool paste_button, bool link_button) +{ + _edit_button = edit_button; + _copy_button = copy_button; + _paste_button = paste_button; + _link_button = link_button; +} + Gtk::Widget * PathParam::param_newWidget() { @@ -175,47 +187,55 @@ PathParam::param_newWidget() Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label)); static_cast(_widget)->pack_start(*pLabel, true, true); pLabel->set_tooltip_text(param_tooltip); - - Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("tool-node-editor"), Inkscape::ICON_SIZE_BUTTON) ); - Gtk::Button * pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Edit on-canvas")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-copy"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_copy_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Copy path")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Paste path")); - - pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); - pButton = Gtk::manage(new Gtk::Button()); - pButton->set_relief(Gtk::RELIEF_NONE); - pIcon->show(); - pButton->add(*pIcon); - pButton->show(); - pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); - static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to path on clipboard")); - + Gtk::Widget * pIcon = NULL; + Gtk::Button * pButton = NULL; + if (_edit_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("tool-node-editor"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Edit on-canvas")); + } + + if (_copy_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-copy"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_copy_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Copy path")); + } + + if (_paste_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-paste"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_paste_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Paste path")); + } + if (_link_button) { + pIcon = Gtk::manage( sp_icon_get_icon( INKSCAPE_ICON("edit-clone"), Inkscape::ICON_SIZE_BUTTON) ); + pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); + static_cast(_widget)->pack_start(*pButton, true, true); + pButton->set_tooltip_text(_("Link to path on clipboard")); + } + static_cast(_widget)->show_all_children(); return dynamic_cast (_widget); diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h index 5381a6b36..ff5e4f1b8 100644 --- a/src/live_effects/parameter/path.h +++ b/src/live_effects/parameter/path.h @@ -44,7 +44,7 @@ public: void param_set_and_write_default(); void set_new_value (Geom::PathVector const &newpath, bool write_to_svg); void set_new_value (Geom::Piecewise > const &newpath, bool write_to_svg); - + void set_buttons(bool edit_button, bool copy_button, bool paste_button, bool link_button); virtual void param_editOncanvas(SPItem * item, SPDesktop * dt); virtual void param_setup_nodepath(Inkscape::NodePath::Path *np); virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector &hp_vec); @@ -91,6 +91,10 @@ protected: gchar * defvalue; private: + bool _edit_button; + bool _copy_button; + bool _paste_button; + bool _link_button; PathParam(const PathParam&); PathParam& operator=(const PathParam&); }; diff --git a/src/live_effects/parameter/satellitesarray.cpp b/src/live_effects/parameter/satellitesarray.cpp index 7626317a1..ce4da243e 100644 --- a/src/live_effects/parameter/satellitesarray.cpp +++ b/src/live_effects/parameter/satellitesarray.cpp @@ -37,6 +37,7 @@ SatellitesArrayParam::SatellitesArrayParam(const Glib::ustring &label, _current_zoom = 0; _effectType = FILLET_CHAMFER; _last_pathvector_satellites = NULL; + param_widget_is_visible(false); } diff --git a/src/live_effects/parameter/satellitesarray.h b/src/live_effects/parameter/satellitesarray.h index 5ae372ac2..300a7a9dd 100644 --- a/src/live_effects/parameter/satellitesarray.h +++ b/src/live_effects/parameter/satellitesarray.h @@ -57,6 +57,7 @@ public: void setEffectType(EffectType et); void setPathVectorSatellites(PathVectorSatellites *pathVectorSatellites, bool write = true); void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + bool widget_is_visible; friend class FilletChamferKnotHolderEntity; friend class LPEFilletChamfer; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index efb1f4353..228263be4 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); +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); @@ -129,16 +129,15 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { if (!value) { LivePathEffectObject *lpeobj = (*it)->lpeobject; Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe) || - dynamic_cast(lpe) || - dynamic_cast(lpe) ) - { + if (lpe) { lpe->doOnRemove(this); } + ++it; + } else { + (*it)->unlink(); + delete *it; + it = this->path_effect_list->erase(it); } - (*it)->unlink(); - delete *it; - it = this->path_effect_list->erase(it); } // Parse the contents of "value" to rebuild the path effect reference list @@ -212,6 +211,46 @@ 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. */ @@ -220,6 +259,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip 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) { @@ -245,6 +285,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip // 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) { @@ -272,7 +315,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } } } - if(!SP_IS_GROUP(this) && !is_clip_or_mask){ + if(!SP_IS_GROUP(this) && !is_clip_or_mask && has_clipormask_lpe){ this->apply_to_clippath(this); this->apply_to_mask(this); } @@ -363,48 +406,49 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) } static void -sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) +sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths) { g_return_if_fail(lpeitem != NULL); - if (SP_IS_GROUP(lpeitem)) { - if (!lpeitem->hasPathEffectRecursive()) { + if (!lpeitem->hasPathEffectOnClipOrMaskRecursive()) { SPMask * mask = lpeitem->mask_ref->getObject(); if(mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + 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())); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild()), keep_paths); } } 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)); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem), keep_paths); } } - } - else if (SP_IS_PATH(lpeitem)) { + } else if (SP_IS_PATH(lpeitem)) { Inkscape::XML::Node *repr = lpeitem->getRepr(); - if (!lpeitem->hasPathEffectRecursive() && 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())); - } - SPClipPath * clip_path = lpeitem->clip_ref->getObject(); - if(clip_path) - { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clip_path->firstChild())); + 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("d", repr->attribute("inkscape:original-d")); repr->setAttribute("inkscape:original-d", NULL); - } - else { + } else { sp_lpe_item_update_patheffect(lpeitem, true, true); } } @@ -458,7 +502,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; @@ -499,9 +552,8 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) 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); } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); } /** @@ -519,7 +571,7 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj) { Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); - lpe->erase_extra_objects = false; + lpe->keep_paths = true; } } } @@ -531,9 +583,8 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) 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); } + sp_lpe_item_cleanup_original_path_recursive(this, keep_paths); } void SPLPEItem::downCurrentPathEffect() @@ -554,7 +605,7 @@ void SPLPEItem::downCurrentPathEffect() this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - sp_lpe_item_cleanup_original_path_recursive(this); + sp_lpe_item_cleanup_original_path_recursive(this, false); } void SPLPEItem::upCurrentPathEffect() @@ -573,7 +624,7 @@ void SPLPEItem::upCurrentPathEffect() this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); - sp_lpe_item_cleanup_original_path_recursive(this); + 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= */ @@ -645,6 +696,7 @@ bool SPLPEItem::hasPathEffectRecursive() const return hasPathEffect(); } } + void SPLPEItem::apply_to_clippath(SPItem *item) { @@ -800,7 +852,7 @@ void SPLPEItem::remove_child(Inkscape::XML::Node * child) { 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)); + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild), false); } } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 0f198c49c..d5d4e118b 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -70,6 +70,8 @@ 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 pathEffectsEnabled() const; diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 0c948c91c..5daedcd02 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -368,7 +368,10 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape } //XML Tree being used directly here while it shouldn't be. - if (SP_IS_PATH(obj) && obj->getRepr()->attribute("inkscape:original-d") != NULL) { + if (SP_IS_PATH(obj) && + obj->getRepr()->attribute("inkscape:original-d") != NULL && + !SP_LPE_ITEM(obj)->hasPathEffectOfType(LivePathEffect::POWERCLIP)) + { ShapeRecord r; r.item = static_cast(obj); r.edit_transform = Geom::identity(); // TODO wrong? @@ -383,7 +386,7 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape ShapeRecord r; r.item = item; // TODO add support for objectBoundingBox - r.edit_transform = base ? base->i2doc_affine() : Geom::identity(); + r.edit_transform = base || role == SHAPE_ROLE_CLIPPING_PATH ? base->i2doc_affine() : Geom::identity(); r.role = role; if (s.insert(r).second) { -- cgit v1.2.3 From 18619e3328e070c5d59f12c4d19fa09713fc4700 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Mon, 29 May 2017 04:23:48 +0200 Subject: Handling hide (bzr r15706) --- src/display/drawing-item.h | 2 ++ src/live_effects/lpe-powerclip.cpp | 46 +++++++++++++++++++++++++------------- src/sp-clippath.cpp | 10 ++++++--- 3 files changed, 39 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 21f6ffacc..1df60d783 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -120,7 +120,9 @@ public: void setBlendMode(unsigned blend_mode); void setTransform(Geom::Affine const &trans); void setClip(DrawingItem *item); + DrawingItem * getClip(){ return _clip;} void setMask(DrawingItem *item); + DrawingItem * getMask(){ return _mask;} void setFillPattern(DrawingPattern *pattern); void setStrokePattern(DrawingPattern *pattern); void setZOrder(unsigned z); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index a3a827ec4..275acef1e 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -17,6 +17,14 @@ // TODO due to internal breakage in glibmm headers, this must be last: #include +// FIXME: expose these from sp-clippath/mask.cpp +struct SPClipPathView { + SPClipPathView *next; + unsigned int key; + Inkscape::DrawingItem *arenaitem; + Geom::OptRect bbox; +}; + namespace Inkscape { namespace LivePathEffect { @@ -48,28 +56,34 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); SPItem * item = SP_ITEM(lpeitem); - if(hide_clip) { + bool update_lpe = false; + if(clip_path && hide_clip) { SPItemView *v; for (v = item->display; v != NULL; v = v->next) { - clip_path->hide(v->arenaitem->key()); + if (clip_path->display->arenaitem && clip_path->display->arenaitem->visible()) { + clip_path->hide(v->arenaitem->key()); + update_lpe = true; + } } - Geom::OptRect bbox = item->geometricBounds(); - clip_path->setBBox(v->arenaitem->key(), bbox); - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } else if (!hide_clip) { + } else if (clip_path && !hide_clip) { Geom::OptRect bbox = item->geometricBounds(); for (SPItemView *v = item->display; v != NULL; v = v->next) { - if (!v->arenaitem->key()) { - v->arenaitem->setKey(SPItem::display_key_new(3)); - } - Inkscape::DrawingItem *ai = clip_path->show( - v->arenaitem->drawing(), - v->arenaitem->key()); - v->arenaitem->setClip(ai); - clip_path->setBBox(v->arenaitem->key(), bbox); - clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + if (!clip_path->display->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); + } + if (clip_path->display->arenaitem && !clip_path->display->arenaitem->visible()) { + Inkscape::DrawingItem *ai = clip_path->show( + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setClip(ai); + clip_path->setBBox(v->arenaitem->key(), bbox); + update_lpe = true; + } } - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + if (update_lpe) { + clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + sp_lpe_item_update_patheffect(sp_lpe_item, true, true); } 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); diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index b371e15b2..16b769d53 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -35,7 +35,6 @@ struct SPClipPathView { 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); @@ -227,15 +226,20 @@ void SPClipPath::hide(unsigned int key) { SP_ITEM(&child)->invoke_hide(key); } } - + bool is_hided = false; for (SPClipPathView *v = display; v != NULL; v = v->next) { + if (!v->arenaitem->getClip()) { + is_hided = true; + } if (v->key == key) { /* We simply unref and let item to manage this in handler */ display = sp_clippath_view_list_remove(display, v); return; } } - + if (is_hided) { + return; + } g_assert_not_reached(); } -- cgit v1.2.3 From 68650ca3a1fad4d26bcb6f3fc49f07ffc6e7e426 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 May 2017 15:09:06 +0200 Subject: Update for CSS 3 'image-rendering'. (bzr r15703.1.11) --- src/display/drawing-image.cpp | 10 ++++++++-- src/style-enums.h | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index e23c89c59..508fcc503 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -116,16 +116,22 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar if (_style) { // See: http://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty // http://www.w3.org/TR/css4-images/#the-image-rendering + // It's back in CSS Images 3 now. // style.h/style.cpp switch (_style->image_rendering.computed) { case SP_CSS_IMAGE_RENDERING_AUTO: - // Do nothing - break; case SP_CSS_IMAGE_RENDERING_OPTIMIZEQUALITY: + case SP_CSS_IMAGE_RENDERING_CRISPEDGES: + // CSS 3 defines: + // 'auto' to use smoothing + // 'optimize-quality' as alias for auto + // We don't have special rendering for 'crisp-edges' yet + // so follow what browsers do. // In recent Cairo, BEST used Lanczos3, which is prohibitively slow dc.patternSetFilter( CAIRO_FILTER_GOOD ); break; case SP_CSS_IMAGE_RENDERING_OPTIMIZESPEED: + case SP_CSS_IMAGE_RENDERING_PIXELATED: default: dc.patternSetFilter( CAIRO_FILTER_NEAREST ); break; diff --git a/src/style-enums.h b/src/style-enums.h index a0fcaedef..4ea656794 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -640,8 +640,8 @@ static SPStyleEnum const enum_image_rendering[] = { {"auto", SP_CSS_IMAGE_RENDERING_AUTO}, {"optimizeSpeed", SP_CSS_IMAGE_RENDERING_OPTIMIZESPEED}, {"optimizeQuality", SP_CSS_IMAGE_RENDERING_OPTIMIZEQUALITY}, - {"-inkscape-crisp-edges", SP_CSS_IMAGE_RENDERING_CRISPEDGES}, - {"-inkscape-pixelated", SP_CSS_IMAGE_RENDERING_PIXELATED}, + {"crisp-edges", SP_CSS_IMAGE_RENDERING_CRISPEDGES}, + {"pixelated", SP_CSS_IMAGE_RENDERING_PIXELATED}, {NULL, -1} }; -- cgit v1.2.3 From d0a7d52e1775c5cf26e8de2263f3077001f71907 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 May 2017 15:26:04 +0200 Subject: Fix PDF export with respect to 'image-rendering'. (bzr r15703.1.12) --- src/extension/internal/cairo-render-context.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 06711bca4..21902db7d 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1580,13 +1580,13 @@ bool CairoRenderContext::renderImage(Inkscape::Pixbuf *pb, // http://www.w3.org/TR/css4-images/#the-image-rendering // style.h/style.cpp switch (style->image_rendering.computed) { - case SP_CSS_COLOR_RENDERING_AUTO: - // Do nothing - break; - case SP_CSS_COLOR_RENDERING_OPTIMIZEQUALITY: + case SP_CSS_IMAGE_RENDERING_AUTO: + case SP_CSS_IMAGE_RENDERING_OPTIMIZEQUALITY: + case SP_CSS_IMAGE_RENDERING_CRISPEDGES: cairo_pattern_set_filter(cairo_get_source(_cr), CAIRO_FILTER_BEST ); break; - case SP_CSS_COLOR_RENDERING_OPTIMIZESPEED: + case SP_CSS_IMAGE_RENDERING_OPTIMIZESPEED: + case SP_CSS_IMAGE_RENDERING_PIXELATED: default: cairo_pattern_set_filter(cairo_get_source(_cr), CAIRO_FILTER_NEAREST ); break; -- cgit v1.2.3 From 38d796905f3b0e467d9e653c51f2993870f033cf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 29 May 2017 17:33:21 +0200 Subject: Allow temp hide clip (bzr r15707) --- src/live_effects/lpe-powerclip.cpp | 39 +++++++++++++++++++------------------- src/live_effects/lpe-powerclip.h | 1 + src/sp-clippath.cpp | 8 +++----- 3 files changed, 23 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 275acef1e..7ab662bbc 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -30,7 +30,7 @@ namespace LivePathEffect { LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) : Effect(lpeobject), - hide_clip(_("Hide clip"), _("Hide clip"), "hide_clip", &wr, this, false), + hide_clip(_("Temporary hide"), _("Hide clip, not storeable, reset on doc load"), "hide_clip", &wr, this, false), inverse(_("Inverse clip"), _("Inverse clip"), "inverse", &wr, this, false), flatten(_("Flatten clip"), _("Flatten clip"), "flatten", &wr, this, false), fillrule(_("Set/unset evenodd fill rule"), _("Set/unset evenodd fill rule (this is overwriting your current value)."), "fillrule", &wr, this, false), @@ -38,53 +38,52 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) //tooltip empty to no show in default param set is_inverse("Store the last inverse apply", "", "is_inverse", &wr, this, "false", false) { - registerParameter(&hide_clip); registerParameter(&inverse); registerParameter(&flatten); registerParameter(&fillrule); registerParameter(&convert_shapes); registerParameter(&is_inverse); + registerParameter(&hide_clip); is_clip = false; previous_fillrule = fillrule; + previous_hide_clip = false; } LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ - original_bbox(lpeitem); + if (is_load) { + hide_clip.param_setValue(false); + } const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); SPItem * item = SP_ITEM(lpeitem); - bool update_lpe = false; - if(clip_path && hide_clip) { - SPItemView *v; - for (v = item->display; v != NULL; v = v->next) { - if (clip_path->display->arenaitem && clip_path->display->arenaitem->visible()) { + if (!is_load) { + if(clip_path && hide_clip && previous_hide_clip != hide_clip) { + SPItemView *v; + for (v = item->display; v != NULL; v = v->next) { clip_path->hide(v->arenaitem->key()); - update_lpe = true; - } - } - } else if (clip_path && !hide_clip) { - Geom::OptRect bbox = item->geometricBounds(); - for (SPItemView *v = item->display; v != NULL; v = v->next) { - if (!clip_path->display->arenaitem->key()) { - v->arenaitem->setKey(SPItem::display_key_new(3)); } - if (clip_path->display->arenaitem && !clip_path->display->arenaitem->visible()) { + } else if (clip_path && !hide_clip && previous_hide_clip != hide_clip) { + Geom::OptRect bbox = item->geometricBounds(); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); + } Inkscape::DrawingItem *ai = clip_path->show( v->arenaitem->drawing(), v->arenaitem->key()); v->arenaitem->setClip(ai); clip_path->setBBox(v->arenaitem->key(), bbox); - update_lpe = true; } } } - if (update_lpe) { + if(!is_load && previous_hide_clip != hide_clip) { clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - sp_lpe_item_update_patheffect(sp_lpe_item, true, true); } + previous_hide_clip = hide_clip; + original_bbox(lpeitem); 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); diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 8ff8111e8..bf3eeac0d 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -40,6 +40,7 @@ private: Geom::Path clip_box; bool is_clip; bool previous_fillrule; + bool previous_hide_clip; }; } //namespace LivePathEffect diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 16b769d53..619f7c65e 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -226,18 +226,16 @@ void SPClipPath::hide(unsigned int key) { SP_ITEM(&child)->invoke_hide(key); } } - bool is_hided = false; + bool no_clippathview = true; for (SPClipPathView *v = display; v != NULL; v = v->next) { - if (!v->arenaitem->getClip()) { - is_hided = true; - } + no_clippathview = false; if (v->key == key) { /* We simply unref and let item to manage this in handler */ display = sp_clippath_view_list_remove(display, v); return; } } - if (is_hided) { + if (no_clippathview) { return; } g_assert_not_reached(); -- cgit v1.2.3 From eb70ace04dd450317b08d1c3e48ff087f9cfe775 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 29 May 2017 17:41:44 +0200 Subject: Alow write to repr on hidden LPE parameters (bzr r15703.1.13) --- src/live_effects/parameter/hidden.cpp | 5 ++++- src/live_effects/parameter/hidden.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/hidden.cpp b/src/live_effects/parameter/hidden.cpp index 6d0e7f58f..e8c55ebd3 100644 --- a/src/live_effects/parameter/hidden.cpp +++ b/src/live_effects/parameter/hidden.cpp @@ -66,9 +66,12 @@ HiddenParam::param_newWidget() } void -HiddenParam::param_setValue(const Glib::ustring newvalue) +HiddenParam::param_setValue(const Glib::ustring newvalue, bool write) { value = newvalue; + if (write) { + param_write_to_repr(value.c_str()); + } } } /* namespace LivePathEffect */ diff --git a/src/live_effects/parameter/hidden.h b/src/live_effects/parameter/hidden.h index 387071e53..c3fba5575 100644 --- a/src/live_effects/parameter/hidden.h +++ b/src/live_effects/parameter/hidden.h @@ -38,7 +38,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue); virtual gchar * param_getSVGValue() const; - void param_setValue(Glib::ustring newvalue); + void param_setValue(Glib::ustring newvalue, bool write = false); virtual void param_set_default(); virtual void param_update_default(const gchar * default_value); -- cgit v1.2.3 From 15adf7b6003d6956e38ccf42a65d0e883bac2731 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 29 May 2017 19:26:57 +0200 Subject: Add toggle clip bisibility button (bzr r15709) --- src/display/drawing-item.h | 2 - src/live_effects/lpe-powerclip.cpp | 148 +++++++++++++++++---------- src/live_effects/lpe-powerclip.h | 4 +- src/live_effects/parameter/satellitesarray.h | 1 - src/sp-clippath.cpp | 1 + src/ui/tools/node-tool.cpp | 2 +- 6 files changed, 99 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 1df60d783..21f6ffacc 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -120,9 +120,7 @@ public: void setBlendMode(unsigned blend_mode); void setTransform(Geom::Affine const &trans); void setClip(DrawingItem *item); - DrawingItem * getClip(){ return _clip;} void setMask(DrawingItem *item); - DrawingItem * getMask(){ return _mask;} void setFillPattern(DrawingPattern *pattern); void setStrokePattern(DrawingPattern *pattern); void setZOrder(unsigned z); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 7ab662bbc..bbbe733fe 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -30,7 +30,6 @@ namespace LivePathEffect { LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) : Effect(lpeobject), - hide_clip(_("Temporary hide"), _("Hide clip, not storeable, reset on doc load"), "hide_clip", &wr, this, false), inverse(_("Inverse clip"), _("Inverse clip"), "inverse", &wr, this, false), flatten(_("Flatten clip"), _("Flatten clip"), "flatten", &wr, this, false), fillrule(_("Set/unset evenodd fill rule"), _("Set/unset evenodd fill rule (this is overwriting your current value)."), "fillrule", &wr, this, false), @@ -43,47 +42,18 @@ LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) registerParameter(&fillrule); registerParameter(&convert_shapes); registerParameter(&is_inverse); - registerParameter(&hide_clip); is_clip = false; previous_fillrule = fillrule; - previous_hide_clip = false; + hide_clip = false; } LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ - if (is_load) { - hide_clip.param_setValue(false); - } + original_bbox(lpeitem); const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_ref->getObject(); - SPItem * item = SP_ITEM(lpeitem); - if (!is_load) { - if(clip_path && hide_clip && previous_hide_clip != hide_clip) { - SPItemView *v; - for (v = item->display; v != NULL; v = v->next) { - clip_path->hide(v->arenaitem->key()); - } - } else if (clip_path && !hide_clip && previous_hide_clip != hide_clip) { - Geom::OptRect bbox = item->geometricBounds(); - for (SPItemView *v = item->display; v != NULL; v = v->next) { - if (!v->arenaitem->key()) { - v->arenaitem->setKey(SPItem::display_key_new(3)); - } - Inkscape::DrawingItem *ai = clip_path->show( - v->arenaitem->drawing(), - v->arenaitem->key()); - v->arenaitem->setClip(ai); - clip_path->setBBox(v->arenaitem->key(), bbox); - } - } - } - if(!is_load && previous_hide_clip != hide_clip) { - clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - previous_hide_clip = hide_clip; - original_bbox(lpeitem); 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); @@ -152,17 +122,17 @@ LPEPowerClip::addInverse (SPItem * clip_data){ 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); -// } -// } -// } + 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); + } + } + } } } } @@ -187,22 +157,92 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ SP_SHAPE(clip_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); -// } -// } -// } + 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); + } + } + } + } + } + } +} + +void +LPEPowerClip::toggleClip() { + SPItem * item = SP_ITEM(sp_lpe_item); + if (item) { + SPClipPath *clip_path = item->clip_ref->getObject(); + if (clip_path) { + hide_clip = !hide_clip; + if(hide_clip) { + SPItemView *v; + for (v = item->display; v != NULL; v = v->next) { + clip_path->hide(v->arenaitem->key()); + } + } else { + Geom::OptRect bbox = item->geometricBounds(); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); + } + Inkscape::DrawingItem *ai = clip_path->show( + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setClip(ai); + clip_path->setBBox(v->arenaitem->key(), bbox); + } } + clip_path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } +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); + 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); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*toggle_button, false, false,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()); + if(param->param_key == "grid") { + widg = NULL; + } + 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); +} + void LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) { diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index bf3eeac0d..63594cfd8 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -23,6 +23,8 @@ public: 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 toggleClip(); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); @@ -31,7 +33,6 @@ protected: //virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: - BoolParam hide_clip; BoolParam inverse; BoolParam flatten; BoolParam fillrule; @@ -39,6 +40,7 @@ private: HiddenParam is_inverse; Geom::Path clip_box; bool is_clip; + bool hide_clip; bool previous_fillrule; bool previous_hide_clip; }; diff --git a/src/live_effects/parameter/satellitesarray.h b/src/live_effects/parameter/satellitesarray.h index 300a7a9dd..5ae372ac2 100644 --- a/src/live_effects/parameter/satellitesarray.h +++ b/src/live_effects/parameter/satellitesarray.h @@ -57,7 +57,6 @@ public: void setEffectType(EffectType et); void setPathVectorSatellites(PathVectorSatellites *pathVectorSatellites, bool write = true); void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); - bool widget_is_visible; friend class FilletChamferKnotHolderEntity; friend class LPEFilletChamfer; diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 619f7c65e..b26a2cbf2 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -35,6 +35,7 @@ struct SPClipPathView { 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/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 5daedcd02..eb4538057 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -386,7 +386,7 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape ShapeRecord r; r.item = item; // TODO add support for objectBoundingBox - r.edit_transform = base || role == SHAPE_ROLE_CLIPPING_PATH ? base->i2doc_affine() : Geom::identity(); + r.edit_transform = base ? base->i2doc_affine() : Geom::identity(); r.role = role; if (s.insert(r).second) { -- cgit v1.2.3 From 4e2d5438baa826e8c46df6d463e2a00345d3dace Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 29 May 2017 22:51:48 +0200 Subject: Working on hide (bzr r15711) --- src/ui/tools/node-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index eb4538057..6004a0de9 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -370,7 +370,7 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape //XML Tree being used directly here while it shouldn't be. if (SP_IS_PATH(obj) && obj->getRepr()->attribute("inkscape:original-d") != NULL && - !SP_LPE_ITEM(obj)->hasPathEffectOfType(LivePathEffect::POWERCLIP)) + !SP_LPE_ITEM(obj)->hasPathEffectOfType(Inkscape::LivePathEffect::POWERCLIP)) { ShapeRecord r; r.item = static_cast(obj); -- cgit v1.2.3 From 9af2f222d8c7e9775422355f3918e3cf6fe8d8ab Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 30 May 2017 16:46:49 +0200 Subject: Fix bug pointed by parclytaxel in IRC (bzr r15703.1.15) --- src/sp-lpe-item.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index be886bdd2..1333642e9 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -555,19 +555,18 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) return; } } - for (PathEffectList::const_iterator it = path_effect_list->begin(); it != path_effect_list->end(); ++it) - { + while ( it != this->path_effect_list->end() ) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj) { Inkscape::LivePathEffect::Effect * lpe = lpeobj->get_lpe(); lpe->keep_paths = keep_paths; lpe->doOnRemove(this); } + // unlink and delete all references in the list (*it)->unlink(); delete *it; it = this->path_effect_list->erase(it); } - this->getRepr()->setAttribute("inkscape:path-effect", NULL); if (!keep_paths) { -- cgit v1.2.3 From 61737e7c412d328473b63fb00c2f0a14a8dc0f38 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 30 May 2017 17:22:35 +0200 Subject: Fix broken fix for bug pointed by parclytaxel in IRC (bzr r15703.1.16) --- src/sp-lpe-item.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 1333642e9..84d318db2 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -555,6 +555,9 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) return; } } + + PathEffectList::iterator it = this->path_effect_list->begin(); + while ( it != this->path_effect_list->end() ) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj) { -- cgit v1.2.3 From 12b4b31445623bab440dd00a122bcdcd697ed044 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 31 May 2017 13:59:57 +0200 Subject: Sort File Save and File Input file type menus. (bzr r15703.1.17) --- src/extension/db.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/db.cpp b/src/extension/db.cpp index f17b784a9..e885d3531 100644 --- a/src/extension/db.cpp +++ b/src/extension/db.cpp @@ -35,6 +35,76 @@ DB db; DB::DB (void) { } + +struct ModuleInputCmp { + bool operator()(Input* module1, Input* module2) const { + + // Ensure SVG files are at top + int n1 = 0; + int n2 = 0; + // 12345678901234567890123456789012 + if (strncmp(module1->get_id(),"org.inkscape.input.svg", 22) == 0) n1 = 1; + if (strncmp(module2->get_id(),"org.inkscape.input.svg", 22) == 0) n2 = 1; + if (strncmp(module1->get_id(),"org.inkscape.input.svgz", 23) == 0) n1 = 2; + if (strncmp(module2->get_id(),"org.inkscape.input.svgz", 23) == 0) n2 = 2; + + if (n1 != 0 && n2 != 0) return (n1 < n2); + if (n1 != 0) return true; + if (n2 != 0) return false; + + // GDK filetypenames begin with lower case letters and thus are sorted at the end. + // Special case "sK1" which starts with a lower case letter to keep it out of GDK region. + if (strncmp(module1->get_id(),"org.inkscape.input.sk1", 22) == 0) { + return ( strcmp("SK1", module2->get_filetypename()) <= 0 ); + } + if (strncmp(module2->get_id(),"org.inkscape.input.sk1", 22) == 0) { + return ( strcmp(module1->get_filetypename(), "SK1" ) <= 0 ); + } + + return ( strcmp(module1->get_filetypename(), module2->get_filetypename()) <= 0 ); + } +}; + + +struct ModuleOutputCmp { + bool operator()(Output* module1, Output* module2) const { + + // Ensure SVG files are at top + int n1 = 0; + int n2 = 0; + // 12345678901234567890123456789012 + if (strncmp(module1->get_id(),"org.inkscape.output.svg.inkscape", 32) == 0) n1 = 1; + if (strncmp(module2->get_id(),"org.inkscape.output.svg.inkscape", 32) == 0) n2 = 1; + if (strncmp(module1->get_id(),"org.inkscape.output.svg.plain", 29) == 0) n1 = 2; + if (strncmp(module2->get_id(),"org.inkscape.output.svg.plain", 29) == 0) n2 = 2; + if (strncmp(module1->get_id(),"org.inkscape.output.svgz.inkscape", 33) == 0) n1 = 3; + if (strncmp(module2->get_id(),"org.inkscape.output.svgz.inkscape", 33) == 0) n2 = 3; + if (strncmp(module1->get_id(),"org.inkscape.output.svgz.plain", 30) == 0) n1 = 4; + if (strncmp(module2->get_id(),"org.inkscape.output.svgz.plain", 30) == 0) n2 = 4; + if (strncmp(module1->get_id(),"org.inkscape.output.scour", 25) == 0) n1 = 5; + if (strncmp(module2->get_id(),"org.inkscape.output.scour", 25) == 0) n2 = 5; + if (strncmp(module1->get_id(),"org.inkscape.output.ZIP", 23) == 0) n1 = 6; + if (strncmp(module2->get_id(),"org.inkscape.output.ZIP", 23) == 0) n2 = 6; + if (strncmp(module1->get_id(),"org.inkscape.output.LAYERS", 26) == 0) n1 = 7; + if (strncmp(module2->get_id(),"org.inkscape.output.LAYERS", 26) == 0) n2 = 7; + + if (n1 != 0 && n2 != 0) return (n1 < n2); + if (n1 != 0) return true; + if (n2 != 0) return false; + + // Special case "sK1" which starts with a lower case letter. + if (strncmp(module1->get_id(),"org.inkscape.output.sk1", 23) == 0) { + return ( strcmp("SK1", module2->get_filetypename()) <= 0 ); + } + if (strncmp(module2->get_id(),"org.inkscape.output.sk1", 23) == 0) { + return ( strcmp(module1->get_filetypename(), "SK1" ) <= 0 ); + } + + return ( strcmp(module1->get_filetypename(), module2->get_filetypename()) <= 0 ); + } +}; + + /** \brief Add a module to the module database \param module The module to be registered. @@ -49,10 +119,12 @@ DB::register_ext (Extension *module) bool add_to_list = ( moduledict.find(module->get_id()) == moduledict.end()); - //printf("Registering: '%s' add:%d\n", module->get_id(), add_to_list); + //printf("Registering: '%s' '%s' add:%d\n", module->get_id(), module->get_name(), add_to_list); moduledict[module->get_id()] = module; - if (add_to_list) modulelist.push_back(module); + if (add_to_list) { + modulelist.push_back( module ); + } } /** @@ -85,7 +157,7 @@ DB::unregister_ext (Extension * module) Extension * DB::get (const gchar *key) { - if (key == NULL) return NULL; + if (key == NULL) return NULL; Extension *mod = moduledict[key]; if ( !mod || mod->deactivated() ) @@ -207,6 +279,7 @@ DB::InputList & DB::get_input_list (DB::InputList &ou_list) { foreach(input_internal, (gpointer)&ou_list); + ou_list.sort( ModuleInputCmp() ); return ou_list; } @@ -220,6 +293,7 @@ DB::OutputList & DB::get_output_list (DB::OutputList &ou_list) { foreach(output_internal, (gpointer)&ou_list); + ou_list.sort( ModuleOutputCmp() ); return ou_list; } -- cgit v1.2.3 From 4e4f45e65c6cfca497972e996a57c2503e3bf4ce Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 31 May 2017 21:21:51 +0200 Subject: Remove silly code ;) (bzr r15714) --- src/sp-clippath.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index b26a2cbf2..1829837d8 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -227,19 +227,13 @@ void SPClipPath::hide(unsigned int key) { SP_ITEM(&child)->invoke_hide(key); } } - bool no_clippathview = true; for (SPClipPathView *v = display; v != NULL; v = v->next) { - no_clippathview = false; if (v->key == key) { /* We simply unref and let item to manage this in handler */ display = sp_clippath_view_list_remove(display, v); return; } } - if (no_clippathview) { - return; - } - g_assert_not_reached(); } void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox) { -- cgit v1.2.3 From d6c9869928a71b96996c80c5d97143ee0d674f38 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 1 Jun 2017 10:36:34 +0200 Subject: Use uniform name for input and output (and PDF is an ISO standard and no longer tied to Adobe). (bzr r15703.1.20) --- src/extension/internal/pdfinput/pdf-input.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index a57396b17..2ee713085 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -946,8 +946,8 @@ void PdfInput::init(void) { "\n" ".pdf\n" "application/pdf\n" - "" N_("Adobe PDF (*.pdf)") "\n" - "" N_("Adobe Portable Document Format") "\n" + "" N_("Portable Document Format (*.pdf)") "\n" + "" N_("Portable Document Format") "\n" "\n" "", new PdfInput()); -- cgit v1.2.3 From d4b3d7584914d22d357424bb657caa1906a5da33 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 1 Jun 2017 11:46:21 +0200 Subject: Avoid name conflict with libwmf (wmf_free). (bzr r15703.1.21) --- src/extension/internal/wmf-print.cpp | 2 +- src/libuemf/uwmf.c | 3 ++- src/libuemf/uwmf.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 6dd9d895e..29dfa2716 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -312,7 +312,7 @@ unsigned int PrintWmf::finish(Inkscape::Extension::Print * /*mod*/) g_error("Fatal programming error in PrintWmf::finish"); } (void) wmf_finish(wt); // Finalize and write out the WMF - wmf_free(&wt); // clean up + uwmf_free(&wt); // clean up wmf_htable_free(&wht); // clean up return 0; diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c index 62e3d3c06..50e4075d8 100644 --- a/src/libuemf/uwmf.c +++ b/src/libuemf/uwmf.c @@ -1517,8 +1517,9 @@ int wmf_start( \brief Release memory for an wmf structure in memory. Call this after wmf_finish(). \return 0 on success, >=1 on failure \param wt WMF in memory + Renamed to uwmf_free to avoid conflict with libwmf */ -int wmf_free( +int uwmf_free( WMFTRACK **wt ){ WMFTRACK *wtl; diff --git a/src/libuemf/uwmf.h b/src/libuemf/uwmf.h index 138ffab37..529232ca9 100644 --- a/src/libuemf/uwmf.h +++ b/src/libuemf/uwmf.h @@ -2078,7 +2078,7 @@ typedef struct { // Prototypes (_set first, then _get) char *wmr_dup(const char *wmr); int wmf_start(const char *name, uint32_t initsize, uint32_t chunksize, WMFTRACK **wt); -int wmf_free(WMFTRACK **wt); +int uwmf_free(WMFTRACK **wt); int wmf_finish(WMFTRACK *wt); int wmf_append(U_METARECORD *rec, WMFTRACK *wt, int freerec); int wmf_header_append(U_METARECORD *rec,WMFTRACK *et, int freerec); -- cgit v1.2.3 From d94079b0ea0195ed9c3fee03c4efd7d34e95d429 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 3 Jun 2017 15:20:04 +0200 Subject: Add list of OpenType tables available in selected font. (bzr r15703.1.22) --- src/ui/widget/font-variants.cpp | 57 ++++++++++++++++++++++++----------------- src/ui/widget/font-variants.h | 3 ++- 2 files changed, 35 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp index b386051a6..6753bbc7a 100644 --- a/src/ui/widget/font-variants.cpp +++ b/src/ui/widget/font-variants.cpp @@ -231,9 +231,13 @@ namespace Widget { // Add tooltips _feature_entry.set_tooltip_text( _("Feature settings in CSS form. No sanity checking is performed.")); + _feature_list.set_justify( Gtk::JUSTIFY_LEFT ); + _feature_list.set_line_wrap( true ); + // Add to frame _feature_vbox.add( _feature_entry ); _feature_vbox.add( _feature_label ); + _feature_vbox.add( _feature_list ); _feature_frame.add( _feature_vbox ); add( _feature_frame ); @@ -532,30 +536,35 @@ namespace Widget { // Make list of tables not handled above... eventually add Gtk::Label with // this info. - // std::map table_copy = res->openTypeTables; - // if( (it = table_copy.find("liga")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("clig")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("dlig")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("hlig")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("calt")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("subs")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("sups")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("smcp")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("c2sc")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("pcap")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("unic")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("titl")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("lnum")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("onum")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("pnum")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("tnum")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("frac")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("afrc")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("ordn")) != table_copy.end() ) table_copy.erase( it ); - // if( (it = table_copy.find("zero")) != table_copy.end() ) table_copy.erase( it ); - // for(it = table_copy.begin(); it != table_copy.end(); ++it) { - // std::cout << "Other: " << it->first << " Occurances: " << it->second << std::endl; - // } + std::map table_copy = res->openTypeTables; + if( (it = table_copy.find("liga")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("clig")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("dlig")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("hlig")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("calt")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("subs")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("sups")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("smcp")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("c2sc")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("pcap")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("unic")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("titl")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("lnum")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("onum")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("pnum")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("tnum")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("frac")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("afrc")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("ordn")) != table_copy.end() ) table_copy.erase( it ); + if( (it = table_copy.find("zero")) != table_copy.end() ) table_copy.erase( it ); + std::string ott_list = "OpenType tables not included above: "; + for(it = table_copy.begin(); it != table_copy.end(); ++it) { + // std::cout << "Other: " << it->first << " Occurances: " << it->second << std::endl; + ott_list += it->first; + ott_list += ", "; + } + + _feature_list.set_text( ott_list.c_str() ); } else { std::cerr << "FontVariants::update(): Couldn't find font_instance for: " diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h index d4329feff..507e5fb91 100644 --- a/src/ui/widget/font-variants.h +++ b/src/ui/widget/font-variants.h @@ -86,7 +86,8 @@ protected: Gtk::VBox _feature_vbox; Gtk::Entry _feature_entry; Gtk::Label _feature_label; - + Gtk::Label _feature_list; + private: void ligatures_init(); void ligatures_callback(); -- cgit v1.2.3 From 33f79b9653a737c534acd45eff6da806b68c276d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 4 Jun 2017 18:12:50 -0400 Subject: Add very raw page loading using links (bzr r15703.1.24) --- src/document.cpp | 12 +++++++++--- src/sp-anchor.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- src/sp-anchor.h | 4 ++++ 3 files changed, 52 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index c7115f906..4fcc2b098 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -481,7 +481,7 @@ SPDocument *SPDocument::createChildDoc(std::string const &uri) SPDocument *document = NULL; while(parent != NULL && parent->getURI() != NULL && document == NULL) { - // Check myself and any parents int he chain + // Check myself and any parents in the chain if(uri == parent->getURI()) { document = parent; break; @@ -500,8 +500,14 @@ SPDocument *SPDocument::createChildDoc(std::string const &uri) // Load a fresh document from the svg source. if(!document) { - const char *path = uri.c_str(); - document = createNewDoc(path, false, false, this); + std::string path; + if(uri.find('/') == -1) { + path = this->getBase() + uri; + } else { + path = uri; + } + std::cout << "Added base: '" << path << "'\n"; + document = createNewDoc(path.c_str(), false, false, this); } return document; } diff --git a/src/sp-anchor.cpp b/src/sp-anchor.cpp index 78ba10c13..b40f53ee1 100644 --- a/src/sp-anchor.cpp +++ b/src/sp-anchor.cpp @@ -5,6 +5,7 @@ * Lauris Kaplinski * Abhishek Sharma * + * Copyright (C) 2017 Martin Owens * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. * @@ -23,6 +24,9 @@ SPAnchor::SPAnchor() : SPGroup() { this->href = NULL; + this->type = NULL; + this->title = NULL; + this->page = NULL; } SPAnchor::~SPAnchor() { @@ -46,6 +50,18 @@ void SPAnchor::release() { g_free(this->href); this->href = NULL; } + if (this->type) { + g_free(this->type); + this->type = NULL; + } + if (this->title) { + g_free(this->title); + this->title = NULL; + } + if (this->page) { + g_free(this->page); + this->page = NULL; + } SPGroup::release(); } @@ -56,12 +72,21 @@ void SPAnchor::set(unsigned int key, const gchar* value) { g_free(this->href); this->href = g_strdup(value); this->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->updatePageAnchor(); break; - case SP_ATTR_XLINK_TYPE: + g_free(this->type); + this->type = g_strdup(value); + this->updatePageAnchor(); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; case SP_ATTR_XLINK_ROLE: case SP_ATTR_XLINK_ARCROLE: case SP_ATTR_XLINK_TITLE: + g_free(this->title); + this->title = g_strdup(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; case SP_ATTR_XLINK_SHOW: case SP_ATTR_XLINK_ACTUATE: case SP_ATTR_TARGET: @@ -74,6 +99,17 @@ void SPAnchor::set(unsigned int key, const gchar* value) { } } +/* + * Detect if this anchor qualifies as a page link and append + * the new page document to this document. + */ +void SPAnchor::updatePageAnchor() { + if (this->type && !strcmp(this->type, "page")) { + if (this->href && !this->page) { + this->page = this->document->createChildDoc(this->href); + } + } +} #define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key)); @@ -83,14 +119,14 @@ Inkscape::XML::Node* SPAnchor::write(Inkscape::XML::Document *xml_doc, Inkscape: } repr->setAttribute("xlink:href", this->href); + if (this->type) repr->setAttribute("xlink:type", this->type); + if (this->title) repr->setAttribute("xlink:title", this->title); if (repr != this->getRepr()) { // XML Tree being directly used while it shouldn't be in the // below COPY_ATTR lines - COPY_ATTR(repr, this->getRepr(), "xlink:type"); COPY_ATTR(repr, this->getRepr(), "xlink:role"); COPY_ATTR(repr, this->getRepr(), "xlink:arcrole"); - COPY_ATTR(repr, this->getRepr(), "xlink:title"); COPY_ATTR(repr, this->getRepr(), "xlink:show"); COPY_ATTR(repr, this->getRepr(), "xlink:actuate"); COPY_ATTR(repr, this->getRepr(), "target"); diff --git a/src/sp-anchor.h b/src/sp-anchor.h index d17718344..2dd81f74c 100644 --- a/src/sp-anchor.h +++ b/src/sp-anchor.h @@ -24,10 +24,14 @@ public: virtual ~SPAnchor(); char *href; + char *type; + char *title; + SPDocument *page; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); virtual void set(unsigned int key, char const* value); + virtual void updatePageAnchor(); virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; -- cgit v1.2.3 From 9a1906ee1091744357b32e0159b6019dc6476544 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Mon, 5 Jun 2017 00:58:45 +0200 Subject: Porting the pre-92 file update message from 0.92.x to trunk: New dialog when opening pre-0.92 files (with 90 dpi). I implemented it mostly based on mizmo's UI proposal (thanks!), with additional inputs from su_v with a few bugfixes from jabiertxof Also adds a commandline option --convert-dpi-method=[none|scale-viewbox|scale-document] to be able to batch convert files. Fixed bugs: - https://launchpad.net/bugs/1659229 (bzr r15703.1.26) --- src/document.cpp | 5 + src/file-update.cpp | 443 ++++++++++++++++++++++++++++++++++++++++++- src/file.cpp | 536 +--------------------------------------------------- src/file.h | 3 + src/main.cpp | 23 +++ 5 files changed, 477 insertions(+), 533 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 4fcc2b098..2141f65e9 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -469,6 +469,11 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, sp_file_convert_font_name(document); } + /** Fix dpi (pre-92 files) **/ + if ( !(INKSCAPE.use_gui()) && sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) { + sp_file_convert_dpi(document); + } + return document; } diff --git a/src/file-update.cpp b/src/file-update.cpp index 8fb3b3111..c9a1b6d62 100644 --- a/src/file-update.cpp +++ b/src/file-update.cpp @@ -8,6 +8,17 @@ * Marc Jeanmougin * su_v */ +#include + +#include "extension/effect.h" +#include "extension/db.h" +#include "extension/input.h" +#include "extension/output.h" +#include "extension/system.h" + +#include "inkscape.h" +#include "preferences.h" + #include "file.h" #include "sp-root.h" #include "sp-text.h" @@ -17,13 +28,33 @@ #include "sp-object.h" #include "sp-item.h" #include "style.h" +#include "sp-defs.h" +#include "dir-util.h" #include "document.h" #include #include #include "text-editing.h" - +#include "document-undo.h" +#include "display/canvas-grid.h" +#include "sp-guide.h" +#include "selection-chemistry.h" +#include "persp3d.h" +#include "proj_pt.h" +#include "ui/shape-editor.h" +#include "io/sys.h" +#include "print.h" +#include "ui/interface.h" +#include "desktop.h" +#include "message.h" +#include "message-stack.h" +#include "verbs.h" +#include "sp-namedview.h" + +using Inkscape::DocumentUndo; using namespace std; +int sp_file_convert_dpi_method_commandline = -1; // Unset + bool is_line(SPObject *i) { if (!(i->getAttribute("sodipodi:role"))) @@ -167,6 +198,416 @@ void sp_file_convert_font_name(SPDocument *doc) sp_file_text_run_recursive(fix_update, doc->getRoot()); } + +// Quick and dirty internal backup function +bool sp_file_save_backup( Glib::ustring uri ) { + + Glib::ustring out = uri; + out.insert(out.find(".svg"),"_backup"); + + FILE *filein = Inkscape::IO::fopen_utf8name(uri.c_str(), "rb"); + if (!filein) { + std::cerr << "sp_file_save_backup: failed to open: " << uri << std::endl; + return false; + } + + FILE *fileout = Inkscape::IO::fopen_utf8name(out.c_str(), "wb"); + if (!fileout) { + std::cerr << "sp_file_save_backup: failed to open: " << out << std::endl; + fclose( filein ); + return false; + } + + int ch; + while ((ch = fgetc(filein)) != EOF) { + fputc(ch, fileout); + } + fflush(fileout); + + bool return_value = true; + if (ferror(fileout)) { + std::cerr << "sp_file_save_backup: error when writing to: " << out << std::endl; + return_value = false; + } + + fclose(filein); + fclose(fileout); + + return return_value; +} + + +void sp_file_convert_dpi(SPDocument *doc) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring uri = doc->getURI(); + SPRoot *root = doc->getRoot(); + + // See if we need to offer the user a fix for the 90->96 px per inch change. + // std::cout << "SPFileOpen:" << std::endl; + // std::cout << " Version: " << sp_version_to_string(root->version.inkscape) << std::endl; + // std::cout << " SVG file from old Inkscape version detected: " + // << sp_version_to_string(root->version.inkscape) << std::endl; + static const double ratio = 90.0/96.0; + + bool need_fix_viewbox = false; + bool need_fix_units = false; + bool need_fix_guides = false; + bool need_fix_grid_mm = false; + bool need_fix_box3d = false; + bool did_scaling = false; + + // Check if potentially need viewbox or unit fix + switch (root->width.unit) { + case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_PT: + case SP_CSS_UNIT_MM: + case SP_CSS_UNIT_CM: + case SP_CSS_UNIT_IN: + need_fix_viewbox = true; + break; + case SP_CSS_UNIT_NONE: + case SP_CSS_UNIT_PX: + need_fix_units = true; + break; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + case SP_CSS_UNIT_PERCENT: + // OK + break; + default: + std::cerr << "sp_file_open: Unhandled width unit!" << std::endl; + } + + switch (root->height.unit) { + case SP_CSS_UNIT_PC: + case SP_CSS_UNIT_PT: + case SP_CSS_UNIT_MM: + case SP_CSS_UNIT_CM: + case SP_CSS_UNIT_IN: + need_fix_viewbox = true; + break; + case SP_CSS_UNIT_NONE: + case SP_CSS_UNIT_PX: + need_fix_units = true; + break; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + case SP_CSS_UNIT_PERCENT: + // OK + break; + default: + std::cerr << "sp_file_open: Unhandled height unit!" << std::endl; + } + + if (need_fix_units && need_fix_viewbox) { + std::cerr << "Different units in document size !" << std::endl; + if (root->viewBox_set) + need_fix_viewbox = false; + else + need_fix_units = false; + } + + // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl; + // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl; + + if ((!root->viewBox_set && need_fix_viewbox) || need_fix_units) { + int response = FILE_DPI_UNCHANGED; // default + + /******** UI *******/ + bool backup = prefs->getBool("/options/dpifixbackup", true); + if (INKSCAPE.use_gui() && sp_file_convert_dpi_method_commandline == -1) { + Gtk::Dialog scale_dialog(_("Convert legacy Inkscape file")); + scale_dialog.set_border_width(10); + scale_dialog.set_resizable(false); + Gtk::Label explanation; + explanation.set_markup(Glib::ustring("") + doc->getName() + "\n" + + _("was created in an older version of Inkscape (90 DPI) and we need " + "to make it compatible with newer versions (96 DPI). Tell us about this file:\n")); + explanation.set_line_wrap(true); + explanation.set_size_request(600,-1); + Gtk::RadioButton::Group c1, c2; + + Gtk::Label choice1_label; + choice1_label.set_markup( + _("This file contains digital artwork for screen display. (Choose if unsure.)")); + Gtk::RadioButton choice1(c1); + choice1.add(choice1_label); + Gtk::RadioButton choice2(c1, _("This file is intended for physical output, such as paper or 3D prints.")); + Gtk::Label choice2_1_label; + choice2_1_label.set_markup(_("The appearance of elements such as clips, masks, filters, and clones\n" + "is most important. (Choose if unsure.)")); + Gtk::RadioButton choice2_1(c2); + choice2_1.add(choice2_1_label); + Gtk::RadioButton choice2_2(c2, _("The accuracy of the physical unit size and position values of objects\n" + "in the file is most important. (Experimental.)")); + Gtk::CheckButton backup_button(_("Create a backup file in same directory.")); + Gtk::Expander moreinfo(_("More details...")); + Gtk::Label moreinfo_text; + moreinfo_text.set_markup( + _("We've updated Inkscape to follow the CSS standard of 96 DPI for better browser " + "compatibility; we used to use 90 DPI. " + "Digital artwork for screen display will be converted to 96 DPI without scaling and should be " + "unaffected. " + "Artwork drawn at 90 DPI for a specific physical size will be too small if converted to 96 DPI " + "without any scaling. There are two scaling methods:\n\n" + "Scaling the whole document: The least error-prone method, this preserves the appearance of " + "the artwork, including filters and the position of masks, etc. " + "The scale of the artwork relative to the document size may not be accurate.\n\n" + "Scaling individual elements in the artwork: This method is less reliable and can result in " + "a changed appearance, " + "but is better for physical output that relies on accurate sizes and positions (for example, for " + "3D printing.)\n\n" + "More information about this change are available in the Inkscape FAQ" + "")); + moreinfo_text.set_line_wrap(true); + moreinfo_text.set_size_request(554,-1); + Gtk::Box b; + b.set_border_width(0); + + b.pack_start(choice2_1, false, false, 4); + b.pack_start(choice2_2, false, false, 4); + choice2_1.show(); + choice2_2.show(); + + Gtk::Alignment balign(0, 0, 0, 0); + balign.set_padding (0, 0, 30, 0); + balign.show(); + balign.add(b); + Gtk::Box *content = scale_dialog.get_content_area(); + content->pack_start(explanation, false, false, 5); + content->pack_start(choice1, false, false, 5); + content->pack_start(choice2, false, false, 5); + content->pack_start(balign, false, false, 5); + content->pack_start(backup_button, false, false, 5); + Gtk::Button *ok_button = scale_dialog.add_button(_("OK"), GTK_RESPONSE_ACCEPT); + backup_button.set_active(backup); + content->pack_start(moreinfo, false, false, 5); + moreinfo.add(moreinfo_text); + scale_dialog.show_all_children(); + b.hide(); + choice1.signal_clicked().connect(sigc::mem_fun(b, &Gtk::Box::hide)); + choice2.signal_clicked().connect(sigc::mem_fun(b, &Gtk::Box::show)); + + response = prefs->getInt("/options/dpiupdatemethod", FILE_DPI_UNCHANGED); + if ( response != FILE_DPI_UNCHANGED ) { + choice2.set_active(); + b.show(); + if ( response == FILE_DPI_DOCUMENT_SCALED) + choice2_2.set_active(); + } + ok_button->grab_focus(); + + int status = scale_dialog.run(); + if ( status == GTK_RESPONSE_ACCEPT ) { + backup = backup_button.get_active(); + prefs->setBool("/options/dpifixbackup", backup); + response = choice1.get_active() ? FILE_DPI_UNCHANGED : choice2_1.get_active() ? FILE_DPI_VIEWBOX_SCALED : FILE_DPI_DOCUMENT_SCALED; + prefs->setInt("/options/dpiupdatemethod", response); + } else if (sp_file_convert_dpi_method_commandline != -1) { + response = sp_file_convert_dpi_method_commandline; + } else { + response = FILE_DPI_UNCHANGED; + } + } else { // GUI with explicit option + response = FILE_DPI_UNCHANGED; + } + + if (backup && (response != FILE_DPI_UNCHANGED)) { + sp_file_save_backup(uri); + } + + if (!(response == FILE_DPI_UNCHANGED && need_fix_units)) { + need_fix_guides = true; // Only fix guides if drawing scaled + need_fix_box3d = true; + } + + if (response == FILE_DPI_VIEWBOX_SCALED) { + double ratio_viewbox = need_fix_units ? 1.0 : ratio; + + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value("px") * ratio_viewbox, + doc->getHeight().value("px") * ratio_viewbox)); + Inkscape::Util::Quantity width = // maybe set it to mm ? + Inkscape::Util::Quantity(doc->getWidth().value("px") / ratio, "px"); + Inkscape::Util::Quantity height = Inkscape::Util::Quantity(doc->getHeight().value("px") / ratio, "px"); + if (need_fix_units) + doc->setWidthAndHeight(width, height, false); + + } else if (response == FILE_DPI_DOCUMENT_SCALED) { + + Inkscape::Util::Quantity width = // maybe set it to mm ? + Inkscape::Util::Quantity(doc->getWidth().value("px") / ratio, "px"); + Inkscape::Util::Quantity height = Inkscape::Util::Quantity(doc->getHeight().value("px") / ratio, "px"); + if (need_fix_units) + doc->setWidthAndHeight(width, height, false); + + if (!root->viewBox_set) { + // Save preferences + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); + bool transform_pattern = prefs->getBool("/options/transform/pattern", true); + bool transform_gradient = prefs->getBool("/options/transform/gradient", true); + + prefs->setBool("/options/transform/stroke", true); + prefs->setBool("/options/transform/rectcorners", true); + prefs->setBool("/options/transform/pattern", true); + prefs->setBool("/options/transform/gradient", true); + + Inkscape::UI::ShapeEditor::blockSetItem(true); + doc->getRoot()->scaleChildItemsRec(Geom::Scale(1 / ratio), Geom::Point(0, 0), false); + Inkscape::UI::ShapeEditor::blockSetItem(false); + + // Restore preferences + prefs->setBool("/options/transform/stroke", transform_stroke); + prefs->setBool("/options/transform/rectcorners", transform_rectcorners); + prefs->setBool("/options/transform/pattern", transform_pattern); + prefs->setBool("/options/transform/gradient", transform_gradient); + + did_scaling = true; +/* + +// There used to be 2 "experimental" scaling methods in trunk. Considering that the method in .92.x appear to work, so I'm commenting those. + + // Save preferences + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); + bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); + + prefs->setBool("/options/kbselection/onlysensitive", false); + prefs->setBool("/options/kbselection/onlyvisible", false); + + Inkscape::Selection *selection = desktop->getSelection(); + Inkscape::SelectionHelper::selectAllInAll( desktop ); + +//method 1 ... + selection->group(); + SPItem * group = selection->singleItem(); + if (group) { + group->setAttribute("transform","scale(1.06666667,1.06666667)"); + } else { + std::cerr << "sp_file_open: Failed to get group!" << std::endl; + } + selection->clear(); + selection->add( group ); + selection->ungroup(); + +// OR method 2... + + double height = root->height.computed; + selection->setScaleRelative( Geom::Point(0,height), Geom::Scale(96.0/90.0,96.0/90.0) ); + +... end method 2 + + selection->clear(); + + prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); + prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); + + did_scaling = true; +*/ + + + + } + } else { // FILE_DPI_UNCHANGED + if (need_fix_units) + need_fix_grid_mm = true; + } + } + + // Fix guides and grids and perspective + for (SPObject *child = root->firstChild(); child; child = child->getNext()) { + SPNamedView *nv = dynamic_cast(child); + if (nv) { + if (need_fix_guides) { + // std::cout << "Fixing guides" << std::endl; + for (SPObject *child2 = nv->firstChild(); child2; child2 = child2->getNext()) { + SPGuide *gd = dynamic_cast(child2); + if (gd) { + gd->moveto(gd->getPoint() / ratio, true); + } + } + } + + for (std::vector::const_iterator it = nv->grids.begin(); it != nv->grids.end(); + ++it) { + Inkscape::CanvasXYGrid *xy = dynamic_cast(*it); + if (xy) { + // std::cout << "A grid: " << xy->getSVGName() << std::endl; + // std::cout << " Origin: " << xy->origin + // << " Spacing: " << xy->spacing << std::endl; + // std::cout << (xy->isLegacy()?" Legacy":" Not Legacy") << std::endl; + Geom::Scale scale = doc->getDocumentScale(); + if (xy->isLegacy()) { + if (xy->isPixel()) { + if (need_fix_grid_mm) { + xy->Scale(Geom::Scale(1, 1)); // See note below + } else { + scale *= Geom::Scale(ratio, ratio); + xy->Scale(scale.inverse()); /* *** */ + } + } else { + if (need_fix_grid_mm) { + xy->Scale(Geom::Scale(ratio, ratio)); + } else { + xy->Scale(scale.inverse()); /* *** */ + } + } + } else { + if (need_fix_guides) { + if (did_scaling) { + xy->Scale(Geom::Scale(ratio, ratio).inverse()); + } else { + // HACK: Scaling the document does not seem to cause + // grids defined in document units to be updated. + // This forces an update. + xy->Scale(Geom::Scale(1, 1)); + } + } + } + } + } + } // If SPNamedView + + SPDefs *defs = dynamic_cast(child); + if (defs && need_fix_box3d) { + for (SPObject *child = defs->firstChild(); child; child = child->getNext()) { + Persp3D *persp3d = dynamic_cast(child); + if (persp3d) { + std::vector tokens; + + const gchar *vp_x = persp3d->getAttribute("inkscape:vp_x"); + const gchar *vp_y = persp3d->getAttribute("inkscape:vp_y"); + const gchar *vp_z = persp3d->getAttribute("inkscape:vp_z"); + const gchar *vp_o = persp3d->getAttribute("inkscape:persp3d-origin"); + // std::cout << "Found Persp3d: " + // << " vp_x: " << vp_x + // << " vp_y: " << vp_y + // << " vp_z: " << vp_z << std::endl; + Proj::Pt2 pt_x(vp_x); + Proj::Pt2 pt_y(vp_y); + Proj::Pt2 pt_z(vp_z); + Proj::Pt2 pt_o(vp_o); + pt_x = pt_x * (1.0 / ratio); + pt_y = pt_y * (1.0 / ratio); + pt_z = pt_z * (1.0 / ratio); + pt_o = pt_o * (1.0 / ratio); + persp3d->setAttribute("inkscape:vp_x", pt_x.coord_string()); + persp3d->setAttribute("inkscape:vp_y", pt_y.coord_string()); + persp3d->setAttribute("inkscape:vp_z", pt_z.coord_string()); + persp3d->setAttribute("inkscape:persp3d-origin", pt_o.coord_string()); + } + } + } + } // Look for SPNamedView and SPDefs loop + + // desktop->getDocument()->ensureUpToDate(); // Does not update box3d! + DocumentUndo::done(doc, SP_VERB_NONE, _("Update Document")); +} + + + /* Local Variables: mode:c++ diff --git a/src/file.cpp b/src/file.cpp index 795df433d..43a9c6f5b 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -65,13 +65,6 @@ #include "event-log.h" #include "ui/dialog/font-substitution.h" -// For updating old Inkscape SVG files -#include "display/canvas-grid.h" -#include "sp-guide.h" -#include "selection-chemistry.h" -#include "persp3d.h" -#include "proj_pt.h" -#include "ui/shape-editor.h" using Inkscape::DocumentUndo; @@ -240,42 +233,6 @@ sp_file_exit() } -// Quick and dirty internal backup function -bool sp_file_save_backup( Glib::ustring uri ) { - - Glib::ustring out = uri; - out.insert(out.find(".svg"),"_backup"); - - FILE *filein = Inkscape::IO::fopen_utf8name(uri.c_str(), "rb"); - if (!filein) { - std::cerr << "sp_file_save_backup: failed to open: " << uri << std::endl; - return false; - } - - FILE *fileout = Inkscape::IO::fopen_utf8name(out.c_str(), "wb"); - if (!fileout) { - std::cerr << "sp_file_save_backup: failed to open: " << out << std::endl; - fclose( filein ); - return false; - } - - int ch; - while ((ch = fgetc(filein)) != EOF) { - fputc(ch, fileout); - } - fflush(fileout); - - bool return_value = true; - if (ferror(fileout)) { - std::cerr << "sp_file_save_backup: error when writing to: " << out << std::endl; - return_value = false; - } - - fclose(filein); - fclose(fileout); - - return return_value; -} /*###################### ## O P E N @@ -342,497 +299,12 @@ bool sp_file_open(const Glib::ustring &uri, root->original.svg = root->version.svg; if (INKSCAPE.use_gui()) { - - // See if we need to offer the user a fix for the 90->96 px per inch change. - // std::cout << "SPFileOpen:" << std::endl; - // std::cout << " Version: " << sp_version_to_string(root->version.inkscape) << std::endl; - - if ( sp_version_inside_range( root->version.inkscape, 0, 1, 0, 92 ) ) { - - // std::cout << " SVG file from old Inkscape version detected: " - // << sp_version_to_string(root->version.inkscape) << std::endl; - static const double ratio = 90.0/96.0; - - bool need_fix_viewbox = false; - bool need_fix_units = false; - bool need_fix_guides = false; - bool need_fix_grid_mm = false; - bool need_fix_box3d = false; - bool did_scaling = false; - - // Check if potentially need viewbox or unit fix - switch (root->width.unit) { - case SP_CSS_UNIT_PC: - case SP_CSS_UNIT_PT: - case SP_CSS_UNIT_MM: - case SP_CSS_UNIT_CM: - case SP_CSS_UNIT_IN: - need_fix_viewbox = true; - break; - case SP_CSS_UNIT_NONE: - case SP_CSS_UNIT_PX: - need_fix_units = true; - break; - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - case SP_CSS_UNIT_PERCENT: - // OK - break; - default: - std::cerr << "sp_file_open: Unhandled width unit!" << std::endl; - } - - switch (root->height.unit) { - case SP_CSS_UNIT_PC: - case SP_CSS_UNIT_PT: - case SP_CSS_UNIT_MM: - case SP_CSS_UNIT_CM: - case SP_CSS_UNIT_IN: - need_fix_viewbox = true; - break; - case SP_CSS_UNIT_NONE: - case SP_CSS_UNIT_PX: - need_fix_units = true; - break; - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - case SP_CSS_UNIT_PERCENT: - // OK - break; - default: - std::cerr << "sp_file_open: Unhandled height unit!" << std::endl; - } - - // std::cout << "Absolute SVG units in root? " << (need_fix_viewbox?"true":"false") << std::endl; - // std::cout << "User units in root? " << (need_fix_units ?"true":"false") << std::endl; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if (!root->viewBox_set && need_fix_viewbox) { - - Glib::ustring msg = _( - "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n" - "Drawing elements may be too small. This can be corrected by\n" - "either setting the SVG 'viewBox' to compensate or by scaling\n" - "all the elements in the drawing."); - Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false); - - Gtk::Label info; - info.set_markup(msg.c_str()); - info.show(); - scaleDialog.get_content_area()->pack_start(info, false, false, 20); - - Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - bool backup = prefs->getBool("/options/dpifixbackup", true); - backupButton.set_active( backup ); - backupButton.show(); - scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); - - scaleDialog.add_button(_("Set 'viewBox'"), 1); - scaleDialog.add_button(_("Scale elements"), 2); - scaleDialog.add_button(_("Ignore"), 3); - scaleDialog.add_button("Scale test - group", 4); - scaleDialog.add_button("Scale test - children", 5); - scaleDialog.add_button("Scale test - all", 6); - - gint response = scaleDialog.run(); - backup = backupButton.get_active(); - prefs->setBool("/options/dpifixbackup", backup); - - if ( backup && response != 3) { - sp_file_save_backup( uri ); - } - - if (response == 1) { - - doc->setViewBox(Geom::Rect::from_xywh( - 0, 0, - doc->getWidth().value("px") * ratio, - doc->getHeight().value("px") * ratio)); - - } else if (response == 2 ) { - - std::list effects; - Inkscape::Extension::db.get_effect_list(effects); - std::list::iterator it = effects.begin(); - bool did = false; - while (it != effects.end()) { - if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) { - Inkscape::UI::View::View *view = desktop; - (*it)->effect(view); - did = true; - break; - } - ++it; - } - if (!did) { - std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; - } - did_scaling = true; - - } else if (response == 4) { - - // Save preferences - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - selection->group(); - SPItem * group = selection->singleItem(); - if (group) { - group->setAttribute("transform","scale(1.06666667,1.06666667)"); - } else { - std::cerr << "sp_file_open: Failed to get group!" << std::endl; - } - selection->clear(); - selection->add( group ); - selection->ungroup(); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - - } else if (response == 5) { - - // Save preferences - bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); - bool transform_pattern = prefs->getBool("/options/transform/pattern", true); - bool transform_gradient = prefs->getBool("/options/transform/gradient", true); - - prefs->setBool("/options/transform/stroke", true); - prefs->setBool("/options/transform/rectcorners", true); - prefs->setBool("/options/transform/pattern", true); - prefs->setBool("/options/transform/gradient", true); - - Inkscape::UI::ShapeEditor::blockSetItem(true); - doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); - Inkscape::UI::ShapeEditor::blockSetItem(false); - - // Restore preferences - prefs->setBool("/options/transform/stroke", transform_stroke); - prefs->setBool("/options/transform/rectcorners", transform_rectcorners); - prefs->setBool("/options/transform/pattern", transform_pattern); - prefs->setBool("/options/transform/gradient", transform_gradient); - - } else if (response == 6) { - - // Save preferences - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - - double height = root->height.computed; - selection->setScaleRelative( Geom::Point(0,height), Geom::Scale(96.0/90.0,96.0/90.0) ); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - - } - - need_fix_box3d = false; // setScaleRelative() handles box3d - need_fix_guides = true; // Always fix guides - } - - else if (need_fix_units) { - Glib::ustring msg = _( - "Old Inkscape files use 1in == 90px. CSS requires 1in == 96px.\n" - "Drawings meant to match a physical size (e.g. Letter or A4)\n" - "will be too small. Scaling the drawing can correct for this.\n" - "Internal scaling can be handled either by setting the SVG 'viewBox'\n" - "attribute to compensate or by scaling all objects in the drawing."); - Gtk::Dialog scaleDialog( _("Old Inkscape file detected (90 DPI)"), false); - - Gtk::Label info; - info.set_markup(msg.c_str()); - info.show(); - scaleDialog.get_content_area()->pack_start(info, false, false, 20); - - Gtk::CheckButton backupButton( _("Create backup file (in same directory).") ); - bool backup = prefs->getBool("/options/dpifixbackup", true); - backupButton.set_active( backup ); - backupButton.show(); - scaleDialog.get_content_area()->pack_start(backupButton, false, false, 20); - - scaleDialog.add_button(_("Set 'viewBox'"), 1); - scaleDialog.add_button(_("Scale elements"), 2); - scaleDialog.add_button(_("Ignore"), 3); - scaleDialog.add_button("Scale test - group", 4); - scaleDialog.add_button("Scale test - children", 5); - scaleDialog.add_button("Scale test - all", 6); - - gint response = scaleDialog.run(); - backup = backupButton.get_active(); - prefs->setBool("/options/dpifixbackup", backup); - - if ( backup && response != 3) { - sp_file_save_backup( uri ); - } - - if (response == 1) { - - if (!root->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh( - 0, 0, - doc->getWidth().value("px"), - doc->getHeight().value("px"))); - } - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - need_fix_guides = true; // Only fix guides if drawing scaled - need_fix_box3d = true; - - } else if (response == 2) { - - std::list effects; - Inkscape::Extension::db.get_effect_list(effects); - std::list::iterator it = effects.begin(); - bool did = false; - while (it != effects.end()){ - if (strcmp((*it)->get_id(), "org.inkscape.dpi90to96") == 0) { - Inkscape::UI::View::View *view = desktop; - (*it)->effect(view); - did = true; - break; - } - ++it; - } - if (!did) { - std::cerr << "sp_file_open: Failed to find dpi90to96 extension." << std::endl; - } - need_fix_guides = true; // Only fix guides if drawing scaled - did_scaling = true; - - } else if (response == 4) { - - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - if (!root->viewBox_set) { - - // Save preferences - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - selection->group(); - SPItem * group = selection->singleItem(); - if (group) { - group->setAttribute("transform","scale(1.06666667,1.06666667)"); - } else { - std::cerr << "sp_file_open: Failed to get group!" << std::endl; - } - selection->clear(); - selection->add( group ); - selection->ungroup(); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - } - - need_fix_box3d = true; - need_fix_guides = true; // Only fix guides if drawing scaled - - } else if (response == 5) { - - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - if (!root->viewBox_set) { - - // Save preferences - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); - bool transform_pattern = prefs->getBool("/options/transform/pattern", true); - bool transform_gradient = prefs->getBool("/options/transform/gradient", true); - - prefs->setBool("/options/transform/stroke", true); - prefs->setBool("/options/transform/rectcorners", true); - prefs->setBool("/options/transform/pattern", true); - prefs->setBool("/options/transform/gradient", true); - - Inkscape::UI::ShapeEditor::blockSetItem(true); - doc->getRoot()->scaleChildItemsRec(Geom::Scale(1/ratio),Geom::Point(0, 0), false); - Inkscape::UI::ShapeEditor::blockSetItem(false); - - // Restore preferences - prefs->setBool("/options/transform/stroke", transform_stroke); - prefs->setBool("/options/transform/rectcorners", transform_rectcorners); - prefs->setBool("/options/transform/pattern", transform_pattern); - prefs->setBool("/options/transform/gradient", transform_gradient); - - did_scaling = true; - - } - - } else if (response == 6) { - - double old_height = root->height.computed; - Inkscape::Util::Quantity width = - Inkscape::Util::Quantity(doc->getWidth().value("px")/ratio, "px" ); - Inkscape::Util::Quantity height = - Inkscape::Util::Quantity(doc->getHeight().value("px")/ratio,"px" ); - doc->setWidthAndHeight( width, height, false ); - - if (!root->viewBox_set) { - - // Save preferences - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive",true); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - - prefs->setBool("/options/kbselection/onlysensitive", false); - prefs->setBool("/options/kbselection/onlyvisible", false); - - Inkscape::Selection *selection = desktop->getSelection(); - Inkscape::SelectionHelper::selectAllInAll( desktop ); - double height = root->height.computed; - - // So far we have just enlarged the drawing but due to the - // inverted coordinate system we must scale around the old - // height position. - selection->setScaleRelative( Geom::Point(0,old_height), Geom::Scale(96.0/90.0,96.0/90.0) ); - selection->clear(); - - prefs->setBool("/options/kbselection/onlysensitive", onlysensitive); - prefs->setBool("/options/kbselection/onlyvisible", onlyvisible ); - - did_scaling = true; - } - - need_fix_box3d = false; // setScaleRelative() handls box3s - need_fix_guides = true; // Only fix guides if drawing scaled - - } else { - // Ignore - need_fix_grid_mm = true; - } - } - - // Fix guides and grids and perspective - for (SPObject *child = root->firstChild() ; child; child = child->getNext() ) { - SPNamedView *nv = dynamic_cast(child); - if (nv) { - if (need_fix_guides) { - // std::cout << "Fixing guides" << std::endl; - for (SPObject *child2 = nv->firstChild() ; child2; child2 = child2->getNext() ) { - SPGuide *gd = dynamic_cast(child2); - if (gd) { - gd->moveto( gd->getPoint() / ratio, true ); - } - } - } - - for(std::vector::const_iterator it=nv->grids.begin();it!=nv->grids.end();++it ) { - Inkscape::CanvasXYGrid *xy = dynamic_cast(*it); - if (xy) { - // std::cout << "A grid: " << xy->getSVGName() << std::endl; - // std::cout << " Origin: " << xy->origin - // << " Spacing: " << xy->spacing << std::endl; - // std::cout << (xy->isLegacy()?" Legacy":" Not Legacy") << std::endl; - Geom::Scale scale = doc->getDocumentScale(); - if (xy->isLegacy()) { - if (xy->isPixel()) { - if (need_fix_grid_mm) { - xy->Scale( Geom::Scale(1,1) ); // See note below - } else { - scale *= Geom::Scale(ratio,ratio); - xy->Scale( scale.inverse() ); /* *** */ - } - } else { - if (need_fix_grid_mm) { - xy->Scale( Geom::Scale(ratio,ratio) ); - } else { - xy->Scale( scale.inverse() ); /* *** */ - } - } - } else { - if (need_fix_guides) { - if(did_scaling){ - xy->Scale( Geom::Scale(ratio,ratio).inverse() ); - } else { - // HACK: Scaling the document does not seem to cause - // grids defined in document units to be updated. - // This forces an update. - xy->Scale( Geom::Scale(1,1) ); - } - } - } - } - } - } // If SPNamedView - - SPDefs *defs = dynamic_cast(child); - if (defs && need_fix_box3d) { - for (SPObject *child = defs->firstChild() ; child; child = child->getNext() ) { - Persp3D* persp3d = dynamic_cast(child); - if (persp3d) { - std::vector tokens; - - const gchar* vp_x = persp3d->getAttribute("inkscape:vp_x"); - const gchar* vp_y = persp3d->getAttribute("inkscape:vp_y"); - const gchar* vp_z = persp3d->getAttribute("inkscape:vp_z"); - const gchar* vp_o = persp3d->getAttribute("inkscape:persp3d-origin"); - // std::cout << "Found Persp3d: " - // << " vp_x: " << vp_x - // << " vp_y: " << vp_y - // << " vp_z: " << vp_z << std::endl; - Proj::Pt2 pt_x (vp_x); - Proj::Pt2 pt_y (vp_y); - Proj::Pt2 pt_z (vp_z); - Proj::Pt2 pt_o (vp_o); - pt_x = pt_x * (1.0/ratio); - pt_y = pt_y * (1.0/ratio); - pt_z = pt_z * (1.0/ratio); - pt_o = pt_o * (1.0/ratio); - persp3d->setAttribute("inkscape:vp_x",pt_x.coord_string()); - persp3d->setAttribute("inkscape:vp_y",pt_y.coord_string()); - persp3d->setAttribute("inkscape:vp_z",pt_z.coord_string()); - persp3d->setAttribute("inkscape:persp3d-origin",pt_o.coord_string()); - } - } - } - } // Look for SPNamedView and SPDefs loop - - // desktop->getDocument()->ensureUpToDate(); // Does not update box3d! - DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Update Document")); - - } // If old Inkscape version + if (sp_version_inside_range(root->version.inkscape, 0, 1, 0, 92)) { + sp_file_convert_dpi(doc); + } } // If use_gui + // resize the window to match the document properties sp_namedview_window_from_document(desktop); sp_namedview_update_layers_from_document(desktop); diff --git a/src/file.h b/src/file.h index 2fc4ea910..c6ff61c25 100644 --- a/src/file.h +++ b/src/file.h @@ -205,6 +205,9 @@ void sp_file_print (Gtk::Window& parentWindow); void sp_file_vacuum (SPDocument *doc); void sp_file_convert_text_baseline_spacing(SPDocument *doc); void sp_file_convert_font_name(SPDocument *doc); +void sp_file_convert_dpi(SPDocument *doc); +enum File_DPI_Fix { FILE_DPI_UNCHANGED = 0, FILE_DPI_VIEWBOX_SCALED, FILE_DPI_DOCUMENT_SCALED }; +extern int sp_file_convert_dpi_method_commandline; #endif // SEEN_SP_FILE_H diff --git a/src/main.cpp b/src/main.cpp index 4c63402fb..7a786234e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,6 +15,7 @@ * ... and various people who have worked with various projects * Jon A. Cruz * Abhishek Sharma + * Marc Jeanmougin * * Copyright (C) 1999-2004 authors * Copyright (C) 2001-2002 Ximian, Inc. @@ -167,6 +168,7 @@ enum { SP_ARG_VERSION, SP_ARG_VACUUM_DEFS, SP_ARG_NO_CONVERT_TEXT_BASELINE_SPACING, + SP_ARG_CONVERT_DPI_METHOD, #ifdef WITH_DBUS SP_ARG_DBUS_LISTEN, SP_ARG_DBUS_NAME, @@ -278,6 +280,7 @@ static void resetCommandlineGlobals() { sp_query_id = NULL; sp_vacuum_defs = FALSE; sp_no_convert_text_baseline_spacing = FALSE; + sp_file_convert_dpi_method_commandline = -1; #ifdef WITH_DBUS sp_dbus_listen = FALSE; sp_dbus_name = NULL; @@ -539,6 +542,11 @@ struct poptOption options[] = { N_("Do not fix legacy (pre-0.92) files' text baseline spacing on opening."), NULL}, + {"convert-dpi-method", 0, + POPT_ARG_STRING, NULL, SP_ARG_CONVERT_DPI_METHOD, + N_("Method used to convert pre-.92 document dpi, if needed."), + "[none|scale-viewbox|scale-document]"}, + POPT_AUTOHELP POPT_TABLEEND }; @@ -2180,6 +2188,21 @@ sp_process_args(poptContext ctx) } break; } + case SP_ARG_CONVERT_DPI_METHOD: { + gchar const *arg = poptGetOptArg(ctx); + if (arg != NULL) { + if (!strcmp(arg,"none")) { + sp_file_convert_dpi_method_commandline = FILE_DPI_UNCHANGED; + } else if (!strcmp(arg,"scale-viewbox")) { + sp_file_convert_dpi_method_commandline = FILE_DPI_VIEWBOX_SCALED; + } else if (!strcmp(arg,"scale-document")) { + sp_file_convert_dpi_method_commandline = FILE_DPI_DOCUMENT_SCALED; + } else { + g_warning("Invalid update option"); + } + } + break; + } case POPT_ERROR_BADOPT: { g_warning ("Invalid option %s", poptBadOption(ctx, 0)); exit(1); -- cgit v1.2.3 From cfb1e23e906e35f0d4e7bbd9fcbb047c3a3788bf Mon Sep 17 00:00:00 2001 From: Michael Soegtrop Date: Mon, 5 Jun 2017 20:59:36 +0200 Subject: fixed enum order + added cpp files to POFILES.in (bzr r14862.2.4) --- src/live_effects/effect-enum.h | 4 ++-- src/live_effects/effect.cpp | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 0ad9c5230..5cc4d58e5 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -42,8 +42,6 @@ enum EffectType { TAPER_STROKE, MIRROR_SYMMETRY, COPY_ROTATE, - EMBRODERY_STITCH, - BOOL_OP, ATTACH_PATH, FILL_BETWEEN_STROKES, FILL_BETWEEN_MANY, @@ -51,6 +49,8 @@ enum EffectType { BOUNDING_BOX, MEASURE_LINE, FILLET_CHAMFER, + BOOL_OP, + EMBRODERY_STITCH, DOEFFECTSTACK_TEST, ANGLE_BISECTOR, CIRCLE_WITH_RADIUS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 44580b9b2..e5a879241 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -118,8 +118,6 @@ const Util::EnumData LPETypeData[] = { {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, /* Ponyscape -> Inkscape 0.92*/ - {EMBRODERY_STITCH, N_("Embrodery stitch"), "embrodery_stitch"}, - {BOOL_OP, N_("Boolean operation"), "bool_op"}, {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"}, @@ -128,6 +126,8 @@ const Util::EnumData LPETypeData[] = { /* 9.93 */ {MEASURE_LINE, N_("Measure Line"), "measure_line"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, + {BOOL_OP, N_("Boolean operation"), "bool_op"}, + {EMBRODERY_STITCH, N_("Embrodery stitch"), "embrodery_stitch"}, #ifdef LPE_ENABLE_TEST_EFFECTS {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"}, {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"}, @@ -171,11 +171,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) 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; -- cgit v1.2.3 From 5adc02881af091a146faceaa8187cd567d5c4412 Mon Sep 17 00:00:00 2001 From: Michael Soegtrop Date: Mon, 5 Jun 2017 21:00:41 +0200 Subject: fixed enum order + added cpp files to POFILES.in (bzr r14876.2.5) --- src/live_effects/effect-enum.h | 2 +- src/live_effects/effect.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 71d669bf6..ed9fb2c9d 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -42,7 +42,6 @@ enum EffectType { TAPER_STROKE, MIRROR_SYMMETRY, COPY_ROTATE, - BOOL_OP, ATTACH_PATH, FILL_BETWEEN_STROKES, FILL_BETWEEN_MANY, @@ -50,6 +49,7 @@ enum EffectType { BOUNDING_BOX, MEASURE_LINE, FILLET_CHAMFER, + BOOL_OP, DOEFFECTSTACK_TEST, ANGLE_BISECTOR, CIRCLE_WITH_RADIUS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index fe40920e3..9e1555c26 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -117,7 +117,6 @@ const Util::EnumData LPETypeData[] = { {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, /* Ponyscape -> Inkscape 0.92*/ - {BOOL_OP, N_("Boolean operation"), "bool_op"}, {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"}, @@ -126,6 +125,7 @@ const Util::EnumData LPETypeData[] = { /* 9.93 */ {MEASURE_LINE, N_("Measure Line"), "measure_line"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, + {BOOL_OP, N_("Boolean operation"), "bool_op"}, #ifdef LPE_ENABLE_TEST_EFFECTS {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"}, {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"}, @@ -169,7 +169,6 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case BOOL_OP: neweffect = static_cast ( new LPEBool(lpeobj) ); break; - case PATTERN_ALONG_PATH: neweffect = static_cast ( new LPEPatternAlongPath(lpeobj) ); break; -- cgit v1.2.3 From 443ab0f809b848675fe5a74fe2290c7dc7ca16b0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 5 Jun 2017 21:32:59 +0200 Subject: Show glyphs with alternative styles in "Feature Settings" section of "Variants" tab of "Text and Font" dialog. (bzr r15703.1.28) --- src/libnrtype/FontFactory.cpp | 97 +++++++++++++++++++++++++++++++++++++---- src/libnrtype/font-instance.h | 3 ++ src/ui/widget/font-variants.cpp | 34 +++++++++++++++ src/ui/widget/font-variants.h | 1 + 4 files changed, 126 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 770616ae7..8d66904e0 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -699,26 +699,26 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // Empty map... bitmap fonts seem to be loaded multiple times. res->openTypeTables.clear(); - auto const hb_face = hb_ft_face_create(res->theFace, NULL); + auto const face = hb_ft_face_create(res->theFace, NULL); // First time to get size of array - auto script_count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, NULL, NULL); + auto script_count = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL); auto const scripts_hb = g_new(hb_tag_t, script_count + 1); // Second time to fill array (this two step process was not necessary with Pango). - hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); + hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); for(unsigned int i = 0; i < script_count; ++i) { - auto language_count = hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); + auto language_count = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); if(language_count > 0) { auto const languages_hb = g_new(hb_tag_t, language_count + 1); - hb_ot_layout_script_get_language_tags(hb_face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); + hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); for(unsigned int j = 0; j < language_count; ++j) { - auto feature_count = hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); for(unsigned int k = 0; k < feature_count; ++k) { ++(res->openTypeTables[ extract_tag(&features_hb[k])]); @@ -731,11 +731,11 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } else { // Even if no languages are present there is still the default. - auto feature_count = hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, NULL, NULL); auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(hb_face, HB_OT_TAG_GSUB, i, + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 0, &feature_count, features_hb); @@ -747,6 +747,85 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } } + // Find glyphs in OpenType substitution tables ('gsub'). + // Note that pango's functions are just dummies. Must use harfbuzz. + + // Loop over all tables + for (auto table: res->openTypeTables) { + + // Only look at style substitution tables ('salt', 'ss01', etc. but not 'ssty'). + if (table.first == "salt" || + (table.first[0] == 's' && table.first[1] == 's' && !(table.first[2] == 't') ) ) { + // std::cout << " Table: " << table.first << std::endl; + + Glib::ustring unicode_characters; + + unsigned int feature_index; + if ( hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, + 0, // Assume one script exists with index 0 + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + HB_TAG(table.first[0], + table.first[1], + table.first[2], + table.first[3]), + &feature_index ) ) { + + // std::cout << " Found feature, number: " << feature_index << std::endl; + unsigned int lookup_indexes[32]; + unsigned int lookup_count = 32; + int count = hb_ot_layout_feature_get_lookups (face, HB_OT_TAG_GSUB, + feature_index, + 0, // Start + &lookup_count, + lookup_indexes ); + // std::cout << " Lookup count: " << count << " total: " << lookup_count << std::endl; + + if (count > 0) { + hb_set_t* glyphs_before = NULL; // hb_set_create(); + hb_set_t* glyphs_input = hb_set_create(); + hb_set_t* glyphs_after = NULL; // hb_set_create(); + hb_set_t* glyphs_output = NULL; // hb_set_create(); + + // For now, just look at first index + hb_ot_layout_lookup_collect_glyphs (face, HB_OT_TAG_GSUB, + lookup_indexes[0], + glyphs_before, + glyphs_input, + glyphs_after, + glyphs_output ); + + hb_font_t *font = hb_font_create (face); + + // Without this, all functions return 0, etc. + hb_ft_font_set_funcs (font); + + hb_codepoint_t codepoint = -1; + while (hb_set_next (glyphs_input, &codepoint)) { + + // There is a unicode to glyph mapping function but not the inverse! + for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { + hb_codepoint_t glyph = 0; + hb_font_get_nominal_glyph (font, unicode_i, &glyph); + if ( glyph == codepoint) { + unicode_characters += (gunichar)unicode_i; + continue; + } + } + } + res->openTypeSubstitutions[table.first] = unicode_characters; + + hb_set_destroy (glyphs_input); + hb_font_destroy (font); + } + } else { + // std::cout << " Did not find '" << table.first << "'!" << std::endl; + } + } + } + // for (auto table: res->openTypeSubstitutions) { + // std::cout << table.first << ": " << table.second << std::endl; + // } + hb_face_destroy (face); g_free(scripts_hb); } else { // already here diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 2fac7c19b..52c921403 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -39,6 +39,9 @@ public: // Map of OpenType tables found in font (convert to std::set?) std::map openTypeTables; + // Map of substitutions indexed by table + std::map openTypeSubstitutions; + font_instance(void); virtual ~font_instance(void); diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp index 6753bbc7a..e7645b620 100644 --- a/src/ui/widget/font-variants.cpp +++ b/src/ui/widget/font-variants.cpp @@ -234,10 +234,14 @@ namespace Widget { _feature_list.set_justify( Gtk::JUSTIFY_LEFT ); _feature_list.set_line_wrap( true ); + _feature_substitutions.set_justify( Gtk::JUSTIFY_LEFT ); + _feature_substitutions.set_line_wrap( true ); + // Add to frame _feature_vbox.add( _feature_entry ); _feature_vbox.add( _feature_label ); _feature_vbox.add( _feature_list ); + _feature_vbox.add( _feature_substitutions ); _feature_frame.add( _feature_vbox ); add( _feature_frame ); @@ -566,6 +570,36 @@ namespace Widget { _feature_list.set_text( ott_list.c_str() ); + // ""; + Glib::ustring markup; + + for (auto table: res->openTypeSubstitutions) { + + markup += table.first; + markup += ": "; + + markup += ""; + markup += Glib::Markup::escape_text(table.second); + markup += ""; + + markup += " → "; + + markup += ""; + markup += ""; + markup += Glib::Markup::escape_text(table.second); + markup += ""; + markup += "\n"; + + } + + _feature_substitutions.set_markup ( markup.c_str() ); + } else { std::cerr << "FontVariants::update(): Couldn't find font_instance for: " << font_spec << std::endl; diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h index 507e5fb91..cf8e476a9 100644 --- a/src/ui/widget/font-variants.h +++ b/src/ui/widget/font-variants.h @@ -87,6 +87,7 @@ protected: Gtk::Entry _feature_entry; Gtk::Label _feature_label; Gtk::Label _feature_list; + Gtk::Label _feature_substitutions; private: void ligatures_init(); -- cgit v1.2.3 From 2be6299592701cf199d74ad88fb79291d4b1e1da Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 6 Jun 2017 02:27:41 +0200 Subject: Add contextual buttons to Hide/lock and Unhide/unlock items (bzr r15703.1.29) --- src/document.cpp | 8 ++-- src/document.h | 4 +- src/ui/interface.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++- src/ui/interface.h | 4 ++ src/ui/tools/measure-tool.cpp | 2 +- 5 files changed, 95 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 2141f65e9..3a7d4408f 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1553,11 +1553,11 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin * Assumes box is normalized (and g_asserts it!) * */ -std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups) const +std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const { std::vector x; g_return_val_if_fail(this->priv != NULL, x); - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, false, into_groups); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, take_insensitive, into_groups); } /* @@ -1567,11 +1567,11 @@ std::vector SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect con * */ -std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups) const +std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const { std::vector x; g_return_val_if_fail(this->priv != NULL, x); - return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups); + return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, take_insensitive, into_groups); } std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const diff --git a/src/document.h b/src/document.h index db50f1717..92f53559f 100644 --- a/src/document.h +++ b/src/document.h @@ -282,8 +282,8 @@ public: bool addResource(char const *key, SPObject *object); bool removeResource(char const *key, SPObject *object); const std::vector getResourceList(char const *key) const; - std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; - std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool into_groups = false) const; + std::vector getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive = false, bool into_groups = false) const; + std::vector getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive = false, bool into_groups = false) const; SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; std::vector getItemsAtPoints(unsigned const key, std::vector points, bool all_layers = true, size_t limit = 0) const ; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 5e85065d1..33e98a81c 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -1438,13 +1438,58 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DELETE)); positionOfLastDialog = 10; // 9 in front + 1 for the separator in the next if; used to position the dialog menu entries below each other + Geom::Rect b(_desktop->point(),_desktop->point() + Geom::Point(1,1)); + std::vector< SPItem * > down_items = _desktop->getDocument()->getItemsPartiallyInBox( _desktop->dkey, b, true, true); + bool has_down_hidden = false; + bool has_down_locked = false; + for(std::vector< SPItem * >::iterator down = down_items.begin(); down != down_items.end(); ++down){ + if((*down)->isHidden()) { + has_down_hidden = true; + } + if((*down)->isLocked()) { + has_down_locked = true; + } + } + AddSeparator(); + Gtk::MenuItem* mi; + + mi = Gtk::manage(new Gtk::MenuItem(_("Hide selected objects"),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::HideSelected)); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(false); + } + mi->show(); + append(*mi);//insert(*mi,positionOfLastDialog++); + + mi = Gtk::manage(new Gtk::MenuItem(_("Unhide objects below"),1)); + mi->signal_activate().connect(sigc::bind >(sigc::mem_fun(*this, &ContextMenu::UnHideBelow), down_items)); + if (!has_down_hidden) { + mi->set_sensitive(false); + } + mi->show(); + append(*mi);//insert(*mi,positionOfLastDialog++); + mi = Gtk::manage(new Gtk::MenuItem(_("Lock selected objects"),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::LockSelected)); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(false); + } + mi->show(); + append(*mi);//insert(*mi,positionOfLastDialog++); + + mi = Gtk::manage(new Gtk::MenuItem(_("Unlock objects below"),1)); + mi->signal_activate().connect(sigc::bind >(sigc::mem_fun(*this, &ContextMenu::UnLockBelow), down_items)); + if (!has_down_locked) { + mi->set_sensitive(false); + } + mi->show(); + append(*mi);//insert(*mi,positionOfLastDialog++); /* Item menu */ if (item!=NULL) { AddSeparator(); MakeObjectMenu(); } - + AddSeparator(); /* layer menu */ SPGroup *group=NULL; if (item) { @@ -1507,6 +1552,44 @@ void ContextMenu::LeaveGroup(void) _desktop->setCurrentLayer(_desktop->currentLayer()->parent); } +void ContextMenu::LockSelected(void) +{ + auto itemlist = _desktop->selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i) { + (*i)->setLocked(true); + } +} + +void ContextMenu::HideSelected(void) +{ + auto itemlist =_desktop->selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i) { + (*i)->setHidden(true); + } +} + +void ContextMenu::UnLockBelow(std::vector items) +{ + _desktop->selection->clear(); + for(auto i=items.begin();i!=items.end(); ++i) { + if ((*i)->isLocked()) { + (*i)->setLocked(false); + _desktop->selection->add(*i); + } + } +} + +void ContextMenu::UnHideBelow(std::vector items) +{ + _desktop->selection->clear(); + for(auto i=items.begin();i!=items.end(); ++i) { + if ((*i)->isHidden()) { + (*i)->setHidden(false); + _desktop->selection->add(*i); + } + } +} + void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)//, bool radio, GSList *group) { SPAction *action; diff --git a/src/ui/interface.h b/src/ui/interface.h index 52074f0f0..a41c36cc3 100644 --- a/src/ui/interface.h +++ b/src/ui/interface.h @@ -172,6 +172,10 @@ class ContextMenu : public Gtk::Menu void EnterGroup(Gtk::MenuItem* mi); void LeaveGroup(void); + void LockSelected(void); + void HideSelected(void); + void UnLockBelow(std::vector items); + void UnHideBelow(std::vector items); ////////////////////////////////////////// //callbacks for the context menu entries of an SP_TYPE_ITEM object void ItemProperties(void); diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index f3185649b..98b2c7d03 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -1260,7 +1260,7 @@ void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, std::vector items; SPDocument *doc = desktop->getDocument(); Geom::Rect rect(start_p, end_p); - items = doc->getItemsPartiallyInBox(desktop->dkey, rect, true); + items = doc->getItemsPartiallyInBox(desktop->dkey, rect, false, true); Inkscape::LayerModel *layer_model = NULL; SPObject *current_layer = NULL; if(desktop){ -- cgit v1.2.3 From 281f5ae5654f8b762f566a177df6e56211f3efe5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 6 Jun 2017 10:13:53 +0200 Subject: Fix build with versions of Harfbuzz prior to 1.2.3. (Visualization of alternative glyphs requires 1.2.3.) (bzr r15703.1.30) --- src/libnrtype/FontFactory.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 8d66904e0..6c0999f2d 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -747,6 +747,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } } +#if HB_VERSION_ATLEAST(1,2,3) // Find glyphs in OpenType substitution tables ('gsub'). // Note that pango's functions are just dummies. Must use harfbuzz. @@ -825,6 +826,11 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // for (auto table: res->openTypeSubstitutions) { // std::cout << table.first << ": " << table.second << std::endl; // } +#else + std::cerr << "Requires Harfbuzz 1.2.3 for visualizing alternative glyph OpenType tables. " + << "Compiled with: " << HB_VERSION_STRING << "." << std::endl; +#endif + hb_face_destroy (face); g_free(scripts_hb); } else { -- cgit v1.2.3 From 09d096d4d8afd236344bd34dc637e9a56ea1d731 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Jun 2017 21:17:08 +0200 Subject: Fixing somethings changing from shapes to paths (bzr r15716) --- src/live_effects/lpe-powerclip.cpp | 91 ++++++++++++++++++++------------------ src/live_effects/lpe-powerclip.h | 4 +- 2 files changed, 48 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index bbbe733fe..e4a6f9e60 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -31,19 +31,16 @@ namespace LivePathEffect { LPEPowerClip::LPEPowerClip(LivePathEffectObject *lpeobject) : Effect(lpeobject), inverse(_("Inverse clip"), _("Inverse clip"), "inverse", &wr, this, false), - flatten(_("Flatten clip"), _("Flatten clip"), "flatten", &wr, this, false), - fillrule(_("Set/unset evenodd fill rule"), _("Set/unset evenodd fill rule (this is overwriting your current value)."), "fillrule", &wr, this, false), + flatten(_("Flatten clip"), _("Flatten clip, see fill rule once convert to paths"), "flatten", &wr, this, false), convert_shapes(_("Convert clip shapes to paths"), _("Convert clip shapes to paths (this is overwriting your current value)."), "convert_shapes", &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(&fillrule); registerParameter(&convert_shapes); registerParameter(&is_inverse); is_clip = false; - previous_fillrule = fillrule; hide_clip = false; } @@ -70,23 +67,58 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ 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(); - const char * id = clip_data->getId(); Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(SP_ITEM(clip_data), 0); - clip_data->updateRepr(xml_doc, clip_path_node, SP_OBJECT_WRITE_ALL); - clip_data->getRepr()->setAttribute("id", id); - clip_path->emitModified(SP_OBJECT_MODIFIED_CASCADE); - std::cout << "toshapes\n"; + // remember the position of the item + gint pos = clip_data->getRepr()->position(); + // 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); + 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( 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") { - removeInverse(SP_ITEM(clip_data)); + if (clip_to_path) { + removeInverse(SP_ITEM(clip_to_path)); + } else { + removeInverse(SP_ITEM(clip_data)); + } } } } else { @@ -103,12 +135,11 @@ LPEPowerClip::addInverse (SPItem * clip_data){ addInverse(subitem); } } else if (SP_IS_PATH(clip_data)) { - setFillRule(clip_data); SPCurve * c = NULL; c = SP_SHAPE(clip_data)->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); - if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + 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 @@ -147,12 +178,13 @@ LPEPowerClip::removeInverse (SPItem * clip_data){ removeInverse(subitem); } } else if (SP_IS_PATH(clip_data)) { - setFillRule(clip_data); SPCurve * c = NULL; c = SP_SHAPE(clip_data)->getCurve(); if (c) { Geom::PathVector c_pv = c->get_pathvector(); - c_pv.pop_back(); + if(c_pv.size() > 1) { + c_pv.pop_back(); + } c->set_pathvector(c_pv); SP_SHAPE(clip_data)->setCurve(c, TRUE); c->unref(); @@ -293,17 +325,6 @@ LPEPowerClip::flattenClip(SPItem * clip_data, Geom::PathVector &path_in) flattenClip(subitem, path_in); } } else if (SP_IS_PATH(clip_data)) { - if (!SP_IS_PATH(clip_data) && convert_shapes) { - SPDocument * document = SP_ACTIVE_DOCUMENT; - if (!document) { - return; - } - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - const char * id = clip_data->getId(); - Inkscape::XML::Node *clip_path_node = sp_selected_item_to_curved_repr(clip_data, 0); - clip_data->updateRepr(xml_doc, clip_path_node, SP_OBJECT_WRITE_ALL); - clip_data->getRepr()->setAttribute("id", id); - } SPCurve * c = NULL; c = SP_SHAPE(clip_data)->getCurve(); if (c) { @@ -317,24 +338,6 @@ LPEPowerClip::flattenClip(SPItem * clip_data, Geom::PathVector &path_in) } } -void -LPEPowerClip::setFillRule(SPItem * clip_data) -{ - if (previous_fillrule != fillrule) { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, clip_data->getRepr()->attribute("style")); - if (fillrule) { - sp_repr_css_set_property (css, "fill-rule", "evenodd"); - } else { - sp_repr_css_set_property (css, "fill-rule", "nonzero"); - } - Glib::ustring css_str; - sp_repr_css_write_string(css,css_str); - clip_data->getRepr()->setAttribute("style", css_str.c_str()); - previous_fillrule = fillrule; - } -} - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 63594cfd8..b9c68c652 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -28,20 +28,18 @@ public: void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); - void setFillRule(SPItem * clip_data); + void setClipRule(SPItem * clip_data); protected: //virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: BoolParam inverse; BoolParam flatten; - BoolParam fillrule; BoolParam convert_shapes; HiddenParam is_inverse; Geom::Path clip_box; bool is_clip; bool hide_clip; - bool previous_fillrule; bool previous_hide_clip; }; -- cgit v1.2.3 From 0477b2e5da044c5d4c61198f3200467bbf619362 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 6 Jun 2017 21:37:40 +0200 Subject: Substitute a bool paramenter by a button (bzr r15717) --- src/live_effects/lpe-powerclip.cpp | 28 ++++++++++++++++++++-------- src/live_effects/lpe-powerclip.h | 7 ++----- 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index e4a6f9e60..d5666bdde 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -32,16 +32,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), - convert_shapes(_("Convert clip shapes to paths"), _("Convert clip shapes to paths (this is overwriting your current value)."), "convert_shapes", &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(&convert_shapes); registerParameter(&is_inverse); is_clip = false; hide_clip = false; + convert_shapes = false; } LPEPowerClip::~LPEPowerClip() {} @@ -235,6 +234,12 @@ LPEPowerClip::toggleClip() { } } +void +LPEPowerClip::convertShapes() { + convert_shapes = true; + sp_lpe_item_update_patheffect(SP_LPE_ITEM(sp_lpe_item), false, false); +} + Gtk::Widget * LPEPowerClip::newWidget() { @@ -244,12 +249,7 @@ LPEPowerClip::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(6); - 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); - vbox->pack_start(*hbox, true,true,2); - hbox->pack_start(*toggle_button, false, false,2); + std::vector::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { @@ -272,6 +272,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); + 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); + vbox->pack_start(*hbox2, true,true,2); + hbox2->pack_start(*topaths_button, false, false,2); return dynamic_cast(vbox); } diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index b9c68c652..88d425f01 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -28,17 +28,14 @@ public: void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); void flattenClip(SPItem * clip_data, Geom::PathVector &path_in); - void setClipRule(SPItem * clip_data); -protected: - //virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); - + void convertShapes(); private: BoolParam inverse; BoolParam flatten; - BoolParam convert_shapes; HiddenParam is_inverse; Geom::Path clip_box; bool is_clip; + bool convert_shapes; bool hide_clip; bool previous_hide_clip; }; -- cgit v1.2.3 From cc8dee1e385d81f4cb326f385ef282ea3b7d0370 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Tue, 6 Jun 2017 22:27:19 +0200 Subject: Starting with powermask (bzr r15718) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 + src/live_effects/lpe-powerclip.cpp | 8 - src/live_effects/lpe-powermask.cpp | 357 +++++++++++++++++++++++++++++++++++++ src/live_effects/lpe-powermask.h | 45 +++++ 6 files changed, 410 insertions(+), 8 deletions(-) create mode 100644 src/live_effects/lpe-powermask.cpp create mode 100644 src/live_effects/lpe-powermask.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index e1e5cab4c..75e3c2154 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -37,6 +37,7 @@ set(live_effects_SRC lpe-perspective-envelope.cpp lpe-perspective_path.cpp lpe-powerclip.cpp + lpe-powermask.cpp lpe-powerstroke.cpp lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp @@ -123,6 +124,7 @@ set(live_effects_SRC lpe-perspective_path.h lpe-powerstroke-interpolators.h lpe-powerclip.h + lpe-powermask.h lpe-powerstroke.h lpe-recursiveskeleton.h lpe-rough-hatches.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 700564334..88e93b936 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -50,6 +50,7 @@ enum EffectType { MEASURE_LINE, FILLET_CHAMFER, POWERCLIP, + POWERMASK, DOEFFECTSTACK_TEST, ANGLE_BISECTOR, CIRCLE_WITH_RADIUS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index ff481dd96..faf1d14ab 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -48,6 +48,7 @@ #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" @@ -126,6 +127,7 @@ const Util::EnumData LPETypeData[] = { {MEASURE_LINE, N_("Measure Line"), "measure_line"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"}, {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"}, @@ -307,6 +309,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case POWERCLIP: neweffect = static_cast ( new LPEPowerClip(lpeobj) ); break; + case POWERMASK: + neweffect = static_cast ( new LPEPowerClip(lpeobj) ); + break; case ROUGHEN: neweffect = static_cast ( new LPERoughen(lpeobj) ); break; diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index d5666bdde..75e4c24de 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -17,14 +17,6 @@ // TODO due to internal breakage in glibmm headers, this must be last: #include -// FIXME: expose these from sp-clippath/mask.cpp -struct SPClipPathView { - SPClipPathView *next; - unsigned int key; - Inkscape::DrawingItem *arenaitem; - Geom::OptRect bbox; -}; - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp new file mode 100644 index 000000000..a98d2655f --- /dev/null +++ b/src/live_effects/lpe-powermask.cpp @@ -0,0 +1,357 @@ +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "live_effects/lpe-powermask.h" +#include <2geom/path-intersection.h> +#include <2geom/intersection-graph.h> +#include "display/drawing-item.h" +#include "display/curve.h" +#include "helper/geom.h" +#include "sp-mask.h" +#include "sp-path.h" +#include "sp-shape.h" +#include "sp-item-group.h" +#include "ui/tools-switch.h" +#include "path-chemistry.h" + +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +namespace Inkscape { +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) +{ + registerParameter(&inverse); + registerParameter(&flatten); + registerParameter(&is_inverse); + is_mask = false; + hide_mask = false; + convert_shapes = false; +} + +LPEPowerMask::~LPEPowerMask() {} + +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(); + 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); + Geom::Point bottomleft = Geom::Point(boundingbox_X.min() - 5,boundingbox_Y.min() - 5); + mask_box.clear(); + mask_box.start(topleft); + mask_box.appendNew(topright); + mask_box.appendNew(bottomright); + mask_box.appendNew(bottomleft); + mask_box.close(); + //mask_path *= sp_lpe_item->i2dt_affine(); + if(mask_path) { + is_mask = true; + 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; + 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; + } +} + +void +LPEPowerMask::addInverse (SPItem * mask_data){ + if (SP_IS_GROUP(mask_data)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(mask_data)); + for ( std::vector::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); + } + } + } + } + } +} + +void +LPEPowerMask::removeInverse (SPItem * mask_data){ + if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { + if (SP_IS_GROUP(mask_data)) { + std::vector item_list = sp_item_group_item_list(SP_GROUP(mask_data)); + for ( std::vector::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); + } + } + } + } + } + } +} + +void +LPEPowerMask::toggleMask() { + SPItem * item = SP_ITEM(sp_lpe_item); + if (item) { + SPMaskPath *mask_path = item->mask_ref->getObject(); + if (mask_path) { + hide_mask = !hide_mask; + if(hide_mask) { + SPItemView *v; + for (v = item->display; v != NULL; v = v->next) { + mask_path->hide(v->arenaitem->key()); + } + } else { + Geom::OptRect bbox = item->geometricBounds(); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); + } + Inkscape::DrawingItem *ai = mask_path->show( + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setMask(ai); + mask_path->setBBox(v->arenaitem->key(), bbox); + } + } + mask_path->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() +{ + // 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()); + if(param->param_key == "grid") { + widg = NULL; + } + 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 * toggle_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Toggle mask visibiliy")))); + toggle_button->signal_clicked().connect(sigc::mem_fun (*this,&LPEPowerMask::toggleMask)); + 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(vbox); +} + +void +LPEPowerMask::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + SPMaskPath *mask_path = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); + if(!keep_paths) { + if(mask_path) { + is_mask = true; + 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; + 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 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; + 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 item_list = sp_item_group_item_list(SP_GROUP(mask_data)); + for ( std::vector::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(); + } + } +} + +}; //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-powermask.h b/src/live_effects/lpe-powermask.h new file mode 100644 index 000000000..933eeefb1 --- /dev/null +++ b/src/live_effects/lpe-powermask.h @@ -0,0 +1,45 @@ +#ifndef INKSCAPE_LPE_POWERMASK_H +#define INKSCAPE_LPE_POWERMASK_H + +/* + * Inkscape::LPEPowerMask + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/hidden.h" +#include "live_effects/parameter/path.h" +#include "live_effects/lpegroupbbox.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEPowerMask : public Effect, GroupBBoxEffect { +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(); +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 +} //namespace Inkscape +#endif -- cgit v1.2.3 From bfdef68f1e252a7e185fced8f8f0c0fd20b66e20 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Wed, 7 Jun 2017 00:41:50 +0200 Subject: Working on powermask (bzr r15719) --- src/live_effects/lpe-powermask.cpp | 293 ++++++++++--------------------------- src/live_effects/lpe-powermask.h | 12 +- 2 files changed, 76 insertions(+), 229 deletions(-) (limited to 'src') 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(bottomright); mask_box.appendNew(bottomleft); mask_box.close(); - //mask_path *= sp_lpe_item->i2dt_affine(); - if(mask_path) { - is_mask = true; - 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; - 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 item_list = sp_item_group_item_list(SP_GROUP(mask_data)); - for ( std::vector::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 item_list = sp_item_group_item_list(SP_GROUP(mask_data)); - for ( std::vector::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 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(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 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; - 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 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; - 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 item_list = sp_item_group_item_list(SP_GROUP(mask_data)); - for ( std::vector::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 -- cgit v1.2.3 From 28f5005c59243827d9583c5bd305e58f25b05a67 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 7 Jun 2017 11:29:09 +0200 Subject: Strip comments when parsing CSS. Allow no space after an element name if followed by '+', '>', or '~' when entering new selector. (bzr r15703.1.32) --- src/ui/dialog/styledialog.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp index 4576671e7..b1bcddd45 100644 --- a/src/ui/dialog/styledialog.cpp +++ b/src/ui/dialog/styledialog.cpp @@ -355,6 +355,12 @@ void StyleDialog::_readStyleElement() // Remove end-of-lines (check it works on Windoze). content.erase(std::remove(content.begin(), content.end(), '\n'), content.end()); + // Remove comments (/* xxx */) + while(content.find("/*") != std::string::npos) { + size_t start = content.find("/*"); + content.erase(start, (content.find("*/", start) - start) +2); + } + // First split into selector/value chunks. // An attempt to use Glib::Regex failed. A C++11 version worked but // reportedly has problems on Windows. Using split_simple() is simpler @@ -787,7 +793,7 @@ void StyleDialog::_addSelector() * set to ".Class1" */ selectorValue = textEditPtr->get_text(); - Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find(" ")); + Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); del->set_sensitive(true); -- cgit v1.2.3 From 2ab552f572576f1138869c1956d8150b7386d610 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 7 Jun 2017 12:52:19 +0200 Subject: Reorder hide and lock from context menu (bzr r15703.1.33) --- src/ui/interface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 33e98a81c..7e80c1a2f 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -1438,6 +1438,13 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DELETE)); positionOfLastDialog = 10; // 9 in front + 1 for the separator in the next if; used to position the dialog menu entries below each other + /* Item menu */ + if (item!=NULL) { + AddSeparator(); + MakeObjectMenu(); + } + AddSeparator(); + /* Lock/Unock Hide/Unhide*/ Geom::Rect b(_desktop->point(),_desktop->point() + Geom::Point(1,1)); std::vector< SPItem * > down_items = _desktop->getDocument()->getItemsPartiallyInBox( _desktop->dkey, b, true, true); bool has_down_hidden = false; @@ -1450,7 +1457,6 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : has_down_locked = true; } } - AddSeparator(); Gtk::MenuItem* mi; mi = Gtk::manage(new Gtk::MenuItem(_("Hide selected objects"),1)); @@ -1484,12 +1490,6 @@ ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : } mi->show(); append(*mi);//insert(*mi,positionOfLastDialog++); - /* Item menu */ - if (item!=NULL) { - AddSeparator(); - MakeObjectMenu(); - } - AddSeparator(); /* layer menu */ SPGroup *group=NULL; if (item) { -- cgit v1.2.3 From ef4db6f8483312a558b512e8a1ad11fc95872886 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 7 Jun 2017 21:34:53 +0200 Subject: Working on powermask LPE (bzr r15722) --- src/live_effects/effect-enum.h | 2 - src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-powerclip.cpp | 3 - src/live_effects/lpe-powerclip.h | 1 - src/live_effects/lpe-powermask.cpp | 181 +++++++++++++++++++++++++------------ src/live_effects/lpe-powermask.h | 13 ++- src/sp-clippath.h | 1 - src/sp-mask.cpp | 3 +- 8 files changed, 136 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 7c2965d14..7114004a0 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -49,8 +49,6 @@ enum EffectType { BOUNDING_BOX, MEASURE_LINE, FILLET_CHAMFER, - POWERCLIP, - POWERMASK, BOOL_OP, POWERCLIP, POWERMASK, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 256530a38..c4a437ff6 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -315,7 +315,7 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) neweffect = static_cast ( new LPEPowerClip(lpeobj) ); break; case POWERMASK: - neweffect = static_cast ( new LPEPowerClip(lpeobj) ); + neweffect = static_cast ( new LPEPowerMask(lpeobj) ); break; case ROUGHEN: neweffect = static_cast ( new LPERoughen(lpeobj) ); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index 75e4c24de..ee1603855 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -247,9 +247,6 @@ LPEPowerClip::newWidget() if ((*it)->widget_is_visible) { Parameter * param = *it; Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - if(param->param_key == "grid") { - widg = NULL; - } Glib::ustring * tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index 88d425f01..e70ec2c9c 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -9,7 +9,6 @@ #include "live_effects/effect.h" #include "live_effects/parameter/hidden.h" -#include "live_effects/parameter/path.h" #include "live_effects/lpegroupbbox.h" namespace Inkscape { diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index bbe0dff40..a49d4c493 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -11,6 +11,7 @@ #include "sp-path.h" #include "sp-shape.h" #include "sp-defs.h" +#include "style.h" #include "sp-item-group.h" #include "svg/svg.h" #include "ui/tools-switch.h" @@ -24,10 +25,21 @@ namespace LivePathEffect { LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) : Effect(lpeobject), - inverse(_("Inverse mask"), _("Inverse mask"), "inverse", &wr, this, false) + invert(_("Invert mask"), _("Invert mask"), "invert", &wr, this, false), + wrap(_("Wrap filtered clip data"), _("Wrap filtered clip data"), "wrap", &wr, this, false), + background(_("Add background to mask"), _("Add background to mask"), "background", &wr, this, false), + background_style(_("Background Style"), _("CSS to background"), "background_style", &wr, this,"fill:#ffffff;opacity:0.7;") + { - registerParameter(&inverse); + registerParameter(&invert); + registerParameter(&wrap); + registerParameter(&background); + registerParameter(&background_style); + background_style.param_hide_canvas_text(); hide_mask = false; + previous_invert = !invert; + previous_wrap = !wrap; + previous_background_style = ""; } LPEPowerMask::~LPEPowerMask() {} @@ -35,7 +47,7 @@ LPEPowerMask::~LPEPowerMask() {} void LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ original_bbox(lpeitem); - const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("mask-path"); + const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("mask"); 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); @@ -49,12 +61,12 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ mask_box.close(); //mask *= sp_lpe_item->i2dt_affine(); if(mask) { - setInverse(); + setMask(); } } void -LPEPowerMask::setInverse(){ +LPEPowerMask::setMask(){ SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); SPObject *elemref = NULL; SPDocument * document = SP_ACTIVE_DOCUMENT; @@ -65,55 +77,111 @@ LPEPowerMask::setInverse(){ 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 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"); + Glib::ustring mask_id = (Glib::ustring)mask->getId(); + Glib::ustring box_id = mask_id + (Glib::ustring)"_transparentbox"; + Glib::ustring filter_id = mask_id + (Glib::ustring)"_inverse"; + Glib::ustring filter_uri = (Glib::ustring)"url(#" + mask_id + (Glib::ustring)"_inverse)"; + if (previous_invert != invert || previous_wrap != wrap) { + if (invert) { + if (!(elemref = document->getObjectById(filter_id))) { + filter = xml_doc->createElement("svg:filter"); + filter->setAttribute("id", filter_id.c_str()); + 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"); + Glib::ustring primitive1_id = (mask_id + (Glib::ustring)"_primitive1").c_str(); + primitive1->setAttribute("id", primitive1_id.c_str()); + primitive1->setAttribute("values", "1"); + primitive1->setAttribute("type", "saturate"); + primitive1->setAttribute("result", "fbSourceGraphic"); + Inkscape::XML::Node *primitive2 = xml_doc->createElement("svg:feColorMatrix"); + Glib::ustring primitive2_id = (mask_id + (Glib::ustring)"_primitive2").c_str(); + primitive2->setAttribute("id", primitive2_id.c_str()); + 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); + } + } else { + if ((elemref = document->getObjectById(filter_id))) { + elemref->deleteObject(true); + } + filter_uri = ""; + } + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPItem * mask_data = SP_ITEM(*iter); + if (! strcmp(mask_data->getId(), box_id.c_str())){ + continue; + } + Glib::ustring mask_data_id = (Glib::ustring)mask_data->getId(); + SPCSSAttr *css = sp_repr_css_attr_new(); + if(mask_data->getRepr()->attribute("style")) { + sp_repr_css_attr_add_from_string(css, mask_data->getRepr()->attribute("style")); + } + char const* filter = sp_repr_css_property (css, "filter", ""); + if(!filter ||! strcmp(filter, filter_uri.c_str())) { + if (filter_uri.empty()) { + sp_repr_css_set_property (css, "filter", NULL); + } else { + sp_repr_css_set_property (css, "filter", filter_uri.c_str()); + } + Glib::ustring css_str; + sp_repr_css_write_string(css, css_str); + mask_data->getRepr()->setAttribute("style", css_str.c_str()); + } else if(wrap){ + Glib::ustring g_data_id = mask_data_id + (Glib::ustring)"_container"; + Inkscape::XML::Node * container = xml_doc->createElement("svg:g"); + container->setAttribute("id", g_data_id.c_str()); + mask->appendChildRepr(container); + container->setPosition(mask_data->getPosition()); + container->appendChild(mask_data->getRepr()); + Inkscape::GC::release(container); + SPCSSAttr *css = sp_repr_css_attr_new(); + if (filter_uri.empty()) { + sp_repr_css_set_property (css, "filter", NULL); + } else { + sp_repr_css_set_property (css, "filter", filter_uri.c_str()); + } + Glib::ustring css_str; + sp_repr_css_write_string(css, css_str); + container->setAttribute("style", css_str.c_str()); + } + } + } + if (background) { + if ((elemref = document->getObjectById(box_id))) { + if (strcmp(previous_background_style, background_style.param_getSVGValue())) { + elemref->getRepr()->setAttribute("style", background_style.param_getSVGValue()); + } + } else { + std::vector mask_list = mask->childList(true); + box = xml_doc->createElement("svg:path"); + box->setAttribute("id", box_id.c_str()); + 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); + box->setPosition(mask_list.size()); + Inkscape::GC::release(box); + mask_list.clear(); + } } 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); + if ((elemref = document->getObjectById(box_id))) { + elemref->deleteObject(true); + } } + previous_invert = invert; + previous_wrap = wrap; + previous_background_style = background_style.param_getSVGValue(); } void @@ -161,9 +229,6 @@ LPEPowerMask::newWidget() if ((*it)->widget_is_visible) { Parameter * param = *it; Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - if(param->param_key == "grid") { - widg = NULL; - } Glib::ustring * tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); @@ -193,8 +258,10 @@ LPEPowerMask::doOnRemove (SPLPEItem const* /*lpeitem*/) SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); if(!keep_paths) { if(mask) { - inverse.param_setValue(false); - setInverse(); + invert.param_setValue(false); + wrap.param_setValue(false); + background.param_setValue(false); + setMask(); } } } diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index 4038f207e..4869fbc53 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -8,8 +8,7 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/hidden.h" -#include "live_effects/parameter/path.h" +#include "live_effects/parameter/text.h" #include "live_effects/lpegroupbbox.h" namespace Inkscape { @@ -23,11 +22,17 @@ public: virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toggleMask(); - void setInverse(); + void setMask(); private: - BoolParam inverse; + BoolParam invert; + BoolParam wrap; + BoolParam background; + TextParam background_style; Geom::Path mask_box; bool hide_mask; + bool previous_invert; + bool previous_wrap; + const gchar * previous_background_style; }; } //namespace LivePathEffect diff --git a/src/sp-clippath.h b/src/sp-clippath.h index 7b1c83356..129f3b7f3 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -21,7 +21,6 @@ struct SPClipPathView; #include - #include "sp-object-group.h" #include "uri-references.h" #include "xml/node.h" diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 4690ffda2..a47fab35e 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -23,7 +23,8 @@ #include "attributes.h" #include "document.h" #include "document-private.h" - +#include "style.h" +#include "attributes.h" #include "sp-mask.h" struct SPMaskView { -- cgit v1.2.3 From 9a581994db67e6f788a24ea20fa150ed7837c489 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 10 Jun 2017 16:27:16 +0200 Subject: Working on powermask --- src/live_effects/lpe-powerclip.cpp | 2 +- src/live_effects/lpe-powermask.cpp | 212 ++++++++++++++++++++----------------- src/live_effects/lpe-powermask.h | 3 - 3 files changed, 118 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index ee1603855..d33e05176 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -40,7 +40,6 @@ LPEPowerClip::~LPEPowerClip() {} void LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ original_bbox(lpeitem); - const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("clip-path"); SPClipPath *clip_path = SP_ITEM(lpeitem)->clip_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); @@ -55,6 +54,7 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ //clip_path *= sp_lpe_item->i2dt_affine(); if(clip_path) { is_clip = true; + const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("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; diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index a49d4c493..8b9d981c4 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -26,9 +26,9 @@ namespace LivePathEffect { LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) : Effect(lpeobject), invert(_("Invert mask"), _("Invert mask"), "invert", &wr, this, false), - wrap(_("Wrap filtered clip data"), _("Wrap filtered clip data"), "wrap", &wr, this, false), + wrap(_("Wrap clip data"), _("Wrap clip data allowing previous filters"), "wrap", &wr, this, false), background(_("Add background to mask"), _("Add background to mask"), "background", &wr, this, false), - background_style(_("Background Style"), _("CSS to background"), "background_style", &wr, this,"fill:#ffffff;opacity:0.7;") + background_style(_("Background Style"), _("CSS to background"), "background_style", &wr, this,"fill:#ffffff;opacity:1;") { registerParameter(&invert); @@ -37,9 +37,6 @@ LPEPowerMask::LPEPowerMask(LivePathEffectObject *lpeobject) registerParameter(&background_style); background_style.param_hide_canvas_text(); hide_mask = false; - previous_invert = !invert; - previous_wrap = !wrap; - previous_background_style = ""; } LPEPowerMask::~LPEPowerMask() {} @@ -78,110 +75,128 @@ LPEPowerMask::setMask(){ Inkscape::XML::Node *filter = NULL; SPDefs * defs = document->getDefs(); Glib::ustring mask_id = (Glib::ustring)mask->getId(); - Glib::ustring box_id = mask_id + (Glib::ustring)"_transparentbox"; + Glib::ustring box_id = mask_id + (Glib::ustring)"_box"; Glib::ustring filter_id = mask_id + (Glib::ustring)"_inverse"; - Glib::ustring filter_uri = (Glib::ustring)"url(#" + mask_id + (Glib::ustring)"_inverse)"; - if (previous_invert != invert || previous_wrap != wrap) { - if (invert) { - if (!(elemref = document->getObjectById(filter_id))) { - filter = xml_doc->createElement("svg:filter"); - filter->setAttribute("id", filter_id.c_str()); - 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"); - Glib::ustring primitive1_id = (mask_id + (Glib::ustring)"_primitive1").c_str(); - primitive1->setAttribute("id", primitive1_id.c_str()); - primitive1->setAttribute("values", "1"); - primitive1->setAttribute("type", "saturate"); - primitive1->setAttribute("result", "fbSourceGraphic"); - Inkscape::XML::Node *primitive2 = xml_doc->createElement("svg:feColorMatrix"); - Glib::ustring primitive2_id = (mask_id + (Glib::ustring)"_primitive2").c_str(); - primitive2->setAttribute("id", primitive2_id.c_str()); - 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); - } - } else { - if ((elemref = document->getObjectById(filter_id))) { - elemref->deleteObject(true); - } - filter_uri = ""; + Glib::ustring filter_label = (Glib::ustring)"filter" + mask_id; + Glib::ustring filter_uri = (Glib::ustring)"url(#" + filter_id + (Glib::ustring)")"; + if (!(elemref = document->getObjectById(filter_id))) { + filter = xml_doc->createElement("svg:filter"); + filter->setAttribute("id", filter_id.c_str()); + filter->setAttribute("inkscape:label", filter_label.c_str()); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "color-interpolation-filters", "sRGB"); + sp_repr_css_change(filter, css, "style"); + sp_repr_css_attr_unref(css); + 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"); + Glib::ustring primitive1_id = (mask_id + (Glib::ustring)"_primitive1").c_str(); + primitive1->setAttribute("id", primitive1_id.c_str()); + primitive1->setAttribute("values", "1"); + primitive1->setAttribute("type", "saturate"); + primitive1->setAttribute("result", "fbSourceGraphic"); + Inkscape::XML::Node *primitive2 = xml_doc->createElement("svg:feColorMatrix"); + Glib::ustring primitive2_id = (mask_id + (Glib::ustring)"_primitive2").c_str(); + primitive2->setAttribute("id", primitive2_id.c_str()); + 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); + Inkscape::GC::release(filter); + filter->appendChild(primitive1); + Inkscape::GC::release(primitive1); + filter->appendChild(primitive2); + Inkscape::GC::release(primitive2); + } + if (background) { + if ((elemref = document->getObjectById(box_id))) { + elemref->deleteObject(true); } - std::vector mask_list = mask->childList(true); - for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { - SPItem * mask_data = SP_ITEM(*iter); - if (! strcmp(mask_data->getId(), box_id.c_str())){ - continue; - } - Glib::ustring mask_data_id = (Glib::ustring)mask_data->getId(); - SPCSSAttr *css = sp_repr_css_attr_new(); - if(mask_data->getRepr()->attribute("style")) { - sp_repr_css_attr_add_from_string(css, mask_data->getRepr()->attribute("style")); - } - char const* filter = sp_repr_css_property (css, "filter", ""); - if(!filter ||! strcmp(filter, filter_uri.c_str())) { - if (filter_uri.empty()) { - sp_repr_css_set_property (css, "filter", NULL); - } else { - sp_repr_css_set_property (css, "filter", filter_uri.c_str()); + box = xml_doc->createElement("svg:path"); + box->setAttribute("id", box_id.c_str()); + 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); + box->setPosition(1); + Inkscape::GC::release(box); + } + if(wrap){ + Glib::ustring g_data_id = mask_id + (Glib::ustring)"_container"; + if((elemref = document->getObjectById(g_data_id))){ + elemref->getRepr()->setPosition(-1); + } else { + Inkscape::XML::Node * container = xml_doc->createElement("svg:g"); + container->setAttribute("id", g_data_id.c_str()); + mask->appendChildRepr(container); + std::vector mask_list = mask->childList(true); + container->setPosition(-1); + Inkscape::GC::release(container); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPItem * mask_data = SP_ITEM(*iter); + Inkscape::XML::Node *mask_node = mask_data->getRepr(); + if (! strcmp(mask_data->getId(), box_id.c_str()) || + ! strcmp(mask_data->getId(), g_data_id.c_str())) + { + continue; } - Glib::ustring css_str; - sp_repr_css_write_string(css, css_str); - mask_data->getRepr()->setAttribute("style", css_str.c_str()); - } else if(wrap){ - Glib::ustring g_data_id = mask_data_id + (Glib::ustring)"_container"; - Inkscape::XML::Node * container = xml_doc->createElement("svg:g"); - container->setAttribute("id", g_data_id.c_str()); - mask->appendChildRepr(container); - container->setPosition(mask_data->getPosition()); - container->appendChild(mask_data->getRepr()); - Inkscape::GC::release(container); SPCSSAttr *css = sp_repr_css_attr_new(); - if (filter_uri.empty()) { + if(mask_node->attribute("style")) { + sp_repr_css_attr_add_from_string(css, mask_node->attribute("style")); + } + char const* filter = sp_repr_css_property (css, "filter", NULL); + if(!filter || !strcmp(filter, filter_uri.c_str())) { sp_repr_css_set_property (css, "filter", NULL); - } else { - sp_repr_css_set_property (css, "filter", filter_uri.c_str()); } Glib::ustring css_str; sp_repr_css_write_string(css, css_str); - container->setAttribute("style", css_str.c_str()); - } - } - } - if (background) { - if ((elemref = document->getObjectById(box_id))) { - if (strcmp(previous_background_style, background_style.param_getSVGValue())) { - elemref->getRepr()->setAttribute("style", background_style.param_getSVGValue()); + mask_node->setAttribute("style", css_str.c_str()); + mask->getRepr()->removeChild(mask_node); + container->appendChild(mask_node); + Inkscape::GC::release(mask_node); } - } else { - std::vector mask_list = mask->childList(true); - box = xml_doc->createElement("svg:path"); - box->setAttribute("id", box_id.c_str()); - 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); - box->setPosition(mask_list.size()); - Inkscape::GC::release(box); - mask_list.clear(); } } else { - if ((elemref = document->getObjectById(box_id))) { + Glib::ustring g_data_id = mask_id + (Glib::ustring)"_container"; + if((elemref = document->getObjectById(g_data_id))){ + std::vector item_list = sp_item_group_item_list(SP_GROUP(elemref)); + for ( std::vector::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) { + Inkscape::XML::Node *mask_node = (*iter)->getRepr(); + elemref->getRepr()->removeChild(mask_node); + mask->getRepr()->appendChild(mask_node); + Inkscape::GC::release(mask_node); + } + sp_object_ref(elemref, 0 ); elemref->deleteObject(true); + sp_object_unref(elemref); + } + } + std::vector mask_list = mask->childList(true); + for ( std::vector::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) { + SPItem * mask_data = SP_ITEM(*iter); + Inkscape::XML::Node *mask_node = mask_data->getRepr(); + if (! strcmp(mask_data->getId(), box_id.c_str())){ + continue; + } + Glib::ustring mask_data_id = (Glib::ustring)mask_data->getId(); + SPCSSAttr *css = sp_repr_css_attr_new(); + if(mask_node->attribute("style")) { + sp_repr_css_attr_add_from_string(css, mask_node->attribute("style")); + } + char const* filter = sp_repr_css_property (css, "filter", NULL); + if(!filter || !strcmp(filter, filter_uri.c_str())) { + if (invert) { + sp_repr_css_set_property (css, "filter", filter_uri.c_str()); + } else { + sp_repr_css_set_property (css, "filter", NULL); + } + Glib::ustring css_str; + sp_repr_css_write_string(css, css_str); + mask_node->setAttribute("style", css_str.c_str()); } } - previous_invert = invert; - previous_wrap = wrap; - previous_background_style = background_style.param_getSVGValue(); } void @@ -262,6 +277,13 @@ LPEPowerMask::doOnRemove (SPLPEItem const* /*lpeitem*/) wrap.param_setValue(false); background.param_setValue(false); setMask(); + SPObject *elemref = NULL; + SPDocument * document = SP_ACTIVE_DOCUMENT; + Glib::ustring mask_id = (Glib::ustring)mask->getId(); + Glib::ustring filter_id = mask_id + (Glib::ustring)"_inverse"; + if ((elemref = document->getObjectById(filter_id))) { + elemref->deleteObject(true); + } } } } diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index 4869fbc53..1bd06e914 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -30,9 +30,6 @@ private: TextParam background_style; Geom::Path mask_box; bool hide_mask; - bool previous_invert; - bool previous_wrap; - const gchar * previous_background_style; }; } //namespace LivePathEffect -- cgit v1.2.3 From 2218ecdfec042a7ee333e9091790e2d1e398350f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 11 Jun 2017 20:58:59 +0200 Subject: Working on powermask --- src/live_effects/lpe-powermask.cpp | 23 +++++++++++++++++++---- src/live_effects/lpe-powermask.h | 1 + 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 8b9d981c4..cc276c870 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -67,7 +67,12 @@ LPEPowerMask::setMask(){ SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); SPObject *elemref = NULL; SPDocument * document = SP_ACTIVE_DOCUMENT; - if(!document || !mask) { + if (!document || !mask) { + return; + } + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); + Inkscape::XML::Node *root_origin = document->getReprRoot(); + if (root_origin != root) { return; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); @@ -109,10 +114,10 @@ LPEPowerMask::setMask(){ filter->appendChild(primitive2); Inkscape::GC::release(primitive2); } + if ((elemref = document->getObjectById(box_id))) { + elemref->deleteObject(true); + } if (background) { - if ((elemref = document->getObjectById(box_id))) { - elemref->deleteObject(true); - } box = xml_doc->createElement("svg:path"); box->setAttribute("id", box_id.c_str()); box->setAttribute("style", background_style.param_getSVGValue()); @@ -187,9 +192,12 @@ LPEPowerMask::setMask(){ } char const* filter = sp_repr_css_property (css, "filter", NULL); if(!filter || !strcmp(filter, filter_uri.c_str())) { + if (invert) { + std::cout << "qqqqqqqqqqqqqqqqqqqqqqqqq\n"; sp_repr_css_set_property (css, "filter", filter_uri.c_str()); } else { + std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaqq\n"; sp_repr_css_set_property (css, "filter", NULL); } Glib::ustring css_str; @@ -197,6 +205,13 @@ LPEPowerMask::setMask(){ mask_node->setAttribute("style", css_str.c_str()); } } + mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +LPEPowerMask::doEffect (SPCurve * curve) +{ + } void diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index 1bd06e914..1cc7a888b 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -19,6 +19,7 @@ public: LPEPowerMask(LivePathEffectObject *lpeobject); virtual ~LPEPowerMask(); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doEffect (SPCurve * curve); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); void toggleMask(); -- cgit v1.2.3 From c5f2e56e9564c601d3210b8570d9a736a01e390b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 12 Jun 2017 20:09:40 +0200 Subject: adding last changes --- src/live_effects/lpe-powermask.cpp | 50 +++++++++++++++++++------------------- src/live_effects/lpe-powermask.h | 1 + 2 files changed, 26 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index cc276c870..decfa842d 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -44,7 +44,6 @@ LPEPowerMask::~LPEPowerMask() {} void LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ original_bbox(lpeitem); - const Glib::ustring uri = (Glib::ustring)sp_lpe_item->getRepr()->attribute("mask"); 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); @@ -56,7 +55,6 @@ LPEPowerMask::doBeforeEffect (SPLPEItem const* lpeitem){ mask_box.appendNew(bottomright); mask_box.appendNew(bottomleft); mask_box.close(); - //mask *= sp_lpe_item->i2dt_affine(); if(mask) { setMask(); } @@ -114,21 +112,7 @@ LPEPowerMask::setMask(){ filter->appendChild(primitive2); Inkscape::GC::release(primitive2); } - if ((elemref = document->getObjectById(box_id))) { - elemref->deleteObject(true); - } - if (background) { - box = xml_doc->createElement("svg:path"); - box->setAttribute("id", box_id.c_str()); - 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); - box->setPosition(1); - Inkscape::GC::release(box); - } - if(wrap){ + if(wrap && is_visible){ Glib::ustring g_data_id = mask_id + (Glib::ustring)"_container"; if((elemref = document->getObjectById(g_data_id))){ elemref->getRepr()->setPosition(-1); @@ -192,12 +176,9 @@ LPEPowerMask::setMask(){ } char const* filter = sp_repr_css_property (css, "filter", NULL); if(!filter || !strcmp(filter, filter_uri.c_str())) { - - if (invert) { - std::cout << "qqqqqqqqqqqqqqqqqqqqqqqqq\n"; + if (invert && is_visible) { sp_repr_css_set_property (css, "filter", filter_uri.c_str()); } else { - std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaqq\n"; sp_repr_css_set_property (css, "filter", NULL); } Glib::ustring css_str; @@ -205,13 +186,32 @@ LPEPowerMask::setMask(){ mask_node->setAttribute("style", css_str.c_str()); } } + if ((elemref = document->getObjectById(box_id))) { + elemref->deleteObject(true); + } + if (background && is_visible) { + box = xml_doc->createElement("svg:path"); + box->setAttribute("id", box_id.c_str()); + 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); + box->setPosition(1); + Inkscape::GC::release(box); + } mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } +void +LPEPowerMask::doOnVisibilityToggled(SPLPEItem const* lpeitem) +{ + doBeforeEffect(lpeitem); +} + void LPEPowerMask::doEffect (SPCurve * curve) { - } void @@ -283,11 +283,11 @@ LPEPowerMask::newWidget() } void -LPEPowerMask::doOnRemove (SPLPEItem const* /*lpeitem*/) +LPEPowerMask::doOnRemove (SPLPEItem const* lpeitem) { - SPMask *mask = SP_ITEM(sp_lpe_item)->mask_ref->getObject(); if(!keep_paths) { - if(mask) { + SPMask *mask = lpeitem->mask_ref->getObject(); + if (mask) { invert.param_setValue(false); wrap.param_setValue(false); background.param_setValue(false); diff --git a/src/live_effects/lpe-powermask.h b/src/live_effects/lpe-powermask.h index 1cc7a888b..ce6166a72 100644 --- a/src/live_effects/lpe-powermask.h +++ b/src/live_effects/lpe-powermask.h @@ -22,6 +22,7 @@ public: virtual void doEffect (SPCurve * curve); virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); virtual Gtk::Widget * newWidget(); + virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); void toggleMask(); void setMask(); private: -- cgit v1.2.3 From e1b08bb2e05c407f3e524e5d9f7b63ae88e15f6c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 24 Jun 2017 19:45:12 +0200 Subject: Working with powerclip and powermask --- src/live_effects/effect.cpp | 1 + src/live_effects/lpe-powerclip.cpp | 127 +++++++++++++++++++++++++------------ src/live_effects/lpe-powerclip.h | 6 +- src/live_effects/lpe-powermask.cpp | 49 ++++++++++++-- src/live_effects/lpe-powermask.h | 2 + src/sp-item.cpp | 7 +- src/sp-path.cpp | 3 +- 7 files changed, 146 insertions(+), 49 deletions(-) (limited to 'src') 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(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 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 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 (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 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); } - 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); + } } } } @@ -159,6 +161,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") { @@ -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(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 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 && 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::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 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::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::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(this) || dynamic_cast(this)))) { + if (!(dynamic_cast(this) || dynamic_cast(this))) { for (auto& o: children) { SPItem *item = dynamic_cast(&o); if (item) { @@ -1401,7 +1401,6 @@ void SPItem::adjust_livepatheffect (Geom::Affine const &postmul, bool set) SPLPEItem *lpeitem = dynamic_cast(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; -- cgit v1.2.3 From d4eac71f31f34723469e332791df919e1c64d7d3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 24 Jun 2017 21:50:49 +0200 Subject: Bug fixes --- src/live_effects/lpe-powerclip.cpp | 14 +++++++++----- src/live_effects/lpe-powerclip.h | 3 +-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index b83c50ea0..2d0d4bb12 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -113,6 +113,8 @@ LPEPowerClip::doBeforeEffect (SPLPEItem const* lpeitem){ } else { removeInverse(SP_ITEM(clip_data)); } + } else if (inverse && !is_visible && is_inverse.param_getSVGValue() == (Glib::ustring)"true"){ + removeInverse(SP_ITEM(clip_data)); } } } else { @@ -161,11 +163,6 @@ LPEPowerClip::addInverse (SPItem * clip_data){ } } -void -LPEPowerClip::doEffect (SPCurve * curve) -{ -} - void LPEPowerClip::removeInverse (SPItem * clip_data){ if(is_inverse.param_getSVGValue() == (Glib::ustring)"true") { @@ -321,6 +318,13 @@ LPEPowerClip::doEffect_path(Geom::PathVector const & path_in){ return path_out; } +void +LPEPowerClip::doOnVisibilityToggled(SPLPEItem const* lpeitem) +{ + doBeforeEffect(lpeitem); +} + + //void //LPEPowerClip::transform_multiply(Geom::Affine const& postmul, bool set) //{ diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index adaa8b7a1..ce46b560a 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -20,11 +20,10 @@ public: virtual ~LPEPowerClip(); virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); - 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); - + virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); void toggleClip(); void addInverse (SPItem * clip_data); void removeInverse (SPItem * clip_data); -- cgit v1.2.3