From 54dcba355d650c72c845711e0c857734f8d5d5b6 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sat, 18 Nov 2017 17:22:01 +1300 Subject: Add arc radius to toolbar --- src/widgets/arc-toolbar.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) (limited to 'src') diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 23e1eba1a..77bfdaf01 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -45,15 +45,20 @@ #include "toolbox.h" #include "ui/icon-names.h" #include "ui/uxmanager.h" +#include "ui/widget/unit-tracker.h" #include "ui/tools/arc-tool.h" #include "verbs.h" #include "widgets/spinbutton-events.h" +#include "widgets/widget-sizes.h" #include "xml/node-event-vector.h" +using Inkscape::UI::Widget::UnitTracker; using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +using Inkscape::Util::Quantity; +using Inkscape::Util::unit_table; //######################## //## Circle / Arc ## @@ -75,6 +80,72 @@ static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) } } +static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + SPDocument* document = desktop->getDocument(); + Geom::Scale scale = document->getDocumentScale(); + + if (DocumentUndo::getUndoSensitive(document)) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, + Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + bool modmade = false; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_GENERICELLIPSE(item)) { + + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (!strcmp(value_name, "rx")) { + ge->rx = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::X]; + } else { + ge->ry = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::Y]; + } + + ge->normalize(); + (SP_OBJECT(ge))->updateRepr(); + (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + modmade = true; + } + } + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, + _("Change arc")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_arctb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_value_changed(adj, tbl, "rx"); +} + +static void sp_arctb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_value_changed(adj, tbl, "ry"); +} + static void sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name) { @@ -204,6 +275,14 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_arctb_defaults(GtkWidget *, GObject *obj) { GtkAdjustment *adj; + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") ); + gtk_adjustment_set_value(adj, 0.0); + gtk_adjustment_value_changed(adj); + + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") ); + gtk_adjustment_set_value(adj, 0.0); + gtk_adjustment_value_changed(adj); + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") ); gtk_adjustment_set_value(adj, 0.0); gtk_adjustment_value_changed(adj); @@ -229,6 +308,34 @@ static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * / // in turn, prevent callbacks from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + gdouble radius = 0; + gdouble rx = 0; + gdouble ry = 0; + sp_repr_get_double(repr, "r", &radius); + if (radius) { + rx = ry = radius; + } else { + sp_repr_get_double(repr, "rx", &rx); + sp_repr_get_double(repr, "ry", &ry); + } + + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + SPDocument* document = desktop->getDocument(); + Geom::Scale scale = document->getDocumentScale(); + + GtkAdjustment *adj; + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); + gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit) * scale[Geom::X]); + gtk_adjustment_value_changed(adj); + + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); + gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit) * scale[Geom::Y]); + gtk_adjustment_value_changed(adj); + gdouble start = 0.; gdouble end = 0.; sp_repr_get_double(repr, "sodipodi:start", &start); @@ -297,6 +404,11 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + GtkAction* rx = GTK_ACTION( g_object_get_data( tbl, "rx_action" ) ); + gtk_action_set_sensitive(rx, TRUE); + GtkAction* ry = GTK_ACTION( g_object_get_data( tbl, "ry_action" ) ); + gtk_action_set_sensitive(ry, TRUE); + if (repr) { g_object_set_data( tbl, "repr", repr ); Inkscape::GC::anchor(repr); @@ -320,6 +432,9 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec EgeAdjustmentAction* eact = 0; GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->setActiveUnit(unit_table.getUnit("px")); + g_object_set_data( holder, "tracker", tracker ); { EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("New:"), "", 0 ); @@ -328,6 +443,46 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec g_object_set_data( holder, "mode_action", act ); } + /* Radius X */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "ArcRadiusXAction", + _("Radius X"), _("Rx:"), _("X Radius of arc"), + "/tools/shapes/arc/rx", 0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_arctb_rx_value_changed, tracker); + tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); + g_object_set_data( holder, "rx_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Radius Y */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "ArcRadiusYAction", + _("Radius Y"), _("Ry:"), _("Y Radius of arc"), + "/tools/shapes/arc/ry", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_arctb_ry_value_changed, tracker); + tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); + g_object_set_data( holder, "ry_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + // add the units menu + { + GtkAction* act = tracker->createAction( "ArcUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act ); + } + /* Start */ { eact = create_adjustment_action( "ArcStartAction", -- cgit v1.2.3 From 25e5f4d5c57be30b7947a16867b5a6044a892f52 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 4 Dec 2017 18:24:16 +0100 Subject: Adding fix to sliders and spin buttons on LPE --- src/live_effects/parameter/parameter.cpp | 11 +++++++---- src/live_effects/parameter/parameter.h | 2 ++ src/live_effects/parameter/point.cpp | 6 ++++++ src/live_effects/parameter/point.h | 1 + src/live_effects/parameter/random.cpp | 7 ++++++- src/live_effects/parameter/random.h | 1 + src/ui/widget/registered-widget.cpp | 24 ++++++++++-------------- src/ui/widget/registered-widget.h | 3 +-- src/ui/widget/scalar.cpp | 6 +++++- src/ui/widget/scalar.h | 6 ++++-- 10 files changed, 43 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 319ab3fe8..497113e03 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -129,9 +129,6 @@ ScalarParam::param_update_default(const gchar * default_value) void ScalarParam::param_set_value(gdouble val) { - if (value != val) { - param_effect->upd_params = true; - } value = val; if (integer) value = round(value); @@ -180,7 +177,7 @@ ScalarParam::param_set_undo(bool set_undo) Gtk::Widget * ScalarParam::param_newWidget() { - if(widget_is_visible){ + 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() ) ); @@ -192,6 +189,7 @@ ScalarParam::param_newWidget() if (add_slider) { rsu->addSlider(); } + rsu->signal_button_release_event().connect(sigc::mem_fun (*this, &ScalarParam::on_button_release)); if(_set_undo){ rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } @@ -201,6 +199,11 @@ ScalarParam::param_newWidget() } } +bool ScalarParam::on_button_release(GdkEventButton* button_event) { + param_effect->upd_params = true; + return false; +} + void ScalarParam::param_set_digits(unsigned digits) { diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 1586ef346..aa4212f15 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -141,6 +141,8 @@ protected: bool _set_undo; private: + bool on_button_release(GdkEventButton* button_event); + ScalarParam(const ScalarParam&); ScalarParam& operator=(const ScalarParam&); }; diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index da6edf812..ff5f59ce2 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -146,6 +146,7 @@ PointParam::param_newWidget() pointwdg->setValue( *this ); pointwdg->clearProgrammatically(); pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); + pointwdg->signal_button_release_event().connect(sigc::mem_fun (*this, &PointParam::on_button_release)); Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); static_cast(hbox)->pack_start(*pointwdg, true, true); @@ -153,6 +154,11 @@ PointParam::param_newWidget() return dynamic_cast (hbox); } +bool PointParam::on_button_release(GdkEventButton* button_event) { + param_effect->upd_params = true; + return false; +} + void PointParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) { diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 03256f6d0..6c5f8df65 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -57,6 +57,7 @@ public: private: PointParam(const PointParam&); PointParam& operator=(const PointParam&); + bool on_button_release(GdkEventButton* button_event); Geom::Point defvalue; bool liveupdate; KnotHolder *knoth; diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp index c2c1b5440..4afa43c6e 100644 --- a/src/live_effects/parameter/random.cpp +++ b/src/live_effects/parameter/random.cpp @@ -103,7 +103,6 @@ RandomParam::param_update_default(const gchar * default_value){ void RandomParam::param_set_value(gdouble val, long newseed) { - param_effect->upd_params = true; value = val; if (integer) value = round(value); @@ -154,12 +153,18 @@ RandomParam::param_newWidget() } regrandom->setRange(min, max); regrandom->setProgrammatically = false; + regrandom->signal_button_release_event().connect(sigc::mem_fun (*this, &RandomParam::on_button_release)); regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter")); return dynamic_cast (regrandom); } +bool RandomParam::on_button_release(GdkEventButton* button_event) { + param_effect->upd_params = true; + return false; +} + RandomParam::operator gdouble() { return rand() * value; diff --git a/src/live_effects/parameter/random.h b/src/live_effects/parameter/random.h index c10473e85..a2c3712a1 100644 --- a/src/live_effects/parameter/random.h +++ b/src/live_effects/parameter/random.h @@ -57,6 +57,7 @@ protected: gdouble defvalue; private: + bool on_button_release(GdkEventButton* button_event); long setup_seed(long); gdouble rand(); diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index a88413347..5dfc70cc3 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -279,7 +279,6 @@ RegisteredScalar::RegisteredScalar ( const Glib::ustring& label, const Glib::ust init_parent(key, wr, repr_in, doc_in); setProgrammatically = false; - setRange (-1e6, 1e6); setDigits (2); setIncrements(0.1, 1.0); @@ -299,12 +298,14 @@ RegisteredScalar::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - os << getValue(); - - set_sensitive(false); + //Force exact 0 if decimals over to 10 + double val = getValue() < 1E-10 && getValue() > -1E-10?0.0:getValue(); + os << val << ';'; + //TODO: Test is ok remove this sensitives + //also removed in registed text and in registered random + //set_sensitive(false); write_to_xml(os.str().c_str()); - set_sensitive(true); - + //set_sensitive(true); _wr->setUpdating (false); } @@ -342,11 +343,9 @@ RegisteredText::on_activate() } _wr->setUpdating (true); Glib::ustring str(getText()); - set_sensitive(false); Inkscape::SVGOStringStream os; os << str; write_to_xml(os.str().c_str()); - set_sensitive(true); _wr->setUpdating (false); } @@ -757,7 +756,6 @@ RegisteredRandom::RegisteredRandom ( const Glib::ustring& label, const Glib::ust init_parent(key, wr, repr_in, doc_in); setProgrammatically = false; - setRange (-1e6, 1e6); setDigits (2); setIncrements(0.1, 1.0); @@ -786,12 +784,10 @@ RegisteredRandom::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - os << getValue() << ';' << getStartSeed(); - - set_sensitive(false); + //Force exact 0 if decimals over to 10 + double val = getValue() < 1E-10 && getValue() > -1E-10?0.0:getValue(); + os << val << ';' << getStartSeed(); write_to_xml(os.str().c_str()); - set_sensitive(true); - _wr->setUpdating (false); } diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index f66d5cbf2..26f93ba7f 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -244,9 +244,8 @@ public: Registry& wr, Inkscape::XML::Node* repr_in = NULL, SPDocument *doc_in = NULL ); - protected: - sigc::connection _value_changed_connection; + sigc::connection _value_changed_connection; void on_value_changed(); }; diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index f8543a371..4d0edeac3 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -14,7 +14,6 @@ # include #endif - #include "scalar.h" #include "spinbutton.h" #include @@ -30,6 +29,7 @@ Scalar::Scalar(Glib::ustring const &label, Glib::ustring const &tooltip, : Labelled(label, tooltip, new SpinButton(), suffix, icon, mnemonic), setProgrammatically(false) { + } Scalar::Scalar(Glib::ustring const &label, Glib::ustring const &tooltip, @@ -149,6 +149,10 @@ Glib::SignalProxy0 Scalar::signal_value_changed() return static_cast(_widget)->signal_value_changed(); } +Glib::SignalProxy Scalar::signal_button_release_event() +{ + return static_cast(_widget)->signal_button_release_event(); +} } // namespace Widget } // namespace UI diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h index f186f46ac..80acaba0e 100644 --- a/src/ui/widget/scalar.h +++ b/src/ui/widget/scalar.h @@ -78,7 +78,6 @@ public: Glib::ustring const &suffix = "", Glib::ustring const &icon = "", bool mnemonic = true); - /** * Fetches the precision of the spin buton. */ @@ -151,7 +150,10 @@ public: * Signal raised when the spin button's value changes. */ Glib::SignalProxy0 signal_value_changed(); - + /** + * Signal raised when the spin button's pressed. + */ + Glib::SignalProxy< bool, GdkEventButton* > signal_button_release_event(); /** * true if the value was set by setValue, not changed by the user; * if a callback checks it, it must reset it back to false. -- cgit v1.2.3 From 63d4d37a384ea0ea7991a69325c164d082db11dc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 4 Dec 2017 20:09:34 +0100 Subject: Minor fixes to remove WIP --- src/ui/widget/registered-widget.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 5dfc70cc3..a3b87f89b 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -298,9 +298,9 @@ RegisteredScalar::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - //Force exact 0 if decimals over to 10 - double val = getValue() < 1E-10 && getValue() > -1E-10?0.0:getValue(); - os << val << ';'; + //Force exact 0 if decimals over to 6 + double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue(); + os << val; //TODO: Test is ok remove this sensitives //also removed in registed text and in registered random //set_sensitive(false); @@ -784,8 +784,8 @@ RegisteredRandom::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - //Force exact 0 if decimals over to 10 - double val = getValue() < 1E-10 && getValue() > -1E-10?0.0:getValue(); + //Force exact 0 if decimals over to 6 + double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue(); os << val << ';' << getStartSeed(); write_to_xml(os.str().c_str()); _wr->setUpdating (false); -- cgit v1.2.3 From 28552a7f1c2cfe77521602a4147b99a7f87a30d4 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 22:22:18 +0100 Subject: Do not reset rx/cx to zero when resetting arc to whole ellipse --- src/widgets/arc-toolbar.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 77bfdaf01..fd8ba0343 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -275,13 +275,6 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_arctb_defaults(GtkWidget *, GObject *obj) { GtkAdjustment *adj; - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") ); - gtk_adjustment_set_value(adj, 0.0); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") ); - gtk_adjustment_set_value(adj, 0.0); - gtk_adjustment_value_changed(adj); adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") ); gtk_adjustment_set_value(adj, 0.0); -- cgit v1.2.3 From 12a2f445e64e08e7d2dd12fde2ee17467238ebf9 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 23:08:51 +0100 Subject: Account for Inkscape's custom arcs (which do not have cx/cy) If an open arc is rendered we need to look at the prefixed values instead. --- src/widgets/arc-toolbar.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index fd8ba0343..77f74b348 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -315,6 +315,10 @@ static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * / sp_repr_get_double(repr, "rx", &rx); sp_repr_get_double(repr, "ry", &ry); } + if (!rx) { + sp_repr_get_double(repr, "sodipodi:rx", &rx); + sp_repr_get_double(repr, "sodipodi:ry", &ry); + } SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); SPDocument* document = desktop->getDocument(); -- cgit v1.2.3 From dfad76343452004bb06c92d19262d22dc3cb9e76 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 23:15:36 +0100 Subject: Prevent setting zero radius While the spec explicitly allows for that (and it should disable rendering of the element) Inkscape does not allow setting a zero radius at runtime (it works fine when opening an existing file). If we still force this during runtime we end up with a "ghost" ellipse on canvas which looks as if it had the old radius but has control points according to the zero radius and has the added bonus of not being movable (or rather being movable but snapping back back immediately when released) until updating the radius with a valid number again which finally moves the ellipse to wherever it should have been. --- src/widgets/arc-toolbar.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 77f74b348..0e503cd5e 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -82,6 +82,13 @@ static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name) { + // Per SVG spec "a [radius] value of zero disables rendering of the element". + // However our implementation does not allow a setting of zero in the UI (not even in the XML editor) + // and ugly things happen if it's forced here, so better leave the properties untouched. + if (!gtk_adjustment_get_value(adj)) { + return; + } + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); -- cgit v1.2.3 From 01d6520bcf68b688ca49b048ffd3a81044c3b135 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 23:36:13 +0100 Subject: Change labels a bit for consistency with other UI strings --- src/widgets/arc-toolbar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 0e503cd5e..3faea1750 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -452,7 +452,7 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; eact = create_adjustment_action( "ArcRadiusXAction", - _("Radius X"), _("Rx:"), _("X Radius of arc"), + _("Horizontal radius"), _("Rx:"), _("Horizontal radius of the circle, ellipse, or arc"), "/tools/shapes/arc/rx", 0, GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, @@ -469,7 +469,7 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; eact = create_adjustment_action( "ArcRadiusYAction", - _("Radius Y"), _("Ry:"), _("Y Radius of arc"), + _("Vertical radius"), _("Ry:"), _("Vertical radius of the circle, ellipse, or arc"), "/tools/shapes/arc/ry", 0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, -- cgit v1.2.3 From ad56baec4315d4059d3a99a796f60e3df9659964 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 4 Dec 2017 23:38:29 +0100 Subject: Working on compiling on linux problem --- src/ui/widget/registered-widget.h | 2 +- src/ui/widget/scalar.cpp | 3 ++- src/ui/widget/scalar.h | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 26f93ba7f..78de055de 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -12,11 +12,11 @@ #ifndef INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_ #define INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_ -#include "ui/widget/scalar.h" #include <2geom/affine.h> #include "xml/node.h" #include "registry.h" +#include "ui/widget/scalar.h" #include "ui/widget/scalar-unit.h" #include "ui/widget/point.h" #include "ui/widget/text.h" diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index 4d0edeac3..a0f1354a3 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -14,6 +14,7 @@ # include #endif + #include "scalar.h" #include "spinbutton.h" #include @@ -29,7 +30,6 @@ Scalar::Scalar(Glib::ustring const &label, Glib::ustring const &tooltip, : Labelled(label, tooltip, new SpinButton(), suffix, icon, mnemonic), setProgrammatically(false) { - } Scalar::Scalar(Glib::ustring const &label, Glib::ustring const &tooltip, @@ -154,6 +154,7 @@ Glib::SignalProxy Scalar::signal_button_release_event() return static_cast(_widget)->signal_button_release_event(); } + } // namespace Widget } // namespace UI } // namespace Inkscape diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h index 80acaba0e..80de5166d 100644 --- a/src/ui/widget/scalar.h +++ b/src/ui/widget/scalar.h @@ -78,6 +78,7 @@ public: Glib::ustring const &suffix = "", Glib::ustring const &icon = "", bool mnemonic = true); + /** * Fetches the precision of the spin buton. */ @@ -150,10 +151,12 @@ public: * Signal raised when the spin button's value changes. */ Glib::SignalProxy0 signal_value_changed(); + /** * Signal raised when the spin button's pressed. */ - Glib::SignalProxy< bool, GdkEventButton* > signal_button_release_event(); + Glib::SignalProxy signal_button_release_event(); + /** * true if the value was set by setValue, not changed by the user; * if a callback checks it, it must reset it back to false. -- cgit v1.2.3 From 5104d5c1cd675e8e81d0b241e81a331d65056b49 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 5 Dec 2017 00:09:17 +0100 Subject: Add fix to problem switching pen tool modes Add fix to bspline when two cusp nodes arround a powered node --- src/ui/tools/freehand-base.cpp | 60 +++++++++-------- src/ui/tools/freehand-base.h | 7 +- src/ui/tools/pen-tool.cpp | 145 ++++++++++++++--------------------------- src/ui/tools/pencil-tool.cpp | 47 +++++++++---- 4 files changed, 115 insertions(+), 144 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 064a83a5a..49b8436de 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -85,7 +85,7 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape) , green_anchor(NULL) , green_closed(false) , white_item(NULL) - , overwrite_curve(NULL) + , sa_overwrited(NULL) , sa(NULL) , ea(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) @@ -144,7 +144,7 @@ void FreehandBase::setup() { this->green_closed = FALSE; // Create start anchor alternative curve - this->overwrite_curve = new SPCurve(); + this->sa_overwrited = new SPCurve(); this->attach = TRUE; spdc_attach_selection(this, this->selection); @@ -599,6 +599,9 @@ static void spdc_selection_modified(Inkscape::Selection *sel, guint /*flags*/, F static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/) { + if (SP_IS_PENCIL_CONTEXT(dc) && dc->sa && dc->input_has_pressure) { + return; + } // We reset white and forget white/start/end anchors spdc_reset_white(dc); dc->sa = NULL; @@ -744,38 +747,21 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - c = reverse_then_unref(c); - } - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->overwrite_curve->append_continuous(c, 0.0625); - c->unref(); - dc->overwrite_curve->closepath_current(); - if(dc->sa){ - dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve)); - dc->white_curves.push_back(dc->overwrite_curve); - } - }else{ - dc->sa->curve->append_continuous(c, 0.0625); - c->unref(); - dc->sa->curve->closepath_current(); + dc->sa_overwrited->append_continuous(c, 0.0625); + c->unref(); + dc->sa_overwrited->closepath_current(); + if(dc->sa){ + dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve)); + dc->white_curves.push_back(dc->sa_overwrited); } + spdc_flush_white(dc, NULL); return; } - // Step C - test start if (dc->sa) { - SPCurve *s = dc->sa->curve; - dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), s)); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - s = dc->overwrite_curve; - } - if (dc->sa->start) { - s = reverse_then_unref(s); - } + dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve)); + SPCurve *s = dc->sa_overwrited; s->append_continuous(c, 0.0625); c->unref(); c = s; @@ -807,7 +793,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->append_continuous(e, 0.0625); e->unref(); } - if (forceclosed) { dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); @@ -882,8 +867,17 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) if(previous_shape_type == BEND_CLIPBOARD){ repr->parent()->removeChild(repr); } + } else if (SP_IS_PENCIL_CONTEXT(dc)) { + if (dc->input_has_pressure) { + spdc_check_for_and_apply_waiting_LPE(dc, dc->white_item, c, false); +// Inkscape::Preferences *prefs = Inkscape::Preferences::get(); +// shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); +// if (shape == NONE) { +// std::vector points; +// spdc_apply_powerstroke_shape(points, dc, dc->white_item); +// } + } } - DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, _("Draw path")); @@ -952,7 +946,11 @@ static void spdc_free_colors(FreehandBase *dc) if (dc->blue_curve) { dc->blue_curve = dc->blue_curve->unref(); } - + + // Overwrite start anchor curve + if (dc->sa_overwrited) { + dc->sa_overwrited = dc->sa_overwrited->unref(); + } // Green for (auto i : dc->green_bpaths) sp_canvas_item_destroy(i); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 02d0a9982..4a14cf8d3 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -76,11 +76,8 @@ public: std::list white_curves; std::vector white_anchors; - // Alternative curve to use on continuing the exisiting curve in case of - // bspline or spirolive, because using anchor curves gives random memory - // bugs as reported by su_v when running this code on macOS (as well as - // making the code hard to understand). - SPCurve *overwrite_curve; + // Temporary modiffied curve when start anchor + SPCurve *sa_overwrited; // Start anchor SPDrawAnchor *sa; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 16cdf63b5..a42a3a07a 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -423,7 +423,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { // This is allowed, if we just canceled curve case PenTool::POINT: if (this->npoints == 0) { - this->_bsplineSpiroColor(); + this->setPolylineMode(); Geom::Point p; if ((bevent.state & GDK_CONTROL_MASK) && (this->polylines_only || this->polylines_paraxial)) { p = event_dt; @@ -444,7 +444,13 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { // Set start anchor this->sa = anchor; - if(anchor){ + if (anchor) { + //Put the start overwrite curve always on the same direction + if (anchor->start) { + this->sa_overwrited = this->sa->curve->create_reverse(); + } else { + this->sa_overwrited = this->sa->curve->copy(); + } this->_bsplineSpiroStartAnchor(bevent.state & GDK_SHIFT_MASK); } if (anchor && (!this->hasWaitingLPE()|| this->bspline || this->spiro)) { @@ -473,7 +479,6 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { } this->_setInitialPoint(p); } else { - // Set end anchor this->ea = anchor; Geom::Point p; @@ -497,6 +502,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { this->_setSubsequentPoint(p, true); } } + this->_bsplineSpiroColor(); // avoid the creation of a control point so a node is created in the release event this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = true; @@ -734,26 +740,9 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::MODE_CLICK: switch (this->state) { case PenTool::POINT: - if ( this->npoints == 0 ) { - // Start new thread only with button release - this->_bsplineSpiroColor(); - if (anchor) { - p = anchor->dp; - } - this->sa = anchor; - // continue the existing curve - if (anchor) { - if(this->bspline || this->spiro){ - this->_bsplineSpiroStartAnchor(revent.state & GDK_SHIFT_MASK);; - } - } - this->_setInitialPoint(p); - } else { - // Set end anchor here - this->ea = anchor; - if (anchor) { - p = anchor->dp; - } + this->ea = anchor; + if (anchor) { + p = anchor->dp; } this->state = PenTool::CONTROL; break; @@ -1264,6 +1253,8 @@ void PenTool::_resetColors() { } this->sa = NULL; this->ea = NULL; + this->sa_overwrited->reset(); + this->npoints = 0; this->red_curve_is_valid = false; } @@ -1415,11 +1406,7 @@ void PenTool::_bsplineSpiroStartAnchor(bool shift) this->spiro = false; } if(!this->spiro && !this->bspline){ - SPCurve *tmp_curve = this->sa->curve->copy(); - if (this->sa->start) { - tmp_curve = tmp_curve ->create_reverse(); - } - this->overwrite_curve = tmp_curve ; + _bsplineSpiroColor(); return; } if(shift){ @@ -1433,14 +1420,10 @@ void PenTool::_bsplineSpiroStartAnchorOn() { using Geom::X; using Geom::Y; - SPCurve *tmp_curve = this->sa->curve->copy(); - if (this->sa->start) { - tmp_curve = tmp_curve ->create_reverse(); - } - Geom::CubicBezier const * cubic = dynamic_cast(&*tmp_curve ->last_segment()); + Geom::CubicBezier const * cubic = dynamic_cast(&*this->sa_overwrited ->last_segment()); SPCurve *last_segment = new SPCurve(); - Geom::Point point_a = tmp_curve->last_segment()->initialPoint(); - Geom::Point point_d = *tmp_curve->last_point(); + Geom::Point point_a = this->sa_overwrited->last_segment()->initialPoint(); + Geom::Point point_d = *this->sa_overwrited->last_point(); Geom::Point point_c = point_d + (1./3)*(point_a - point_d); point_c = Geom::Point(point_c[X] + HANDLE_CUBIC_GAP, point_c[Y] + HANDLE_CUBIC_GAP); if(cubic){ @@ -1450,43 +1433,34 @@ void PenTool::_bsplineSpiroStartAnchorOn() last_segment->moveto(point_a); last_segment->curveto(point_a,point_c,point_d); } - if( tmp_curve ->get_segment_count() == 1){ - tmp_curve = last_segment; + if( this->sa_overwrited->get_segment_count() == 1){ + this->sa_overwrited = last_segment->copy(); }else{ //we eliminate the last segment - tmp_curve ->backspace(); + this->sa_overwrited->backspace(); //and we add it again with the recreation - tmp_curve ->append_continuous(last_segment, 0.0625); + this->sa_overwrited->append_continuous(last_segment, 0.0625); } - if (this->sa->start) { - tmp_curve = tmp_curve ->create_reverse(); - } - this->overwrite_curve = tmp_curve ; + last_segment->unref(); } void PenTool::_bsplineSpiroStartAnchorOff() { - SPCurve *tmp_curve = this->sa->curve->copy(); - if(this->sa->start) - tmp_curve = tmp_curve ->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmp_curve ->last_segment()); + Geom::CubicBezier const * cubic = dynamic_cast(&*this->sa_overwrited->last_segment()); if(cubic){ SPCurve *last_segment = new SPCurve(); last_segment->moveto((*cubic)[0]); last_segment->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmp_curve ->get_segment_count() == 1){ - tmp_curve = last_segment; + if( this->sa_overwrited->get_segment_count() == 1){ + this->sa_overwrited = last_segment->copy(); }else{ //we eliminate the last segment - tmp_curve ->backspace(); + this->sa_overwrited->backspace(); //and we add it again with the recreation - tmp_curve ->append_continuous(last_segment, 0.0625); + this->sa_overwrited->append_continuous(last_segment, 0.0625); } + last_segment->unref(); } - if (this->sa->start) { - tmp_curve = tmp_curve ->create_reverse(); - } - this->overwrite_curve = tmp_curve; } void PenTool::_bsplineSpiroMotion(guint const state){ @@ -1503,17 +1477,14 @@ void PenTool::_bsplineSpiroMotion(guint const state){ this->p[2] = Geom::Point(this->p[2][X] + HANDLE_CUBIC_GAP,this->p[2][Y] + HANDLE_CUBIC_GAP); if (this->green_curve->is_unset() && !this->sa) { this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); - this->p[1] = Geom::Point(this->p[1][X] + HANDLE_CUBIC_GAP,this->p[1][Y] + HANDLE_CUBIC_GAP); + this->p[1] = Geom::Point(this->p[1][X] + HANDLE_CUBIC_GAP, this->p[1][Y] + HANDLE_CUBIC_GAP); if(shift){ this->p[2] = this->p[3]; } } else if (!this->green_curve->is_unset()){ tmp_curve = this->green_curve->copy(); } else { - tmp_curve = this->overwrite_curve->copy(); - if(this->sa->start) { - tmp_curve = tmp_curve ->create_reverse(); - } + tmp_curve = this->sa_overwrited->copy(); } if ((state & GDK_MOD1_MASK ) && previous != Geom::Point(0,0)) { //ALT drag this->p[0] = this->p[0] + (this->p[3] - previous); @@ -1550,11 +1521,7 @@ void PenTool::_bsplineSpiroMotion(guint const state){ } cubic = dynamic_cast(&*tmp_curve ->last_segment()); if (this->sa && this->green_curve->is_unset()) { - if(this->sa->start) { - this->overwrite_curve = tmp_curve->copy()->create_reverse(); - } else { - this->overwrite_curve = tmp_curve->copy(); - } + this->sa_overwrited = tmp_curve->copy(); } if (!this->green_bpaths.empty()) { this->green_curve = tmp_curve->copy(); @@ -1588,6 +1555,9 @@ void PenTool::_bsplineSpiroMotion(guint const state){ if (shift) { this->p[2] = this->p[3]; } + if(Geom::are_near((*cubic)[3], (*cubic)[2])) { + this->p[1] = this->p[0]; + } } else { this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] ); } @@ -1627,19 +1597,13 @@ void PenTool::_bsplineSpiroEndAnchorOn() SPCurve *tmp_curve; SPCurve *last_segment = new SPCurve(); Geom::Point point_c(0,0); - bool reverse = false; if( this->green_anchor && this->green_anchor->active ){ tmp_curve = this->green_curve->create_reverse(); if(this->green_curve->get_segment_count()==0){ return; } - reverse = true; } else if(this->sa){ - tmp_curve = this->overwrite_curve->copy(); - if(!this->sa->start){ - tmp_curve = tmp_curve ->create_reverse(); - reverse = true; - } + tmp_curve = this->sa_overwrited->copy()->create_reverse(); }else{ return; } @@ -1665,17 +1629,16 @@ void PenTool::_bsplineSpiroEndAnchorOn() //and we add it again with the recreation tmp_curve ->append_continuous(last_segment, 0.0625); } - if (reverse) { - tmp_curve = tmp_curve ->create_reverse(); - } + tmp_curve = tmp_curve ->create_reverse(); if( this->green_anchor && this->green_anchor->active ) { this->green_curve->reset(); - this->green_curve = tmp_curve ; + this->green_curve = tmp_curve->copy(); }else{ - this->overwrite_curve->reset(); - this->overwrite_curve = tmp_curve ; + this->sa_overwrited->reset(); + this->sa_overwrited = tmp_curve->copy(); } + tmp_curve->unref(); } void PenTool::_bsplineSpiroEndAnchorOff() @@ -1683,20 +1646,14 @@ void PenTool::_bsplineSpiroEndAnchorOff() SPCurve *tmp_curve; SPCurve *last_segment = new SPCurve(); - bool reverse = false; this->p[2] = this->p[3]; if( this->green_anchor && this->green_anchor->active ){ tmp_curve = this->green_curve->create_reverse(); if(this->green_curve->get_segment_count()==0){ return; } - reverse = true; } else if(this->sa){ - tmp_curve = this->overwrite_curve->copy(); - if(!this->sa->start){ - tmp_curve = tmp_curve ->create_reverse(); - reverse = true; - } + tmp_curve = this->sa_overwrited->copy()->create_reverse(); }else{ return; } @@ -1716,17 +1673,17 @@ void PenTool::_bsplineSpiroEndAnchorOff() //and we add it again with the recreation tmp_curve ->append_continuous(last_segment, 0.0625); } - if (reverse) { - tmp_curve = tmp_curve ->create_reverse(); - } + tmp_curve = tmp_curve ->create_reverse(); + if( this->green_anchor && this->green_anchor->active ) { this->green_curve->reset(); - this->green_curve = tmp_curve ; + this->green_curve = tmp_curve->copy(); }else{ - this->overwrite_curve->reset(); - this->overwrite_curve = tmp_curve ; + this->sa_overwrited->reset(); + this->sa_overwrited = tmp_curve->copy(); } + tmp_curve->unref(); } //prepares the curves for its transformation into BSpline curve. @@ -1740,10 +1697,7 @@ void PenTool::_bsplineSpiroBuild() SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start if(this->sa && !this->sa->curve->is_unset()){ - curve = this->overwrite_curve->copy(); - if (this->sa->start) { - curve = curve->create_reverse(); - } + curve = this->sa_overwrited->copy(); } if (!this->green_curve->is_unset()){ @@ -2038,7 +1992,6 @@ void PenTool::_finish(gboolean const closed) { // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); - this->overwrite_curve = NULL; this->sa = NULL; this->ea = NULL; diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index fb50898ed..96bd14a46 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -214,7 +214,12 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) { } if (anchor) { p = anchor->dp; - this->overwrite_curve = anchor->curve; + //Put the start overwrite curve always on the same direction + if (anchor->start) { + this->sa_overwrited = anchor->curve->create_reverse(); + } else { + this->sa_overwrited = anchor->curve->copy(); + } desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { m.setup(desktop, true, _powerpreview); @@ -278,6 +283,25 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) { return false; // Do not drag if we're within tolerance from origin. } } + // motion notify coordinates as given (no snapping back to origin) + if (input_has_pressure && pencil_within_tolerance) { + anchor = spdc_test_inside(this, pencil_drag_origin_w); + if (anchor) { + this->sa = anchor; + //Put the start overwrite curve always on the same direction + if (anchor->start) { + this->sa_overwrited = this->sa->curve->create_reverse(); + } else { + this->sa_overwrited = this->sa->curve->copy(); + } + p = anchor->dp; + this->_setStartpoint(p); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); + } + } + if (input_has_pressure) { + this->state = SP_PENCIL_CONTEXT_FREEHAND; + } // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the @@ -287,10 +311,6 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) { switch (this->state) { case SP_PENCIL_CONTEXT_ADDLINE: /* Set red endpoint */ - if (input_has_pressure) { - this->state = SP_PENCIL_CONTEXT_FREEHAND; - return true; - } if (anchor) { p = anchor->dp; } else { @@ -690,7 +710,7 @@ PencilTool::addPowerStrokePencil(SPCurve * c) this->points.clear(); using namespace Inkscape::LivePathEffect; bool live = false; - SPCurve * curve; + SPCurve * curve = new SPCurve(); if(!c) { SPCurve * previous_red = red_curve->copy(); SPCurve * previous_green = green_curve->copy(); @@ -701,24 +721,27 @@ PencilTool::addPowerStrokePencil(SPCurve * c) _interpolate(); prefs->setDouble("/tools/freehand/pencil/tolerance", tol); live = true; - if (sa) { - curve = sa->curve; - if (!green_curve->is_empty()) { + if (sa && sa->curve) { + curve = sa_overwrited->copy(); + if (!green_curve->is_unset()) { curve->append_continuous( green_curve, 0.0625); - if (!red_curve->is_empty()) { + if (!red_curve->is_unset()) { curve->append_continuous( red_curve, 0.0625); } } } else { - if (!green_curve->is_empty()) { + if (!green_curve->is_unset()) { curve = green_curve->copy(); - if (!red_curve->is_empty()) { + if (!red_curve->is_unset()) { curve->append_continuous( red_curve, 0.0625); } } else { curve = NULL; } } + if (curve->is_empty()) { + curve = NULL; + } red_curve = previous_red->copy(); green_curve = previous_green->copy(); previous_red->unref(); -- cgit v1.2.3 From 3ddb38fe604a66c89bcfde23ac61eafdc661d95d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 5 Dec 2017 00:15:35 +0100 Subject: Add sugested header by Eduard Braun to allow compiling --- src/ui/widget/scalar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index a0f1354a3..1aab9550e 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -14,7 +14,7 @@ # include #endif - +#include #include "scalar.h" #include "spinbutton.h" #include -- cgit v1.2.3 From d1395472c4b20d4e4763364b61e3d6caedb29444 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Tue, 5 Dec 2017 12:35:57 +1300 Subject: Add arc radius to toolbar --- src/sp-ellipse.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/sp-ellipse.h | 13 ++++++++-- src/widgets/arc-toolbar.cpp | 57 +++++++++++++++++++------------------------ 3 files changed, 95 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 166237c8e..c32e3012c 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -721,6 +721,65 @@ bool SPGenericEllipse::_isSlice() const return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI)); } +/** +Returns the ratio in which the vector from p0 to p1 is stretched by transform + */ +gdouble SPGenericEllipse::vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform) { + if (p0 == p1) { + return 0; + } + + return (Geom::distance(p0 * xform, p1 * xform) / Geom::distance(p0, p1)); +} + +void SPGenericEllipse::setVisibleRx(gdouble rx) { + if (rx == 0) { + this->rx.unset(); + } else { + this->rx = rx / SPGenericEllipse::vectorStretch( + Geom::Point(this->cx.computed + 1, this->cy.computed), + Geom::Point(this->cx.computed, this->cy.computed), + this->i2doc_affine()); + } + + this->updateRepr(); +} + +void SPGenericEllipse::setVisibleRy(gdouble ry) { + if (ry == 0) { + this->ry.unset(); + } else { + this->ry = ry / SPGenericEllipse::vectorStretch( + Geom::Point(this->cx.computed, this->cy.computed + 1), + Geom::Point(this->cx.computed, this->cy.computed), + this->i2doc_affine()); + } + + this->updateRepr(); +} + +gdouble SPGenericEllipse::getVisibleRx() const { + if (!this->rx._set) { + return 0; + } + + return this->rx.computed * SPGenericEllipse::vectorStretch( + Geom::Point(this->cx.computed + 1, this->cy.computed), + Geom::Point(this->cx.computed, this->cy.computed), + this->i2doc_affine()); +} + +gdouble SPGenericEllipse::getVisibleRy() const { + if (!this->ry._set) { + return 0; + } + + return this->ry.computed * SPGenericEllipse::vectorStretch( + Geom::Point(this->cx.computed, this->cy.computed + 1), + Geom::Point(this->cx.computed, this->cy.computed), + this->i2doc_affine()); +} + /* Local Variables: mode:c++ diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index a879c596d..a31b571d8 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -20,8 +20,8 @@ #include "sp-shape.h" /* Common parent class */ -#define SP_GENERICELLIPSE(obj) (dynamic_cast(obj)) -#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast((obj)) != NULL) +#define SP_GENERICELLIPSE(obj) (dynamic_cast((SPObject*)obj)) +#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast((SPObject*)obj) != NULL) enum GenericEllipseType { SP_GENERIC_ELLIPSE_UNDEFINED, // FIXME shouldn't exist @@ -83,11 +83,20 @@ public: bool set_elliptical_path_attribute(Inkscape::XML::Node *repr); void position_set(double x, double y, double rx, double ry); + double getVisibleRx() const; + void setVisibleRx(double rx); + + double getVisibleRy() const; + void setVisibleRy(double ry); + protected: /** * @brief Determines whether the shape is a part of an ellipse. */ bool _isSlice() const; + +private: + static double vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform); }; #endif diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 3faea1750..907285a60 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -122,9 +122,9 @@ static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const SPGenericEllipse *ge = SP_GENERICELLIPSE(item); if (!strcmp(value_name, "rx")) { - ge->rx = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::X]; + ge->setVisibleRx(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } else { - ge->ry = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::Y]; + ge->setVisibleRy(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } ge->normalize(); @@ -308,37 +308,25 @@ static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * / // in turn, prevent callbacks from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - gdouble radius = 0; - gdouble rx = 0; - gdouble ry = 0; - sp_repr_get_double(repr, "r", &radius); - if (radius) { - rx = ry = radius; - } else { - sp_repr_get_double(repr, "rx", &rx); - sp_repr_get_double(repr, "ry", &ry); - } - if (!rx) { - sp_repr_get_double(repr, "sodipodi:rx", &rx); - sp_repr_get_double(repr, "sodipodi:ry", &ry); - } + gpointer item = g_object_get_data( tbl, "item" ); + if (item && SP_IS_GENERICELLIPSE(item)) { + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - SPDocument* document = desktop->getDocument(); - Geom::Scale scale = document->getDocumentScale(); + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); - GtkAdjustment *adj; - adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); - gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit) * scale[Geom::X]); - gtk_adjustment_value_changed(adj); + GtkAdjustment *adj; + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); + gdouble rx = ge->getVisibleRx(); + gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); + gtk_adjustment_value_changed(adj); - adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); - gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit) * scale[Geom::Y]); - gtk_adjustment_value_changed(adj); + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); + gdouble ry = ge->getVisibleRy(); + gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); + gtk_adjustment_value_changed(adj); + } gdouble start = 0.; gdouble end = 0.; @@ -387,14 +375,18 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb { int n_selected = 0; Inkscape::XML::Node *repr = NULL; + SPItem *item = NULL; + if ( g_object_get_data( tbl, "repr" ) ) { + g_object_set_data( tbl, "item", NULL ); + } purge_repr_listener( tbl, tbl ); auto itemlist= selection->items(); for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { + if (SP_IS_GENERICELLIPSE(*i)) { n_selected++; + item = *i; repr = item->getRepr(); } } @@ -415,6 +407,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb if (repr) { g_object_set_data( tbl, "repr", repr ); + g_object_set_data( tbl, "item", item ); Inkscape::GC::anchor(repr); sp_repr_add_listener(repr, &arc_tb_repr_events, tbl); sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl); -- cgit v1.2.3 From 318ee3271bcfac6bceec28ac432e1de1b4736f0e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 5 Dec 2017 08:54:12 +0100 Subject: Working on compiling on linux problem. Another attemp to Eduard fix --- src/ui/widget/scalar.cpp | 1 - src/ui/widget/scalar.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index 1aab9550e..c34121b4f 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -14,7 +14,6 @@ # include #endif -#include #include "scalar.h" #include "spinbutton.h" #include diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h index 80de5166d..c35cf4f13 100644 --- a/src/ui/widget/scalar.h +++ b/src/ui/widget/scalar.h @@ -12,6 +12,7 @@ #ifndef INKSCAPE_UI_WIDGET_SCALAR_H #define INKSCAPE_UI_WIDGET_SCALAR_H +#include #include "labelled.h" namespace Inkscape { -- cgit v1.2.3 From cfb8746827325cca0ad2fbce0a35f20de6b2d680 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Tue, 5 Dec 2017 11:59:34 +0100 Subject: Attemp to fix compile bug --- src/ui/widget/scalar.cpp | 2 +- src/ui/widget/scalar.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index c34121b4f..937bea697 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -148,7 +148,7 @@ Glib::SignalProxy0 Scalar::signal_value_changed() return static_cast(_widget)->signal_value_changed(); } -Glib::SignalProxy Scalar::signal_button_release_event() +Glib::SignalProxy1 Scalar::signal_button_release_event() { return static_cast(_widget)->signal_button_release_event(); } diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h index c35cf4f13..b2c923953 100644 --- a/src/ui/widget/scalar.h +++ b/src/ui/widget/scalar.h @@ -12,7 +12,6 @@ #ifndef INKSCAPE_UI_WIDGET_SCALAR_H #define INKSCAPE_UI_WIDGET_SCALAR_H -#include #include "labelled.h" namespace Inkscape { @@ -156,7 +155,7 @@ public: /** * Signal raised when the spin button's pressed. */ - Glib::SignalProxy signal_button_release_event(); + Glib::SignalProxy1 signal_button_release_event(); /** * true if the value was set by setValue, not changed by the user; -- cgit v1.2.3 From f45c0191ca0797a39d98b0ddad3a79e6e1efad4c Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Tue, 5 Dec 2017 18:47:45 +0100 Subject: PDF+LaTeX export: Avoid printing empty boxes This also fixes an issue with multipage PDF output where an empty string would have been assumed to require emission of the previous page when in fact the CairoRenderer does not produce a new page in this case resulting in another facet of https://bugs.launchpad.net/ubuntu/+source/inkscape/+bug/1417470 Invisible characters might still cause this issue but it seems to be a very unlikely scenario and there's no way to know this without actually rendering the glyphs (which seems to be overkill here) --- src/extension/internal/latex-text-renderer.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index d1cf7e484..3e90881ac 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -260,6 +260,11 @@ void LaTeXTextRenderer::sp_use_render(SPUse *use) void LaTeXTextRenderer::sp_text_render(SPText *textobj) { + // Nothing to do here... (so don't emit an empty box) + // Also avoids falling out of sync with the CairoRenderer (which won't render anything in this case either) + if (textobj->layout.getActualLength() == 0) + return; + // Only PDFLaTeX supports importing a single page of a graphics file, // so only PDF backend gets interleaved text/graphics if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP) -- cgit v1.2.3 From 9a6a3d91188f393bc1ea5667d54fb5b4c611b739 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Tue, 5 Dec 2017 21:27:56 +0100 Subject: PDF+LaTeX export: Fix multiline text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap text in "\shortstack" to allow for newlines using "\\". The output extension already produced those but they are ignored in a "\smash" environment. Patch by Michael Jäntsch Fixed bug: - https://bugs.launchpad.net/inkscape/+bug/771959 --- src/extension/internal/latex-text-renderer.cpp | 43 ++++++++++++++++++-------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 3e90881ac..e5b87b389 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -276,16 +276,20 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj) // Align vertically on the baseline of the font (retreived from the anchor point) // Align horizontally on anchorpoint gchar const *alignment = NULL; + gchar const *alignstack = NULL; switch (style->text_anchor.computed) { case SP_CSS_TEXT_ANCHOR_START: - alignment = "[lb]"; + alignment = "[lt]"; + alignstack = "[l]"; break; case SP_CSS_TEXT_ANCHOR_END: - alignment = "[rb]"; + alignment = "[rt]"; + alignstack = "[r]"; break; case SP_CSS_TEXT_ANCHOR_MIDDLE: default: - alignment = "[b]"; + alignment = "[t]"; + alignstack = "[c]"; break; } Geom::Point anchor = textobj->attributes.firstXY() * transform(); @@ -332,12 +336,14 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj) os << "\\rotatebox{" << degrees << "}{"; } os << "\\makebox(0,0)" << alignment << "{"; - os << "\\smash{"; // smash the text, to be able to put the makebox coordinates at the baseline + os << "\\shortstack" << alignstack << "{"; + os << "\\smash{"; + bool smash_closed = false; // Walk through all spans in the text object. // Write span strings to LaTeX, associated with font weight and style. Inkscape::Text::Layout const &layout = *(te_get_layout (textobj)); - for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); + for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); li != le; li.nextStartOfSpan()) { SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li)); @@ -372,22 +378,33 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj) if (!spanstr) { continue; } + // replace carriage return with double slash - gchar ** splitstr = g_strsplit(spanstr, "\n", -1); - gchar *spanstr_new = g_strjoinv("\\\\ ", splitstr); - os << spanstr_new; + gchar ** splitstr = g_strsplit(spanstr, "\n", 2); + os << splitstr[0]; + + // smash the first line of the text only, to be able to align the rest of the makebox top + // assuming that spans always end at the end of a line + if (g_strv_length(splitstr) > 1) + { + if (!smash_closed) + { + os << "}"; // smash end + smash_closed = true; + } + os << "\\\\"; + } + g_strfreev(splitstr); - g_free(spanstr_new); if (is_oblique) { os << "}"; } // oblique end if (is_italic) { os << "}"; } // italic end if (is_bold) { os << "}"; } // bold end } - os << "}"; // smash end - if (has_rotation) { - os << "}"; // rotatebox end - } + if (!smash_closed) { os << "}"; } // smash end + os << "}"; // shortstack end + if (has_rotation) { os << "}"; } // rotatebox end os << "}"; //makebox end os << "}%\n"; // put end -- cgit v1.2.3 From 82b42536b29ccb2f93f4bd156c7fa20367920348 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Tue, 5 Dec 2017 21:51:01 +0100 Subject: PDF+LaTeX export: do not apply style to newlines As the parser seems to wrap newlines into their own tspan which has the same style as the preceding tspan the latex-text renderer produced output like "\texbf{\\}" which broke compilation in LaTeX --- src/extension/internal/latex-text-renderer.cpp | 53 ++++++++++++++------------ 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index e5b87b389..7a1cacbf2 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -346,31 +346,6 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj) for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); li != le; li.nextStartOfSpan()) { - SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li)); - bool is_bold = false, is_italic = false, is_oblique = false; - - if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD || - spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER) - { - is_bold = true; - os << "\\textbf{"; - } - if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC) - { - is_italic = true; - os << "\\textit{"; - } - if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE) - { - is_oblique = true; - os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so... - } - Inkscape::Text::Layout::iterator ln = li; ln.nextStartOfSpan(); Glib::ustring uspanstr = sp_te_get_string_multiline (textobj, li, ln); @@ -379,6 +354,34 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj) continue; } + bool is_bold = false, is_italic = false, is_oblique = false; + + // newline character only -> don't attempt to add style (will break compilation in LaTeX) + if (g_strcmp0(spanstr, "\n")) { + SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li)); + if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER) + { + is_bold = true; + os << "\\textbf{"; + } + if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC) + { + is_italic = true; + os << "\\textit{"; + } + if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE) + { + is_oblique = true; + os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so... + } + } + // replace carriage return with double slash gchar ** splitstr = g_strsplit(spanstr, "\n", 2); os << splitstr[0]; -- cgit v1.2.3 From 1c8ce1ee6081b4d2f5a111d4c960cedca77634dc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 5 Dec 2017 22:33:59 +0100 Subject: Fix bug:1695649 - Knot LPE has no effect after Simplify or B-Spline --- src/live_effects/lpe-knot.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index b21181ffc..b3918b6ab 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -510,12 +510,7 @@ collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::v } } else if (SP_IS_SHAPE(lpeitem)) { - SPCurve * c = NULL; - if (SP_IS_PATH(lpeitem)) { - c = SP_PATH(lpeitem)->get_curve_for_edit(); - } else { - c = SP_SHAPE(lpeitem)->getCurve(); - } + SPCurve * c = SP_SHAPE(lpeitem)->getCurve(); if (c) { Geom::PathVector subpaths = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); for (unsigned i=0; istyle->stroke_width.computed); } } + c->unref(); } } -- cgit v1.2.3 From b07c5c5e802ee4d9cc947ca24d7b15fa5c71a7e8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 5 Dec 2017 22:11:12 +0100 Subject: Fix bug#1643179. Guides lock lost on load. Patch proposed in #5 --- src/file.cpp | 5 +++++ src/sp-guide.cpp | 6 +++--- src/sp-namedview.cpp | 13 ++++++------- src/sp-namedview.h | 2 +- src/ui/dialog/guides.cpp | 2 +- src/widgets/desktop-widget.cpp | 6 +++--- 6 files changed, 19 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 320016a41..e5caaaca0 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -272,6 +272,11 @@ bool sp_file_open(const Glib::ustring &uri, } if ( INKSCAPE.use_gui() ) { + + SPNamedView *nv = desktop->namedview; + if (nv->lockguides) { + desktop->toggleGuidesLock(); + } // Perform a fixup pass for hrefs. if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) { Glib::ustring msg = _("Broken links have been changed to point to existing files."); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 8b4bf121d..fe6d0b64a 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -112,9 +112,8 @@ void SPGuide::set(unsigned int key, const gchar *value) { this->set_label(this->label, false); break; case SP_ATTR_INKSCAPE_LOCKED: - this->locked = helperfns_read_bool(value, false); if (value) { - this->set_locked(this->locked, false); + this->set_locked(helperfns_read_bool(value, false), false); } break; case SP_ATTR_ORIENTATION: @@ -275,7 +274,8 @@ void SPGuide::showSPGuide(SPCanvasGroup *group, GCallback handler) { SPCanvasItem *item = sp_guideline_new(group, label, point_on_line, normal_to_line); sp_guideline_set_color(SP_GUIDELINE(item), color); - + sp_guideline_set_locked(SP_GUIDELINE(item), locked); + g_signal_connect(G_OBJECT(item), "event", G_CALLBACK(handler), this); views.push_back(SP_GUIDELINE(item)); diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 2992b85d3..ef22eca2d 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -593,10 +593,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) { break; } case SP_ATTR_INKSCAPE_LOCKGUIDES: - this->lockguides = value ? sp_str_to_bool(value) : FALSE; - sp_namedview_lock_guides(this); - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; + this->lockguides = value ? sp_str_to_bool(value) : FALSE; + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; default: SPObjectGroup::set(key, value); break; @@ -671,7 +670,6 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r } sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides); - sp_namedview_lock_single_guide(SP_GUIDE(g), this->lockguides); } } } @@ -721,7 +719,6 @@ void SPNamedView::show(SPDesktop *desktop) (*it)->sensitize(desktop->getCanvas(), TRUE); } sp_namedview_show_single_guide((*it), showguides); - sp_namedview_lock_single_guide((*it), lockguides); } views.push_back(desktop); @@ -1013,9 +1010,10 @@ void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr) doc->setModifiedSinceSave(); } -void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr) +void sp_namedview_guides_toggle_lock(SPDocument *doc, SPNamedView * namedview) { unsigned int v; + Inkscape::XML::Node *repr = namedview->getRepr(); unsigned int set = sp_repr_get_boolean(repr, "inkscape:lockguides", &v); if (!set) { // hide guides if not specified, for backwards compatibility v = true; @@ -1026,6 +1024,7 @@ void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr) bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); sp_repr_set_boolean(repr, "inkscape:lockguides", v); + sp_namedview_lock_guides(namedview); DocumentUndo::setUndoSensitive(doc, saved); doc->setModifiedSinceSave(); } diff --git a/src/sp-namedview.h b/src/sp-namedview.h index d8ac1a77e..20d762bc4 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -123,7 +123,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop); void sp_namedview_update_layers_from_document (SPDesktop *desktop); void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr); -void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr); +void sp_namedview_guides_toggle_lock(SPDocument *doc, SPNamedView *namedview); void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document); Inkscape::CanvasGrid * sp_namedview_get_first_enabled_grid(SPNamedView *namedview); diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index f0de5ad0d..5dc64bb24 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -96,7 +96,7 @@ void GuidelinePropertiesDialog::_onOK() normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } //To allow reposition from dialog - _guide->set_locked(false, true); + _guide->set_locked(false, false); _guide->set_normal(normal, true); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index f9c8e4ac6..0f5d8b973 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -388,6 +388,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->guides_lock, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1); + g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw); gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl_wrapper, TRUE, TRUE, 1 ); @@ -993,7 +994,7 @@ void sp_update_guides_lock( GtkWidget */*button*/, gpointer data ) if ( down != nv->lockguides ) { nv->lockguides = down; - sp_namedview_guides_toggle_lock(doc, repr); + sp_namedview_guides_toggle_lock(doc, nv); if (down) { dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Locked all guides")); } else { @@ -1658,7 +1659,6 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) /* Once desktop is set, we can update rulers */ sp_desktop_widget_update_rulers (dtw); - sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), namedview->lockguides ); sp_view_widget_set_view (SP_VIEW_WIDGET (dtw), dtw->desktop); @@ -1670,7 +1670,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) dtw->menubar = sp_ui_main_menubar (dtw->desktop); gtk_widget_set_name(dtw->menubar, "MenuBar"); gtk_widget_show_all (dtw->menubar); - SPNamedView *nv = dtw->desktop->namedview; + gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0); dtw->layoutWidgets(); -- cgit v1.2.3 From da4e818f765c88916763e17d2180f9df22bf5038 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 6 Dec 2017 00:15:06 +0100 Subject: Fix bug:#1713491: opening the 'Path Effects' dialog causes document to be marked as 'changed', even though nothing was changed --- src/ui/widget/registered-widget.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 78de055de..765fa77b6 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -108,12 +108,14 @@ protected: bool saved = DocumentUndo::getUndoSensitive(local_doc); DocumentUndo::setUndoSensitive(local_doc, false); + const char * svgstr_old = local_repr->attribute(_key.c_str()); if (!write_undo) { local_repr->setAttribute(_key.c_str(), svgstr); } DocumentUndo::setUndoSensitive(local_doc, saved); - - local_doc->setModifiedSinceSave(); + if (svgstr_old && svgstr && strcmp(svgstr_old,svgstr)) { + local_doc->setModifiedSinceSave(); + } if (write_undo) { local_repr->setAttribute(_key.c_str(), svgstr); -- cgit v1.2.3 From d31522600e346792119f3a70867ef441374b2f47 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Thu, 7 Dec 2017 00:33:27 +0100 Subject: Fix bug 1735316 - Pattern Along Path: Option to hide the new handler https://bugs.launchpad.net/inkscape/+bug/1735316 --- src/live_effects/lpe-bendpath.cpp | 47 ++++++++++++++++++++----------- src/live_effects/lpe-bendpath.h | 3 ++ src/live_effects/lpe-patternalongpath.cpp | 44 +++++++++++++++++++---------- src/live_effects/lpe-patternalongpath.h | 3 ++ 4 files changed, 66 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index ff5f738eb..dcbf5efd0 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -9,6 +9,7 @@ #include "sp-item-group.h" #include "knot-holder-entity.h" #include "knotholder.h" +#include "display/curve.h" // TODO due to internal breakage in glibmm headers, this must be last: #include @@ -39,7 +40,6 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { -Geom::PathVector bp_helper_path; namespace BeP { class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity { public: @@ -55,16 +55,19 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : original_height(0.0), prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), - vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) + vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false), + hide_knot(_("Hide width knot"), _("Hide width knot"),"hide_knot", &wr, this, false) { registerParameter( &bend_path ); registerParameter( &prop_scale); registerParameter( &scale_y_rel); registerParameter( &vertical_pattern); + registerParameter(&hide_knot); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); - + + knot_entity = NULL; _provides_knotholder_entities = true; apply_to_clippath_and_mask = true; concatenate_before_pwd2 = true; @@ -81,6 +84,15 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) // get the item bounding box original_bbox(lpeitem); original_height = boundingbox_Y.max() - boundingbox_Y.min(); + if (knot_entity) { + if (hide_knot) { + helper_path.clear(); + knot_entity->knot->hide(); + } else { + knot_entity->knot->show(); + } + knot_entity->update_knot(); + } } Geom::Piecewise > @@ -162,15 +174,19 @@ LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set) void LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { - hp_vec.push_back(bp_helper_path); + hp_vec.push_back(helper_path); } void LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) { - KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this); - e->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); - knotholder->add(e); + knot_entity = new BeP::KnotHolderEntityWidthBendPath(this); + knot_entity->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(knot_entity); + if (hide_knot) { + knot_entity->knot->hide(); + knot_entity->update_knot(); + } } namespace BeP { @@ -208,7 +224,6 @@ Geom::Point KnotHolderEntityWidthBendPath::knot_get() const { LPEBendPath *lpe = dynamic_cast (_effect); - Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); @@ -216,17 +231,17 @@ KnotHolderEntityWidthBendPath::knot_get() const Geom::CubicBezier const *cubic = dynamic_cast(&*first_curve); Geom::Ray ray(ptA, B); if (cubic) { - ray.setPoints(ptA,(*cubic)[1]); + ray.setPoints(ptA, (*cubic)[1]); } ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; - - bp_helper_path.clear(); - Geom::Path hp(result_point); - hp.appendNew(ptA); - bp_helper_path.push_back(hp); - hp.clear(); - + lpe->helper_path.clear(); + if (!lpe->hide_knot) { + Geom::Path hp(result_point); + hp.appendNew(ptA); + lpe->helper_path.push_back(hp); + hp.clear(); + } return result_point; } } // namespace BeP diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index f232687ce..74892201d 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -58,6 +58,9 @@ protected: private: BoolParam scale_y_rel; BoolParam vertical_pattern; + BoolParam hide_knot; + KnotHolderEntity *knot_entity; + Geom::PathVector helper_path; Geom::Piecewise > uskeleton; Geom::Piecewise > n; diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 4aa172161..5be88a2b7 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -42,7 +42,6 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { -Geom::PathVector pap_helper_path; namespace WPAP { class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity { @@ -82,6 +81,7 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : "prop_units", &wr, this, false), vertical_pattern(_("Pattern is _vertical"), _("Rotate pattern 90 deg before applying"), "vertical_pattern", &wr, this, false), + hide_knot(_("Hide width knot"), _("Hide width knot"),"hide_knot", &wr, this, false), fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."), "fuse_tolerance", &wr, this, 0) { @@ -94,10 +94,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter(&tang_offset); registerParameter(&prop_units); registerParameter(&vertical_pattern); + registerParameter(&hide_knot); registerParameter(&fuse_tolerance); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); - + knot_entity = NULL; _provides_knotholder_entities = true; } @@ -115,6 +116,15 @@ LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) if (bbox) { original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); } + if (knot_entity) { + if (hide_knot) { + helper_path.clear(); + knot_entity->knot->hide(); + } else { + knot_entity->knot->show(); + } + knot_entity->update_knot(); + } } Geom::Piecewise > @@ -272,16 +282,20 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set) void LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { - hp_vec.push_back(pap_helper_path); + hp_vec.push_back(helper_path); } void LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) { - KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); - e->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); - knotholder->add(e); + knot_entity = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); + knot_entity->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(knot_entity); + if (hide_knot) { + knot_entity->knot->hide(); + knot_entity->update_knot(); + } } namespace WPAP { @@ -290,7 +304,7 @@ void KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) { LPEPatternAlongPath *lpe = dynamic_cast (_effect); - + Geom::Point const s = snap_knot_position(p, state); SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { @@ -325,7 +339,6 @@ Geom::Point KnotHolderEntityWidthPatternAlongPath::knot_get() const { LPEPatternAlongPath *lpe = dynamic_cast (_effect); - SPShape const *sp_shape = dynamic_cast(SP_LPE_ITEM(item)); if (sp_shape) { SPCurve *curve_before = sp_shape->getCurveBeforeLPE(); @@ -341,13 +354,14 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const } ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; - - pap_helper_path.clear(); - Geom::Path hp(result_point); - hp.appendNew(ptA); - pap_helper_path.push_back(hp); - hp.clear(); - curve_before->unref(); + lpe->helper_path.clear(); + if (!lpe->hide_knot) { + Geom::Path hp(result_point); + hp.appendNew(ptA); + lpe->helper_path.push_back(hp); + hp.clear(); + } + curve_before->unref(); return result_point; } } diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index c34a9a15d..ded875a8b 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -60,7 +60,10 @@ private: ScalarParam tang_offset; BoolParam prop_units; BoolParam vertical_pattern; + BoolParam hide_knot; ScalarParam fuse_tolerance; + KnotHolderEntity *knot_entity; + Geom::PathVector helper_path; void on_pattern_pasted(); LPEPatternAlongPath(const LPEPatternAlongPath&); -- cgit v1.2.3 From c1dc7dd75c5f43b109d06444375dad58ff49872b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Thu, 7 Dec 2017 01:16:38 +0100 Subject: Fix bug 1733422 - Bezier and pencil tool don't work form: from clipboard https://bugs.launchpad.net/inkscape/+bug/1733422 Also allow using all shapes in "from clipboard" pen/cil shapes drop down --- src/ui/tools/freehand-base.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 49b8436de..79c9ce7f9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -36,6 +36,7 @@ #include "ui/tools/lpe-tool.h" #include "selection-chemistry.h" #include "sp-item-group.h" +#include "sp-rect.h" #include "live_effects/lpe-powerstroke.h" #include "style.h" #include "ui/control-manager.h" @@ -466,6 +467,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,true)){ SPItem * pasted_clipboard = dc->selection->singleItem(); + dc->selection->toCurves(); + pasted_clipboard = dc->selection->singleItem(); if(pasted_clipboard){ Inkscape::XML::Node *pasted_clipboard_root = pasted_clipboard->getRepr(); Inkscape::XML::Node *path = sp_repr_lookup_name(pasted_clipboard_root, "svg:path", -1); // unlimited search depth @@ -494,6 +497,19 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { gchar const *svgd = item->getRepr()->attribute("d"); if(bend_item && (SP_IS_SHAPE(bend_item) || SP_IS_GROUP(bend_item))){ + // If item is a SPRect, convert it to path first: + if ( dynamic_cast(bend_item) ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection *sel = desktop->getSelection(); + if ( sel && !sel->isEmpty() ) { + sel->clear(); + sel->add(bend_item); + sel->toCurves(); + bend_item = sel->singleItem(); + } + } + } bend_item->moveTo(item,false); bend_item->transform.setTranslation(Geom::Point()); spdc_apply_bend_shape(svgd, dc, bend_item); -- cgit v1.2.3