summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/live_effects/lpe-powerstroke.cpp68
-rw-r--r--src/live_effects/lpe-powerstroke.h2
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp11
-rw-r--r--src/ui/dialog/inkscape-preferences.h1
-rw-r--r--src/ui/toolbar/pencil-toolbar.cpp107
-rw-r--r--src/ui/toolbar/pencil-toolbar.h6
-rw-r--r--src/ui/tools/freehand-base.cpp132
-rw-r--r--src/ui/tools/pencil-tool.cpp385
-rw-r--r--src/ui/tools/pencil-tool.h12
-rw-r--r--src/widgets/toolbox.cpp8
10 files changed, 383 insertions, 349 deletions
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index 55ef2aaa7..15fda42fc 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -207,6 +207,39 @@ LPEPowerStroke::doBeforeEffect(SPLPEItem const *lpeItem)
{
offset_points.set_scale_width(scale_width);
}
+
+void
+LPEPowerStroke::applyStyle(SPLPEItem *lpeitem)
+{
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ if (lpeitem->style) {
+ if (lpeitem->style->stroke.isPaintserver()) {
+ SPPaintServer * server = lpeitem->style->getStrokePaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "fill", str.c_str());
+ }
+ } else if (lpeitem->style->stroke.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
+ sp_repr_css_set_property (css, "fill", c);
+ } else {
+ sp_repr_css_set_property (css, "fill", "none");
+ }
+ } else {
+ sp_repr_css_unset_property (css, "fill");
+ }
+
+ sp_repr_css_set_property(css, "fill-rule", "nonzero");
+ sp_repr_css_set_property(css, "stroke", "none");
+
+ sp_desktop_apply_css_recursive(lpeitem, css, true);
+ sp_repr_css_attr_unref (css);
+}
+
void
LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem)
{
@@ -216,42 +249,11 @@ LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem)
Geom::PathVector const &pathv = pathv_to_linear_and_cubic_beziers(SP_SHAPE(lpeitem)->_curve->get_pathvector());
double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed / 2 : 1.;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- Glib::ustring pref_path_ps = "/live_effects/powerstroke/powerpencilstyle";
Glib::ustring pref_path_pp = "/live_effects/powerstroke/powerpencil";
bool powerpencil = prefs->getBool(pref_path_pp, false);
- bool powerpencilstyle = prefs->getBool(pref_path_ps, false);
- if (!powerpencilstyle) {
- SPCSSAttr *css = sp_repr_css_attr_new ();
- if (lpeitem->style) {
- if (lpeitem->style->stroke.isPaintserver()) {
- SPPaintServer * server = lpeitem->style->getStrokePaintServer();
- if (server) {
- Glib::ustring str;
- str += "url(#";
- str += server->getId();
- str += ")";
- sp_repr_css_set_property (css, "fill", str.c_str());
- }
- } else if (lpeitem->style->stroke.isColor()) {
- gchar c[64];
- sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value)));
- sp_repr_css_set_property (css, "fill", c);
- } else {
- sp_repr_css_set_property (css, "fill", "none");
- }
- } else {
- sp_repr_css_unset_property (css, "fill");
- }
-
- sp_repr_css_set_property(css, "fill-rule", "nonzero");
- sp_repr_css_set_property(css, "stroke", "none");
-
- sp_desktop_apply_css_recursive(item, css, true);
- sp_repr_css_attr_unref (css);
-
- item->updateRepr();
- }
if (!powerpencil) {
+ applyStyle(item);
+ item->updateRepr();
if (pathv.empty()) {
points.emplace_back(0.2,width );
points.emplace_back(0.5,width );
diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h
index 96ee2a192..9ac4a65a5 100644
--- a/src/live_effects/lpe-powerstroke.h
+++ b/src/live_effects/lpe-powerstroke.h
@@ -32,7 +32,7 @@ public:
void doBeforeEffect(SPLPEItem const *lpeItem) override;
void doOnApply(SPLPEItem const* lpeitem) override;
void doOnRemove(SPLPEItem const* lpeitem) override;
-
+ void applyStyle(SPLPEItem *lpeitem);
// methods called by path-manipulator upon edits
void adjustForNewPath(Geom::PathVector const & path_in);
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 1da02307b..3119b1b3b 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -227,14 +227,6 @@ void InkscapePreferences::AddBaseSimplifySpinbutton(DialogPage &p, Glib::ustring
false );
}
-void InkscapePreferences::AddPencilPowerStrokePressureStep(DialogPage &p, Glib::ustring const &prefs_path, gint def_value)
-{
- PrefSpinButton* sb = Gtk::manage( new PrefSpinButton);
- sb->init ( prefs_path + "/ps-step-pressure", 1, 100, 1, 10, def_value, true, false);
- p.add_line( false, _("Pressure change for new knot:"), *sb, _("%"),
- _("Percentage increase / decrease of stylus pressure that is required to create a new PowerStroke knot."),
- false );
-}
static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatch *swatch)
{
@@ -454,9 +446,6 @@ void InkscapePreferences::initPageTools()
this->AddNewObjectsStyle(_page_pencil, "/tools/freehand/pencil");
this->AddDotSizeSpinbutton(_page_pencil, "/tools/freehand/pencil", 3.0);
this->AddBaseSimplifySpinbutton(_page_pencil, "/tools/freehand/pencil", 25.0);
- _page_pencil.add_group_header( _("Pressure sensitivity settings"));
- this->AddPencilPowerStrokePressureStep(_page_pencil, "/tools/freehand/pencil", 5);
-
_page_pencil.add_group_header( _("Sketch mode"));
_page_pencil.add_line( true, "", _pencil_average_all_sketches, "",
_("If on, the sketch result will be the normal average of all sketches made, instead of averaging the old result with the new sketch"));
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 0902d4d11..e1dbd51c2 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -556,7 +556,6 @@ protected:
static void AddFirstAndLastCheckbox(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, bool def_value);
static void AddDotSizeSpinbutton(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, double def_value);
static void AddBaseSimplifySpinbutton(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, double def_value);
- static void AddPencilPowerStrokePressureStep(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, gint def_value);
static void AddNewObjectsStyle(UI::Widget::DialogPage& p, Glib::ustring const &prefs_path, const gchar* banner = nullptr);
void on_pagelist_selection_changed();
diff --git a/src/ui/toolbar/pencil-toolbar.cpp b/src/ui/toolbar/pencil-toolbar.cpp
index 3ef896ccf..753d51cd5 100644
--- a/src/ui/toolbar/pencil-toolbar.cpp
+++ b/src/ui/toolbar/pencil-toolbar.cpp
@@ -105,42 +105,54 @@ PencilToolbar::PencilToolbar(SPDesktop *desktop,
add(* Gtk::manage(new Gtk::SeparatorToolItem()));
if (pencil_mode) {
+ /* Use pressure */
+ {
+ _pressure_item = add_toggle_button(_("Use pressure input"),
+ _("Use pressure input"));
+ _pressure_item->set_icon_name(INKSCAPE_ICON("draw-use-pressure"));
+ bool oldPressureMode = prefs->getIntLimited("/tools/freehand/pencil/freehand-mode", 0, 0, 3) == 3;
+ bool pressure = prefs->getBool(freehand_tool_name() + "/pressure", oldPressureMode);
+ if (oldPressureMode && pressure) {
+ prefs->setBool(freehand_tool_name() + "/pressure", true);
+ }
+ _pressure_item->set_active(pressure);
+ _pressure_item->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::use_pencil_pressure));
+ // always show
+ add(*_pressure_item);
+ }
/* min pressure */
{
- auto minpressure_val = prefs->getDouble("/tools/freehand/pencil/minpressure", 0);
+ auto minpressure_val = prefs->getDouble("/tools/freehand/pencil/minpressure", 10);
_minpressure_adj = Gtk::Adjustment::create(minpressure_val, 0, 100, 1, 0);
_minpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-minpressure", _("Min:"), _minpressure_adj, 0, 0));
_minpressure->set_tooltip_text(_("Min percent of pressure"));
_minpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_minpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::minpressure_value_changed));
+ add(*_minpressure);
}
/* max pressure */
{
- auto maxpressure_val = prefs->getDouble("/tools/freehand/pencil/maxpressure", 100);
+ auto maxpressure_val = prefs->getDouble("/tools/freehand/pencil/maxpressure", 40);
_maxpressure_adj = Gtk::Adjustment::create(maxpressure_val, 0, 100, 1, 0);
_maxpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-maxpressure", _("Max:"), _maxpressure_adj, 0, 0));
_maxpressure->set_tooltip_text(_("Max percent of pressure"));
_maxpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_maxpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::maxpressure_value_changed));
+ add(*_maxpressure);
}
-
- /* Use pressure */
+ /* pressure steps */
{
- _pressure_item = add_toggle_button(_("Use pressure input"),
- _("Use pressure input"));
- _pressure_item->set_icon_name(INKSCAPE_ICON("draw-use-pressure"));
- bool oldPressureMode = prefs->getIntLimited("/tools/freehand/pencil/freehand-mode", 0, 0, 3) == 3;
- bool pressure = prefs->getBool(freehand_tool_name() + "/pressure", oldPressureMode);
- if (oldPressureMode && pressure) {
- prefs->setBool(freehand_tool_name() + "/pressure", true);
- }
- _pressure_item->set_active(pressure);
- _pressure_item->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::use_pencil_pressure));
-
- add(*_minpressure);
- add(*_maxpressure);
+ auto pressurestep_val = prefs->getDouble("/tools/freehand/pencil/pressurestep", 5);
+ _pressurestep_adj = Gtk::Adjustment::create(pressurestep_val, 0., 100, 1.0, 0.0);
+ _pressurestep = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-pressurestep", _("Knot gap:"), _pressurestep_adj, 0, 0));
+ _pressurestep->set_tooltip_text(_("Pressure steps for new knot"));
+ _pressurestep->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
+ _pressurestep_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::pressurestep_value_changed));
+ add(*_pressurestep);
}
+
+
add(* Gtk::manage(new Gtk::SeparatorToolItem()));
/* Tolerance */
@@ -154,7 +166,7 @@ PencilToolbar::PencilToolbar(SPDesktop *desktop,
tolerance_item->set_custom_numeric_menu_data(values, labels);
tolerance_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_tolerance_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::tolerance_value_changed));
- //ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
+ // ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
add(*tolerance_item);
}
@@ -165,7 +177,6 @@ PencilToolbar::PencilToolbar(SPDesktop *desktop,
_simplify->set_icon_name(INKSCAPE_ICON("interactive_simplify"));
_simplify->set_active(prefs->getInt("/tools/freehand/pencil/simplify", 0));
_simplify->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::simplify_lpe));
-
}
/* LPE simplify flatten */
@@ -192,27 +203,8 @@ PencilToolbar::PencilToolbar(SPDesktop *desktop,
if (freehandMode != 1 && freehandMode != 2) {
_flatten_spiro_bspline->set_visible(false);
}
-
if (pencil_mode) {
- /* Pressure */
- if (!prefs->getBool(freehand_tool_name() + "/pressure", false)) {
- _minpressure->set_visible(false);
- _maxpressure->set_visible(false);
- }
-
- /* LPE simplify based tolerance */
- if (freehandMode == 2) {
- _simplify->set_visible(false);
- }
-
- /* LPE simplify flatten */
- if (freehandMode == 2 || !prefs->getInt("/tools/freehand/pencil/simplify", 0)) {
- _flatten_simplify->set_visible(false);
- }
- if (!prefs->getBool(freehand_tool_name() + "/pressure", false)) {
- /* Advanced shape options */
- _shape_item->set_visible(!prefs->getBool("/tools/freehand/pencil/pressure", false));
- }
+ use_pencil_pressure();
}
}
@@ -273,10 +265,8 @@ PencilToolbar::add_freehand_mode_toggle(bool tool_is_pencil)
auto label = Gtk::manage(new UI::Widget::LabelToolItem(_("Mode:")));
label->set_tooltip_text(_("Mode of new lines drawn by this tool"));
add(*label);
-
/* Freehand mode toggle buttons */
Gtk::RadioToolButton::Group mode_group;
-
auto bezier_mode_btn = Gtk::manage(new Gtk::RadioToolButton(mode_group, _("Bezier")));
bezier_mode_btn->set_tooltip_text(_("Create regular Bezier path"));
bezier_mode_btn->set_icon_name(INKSCAPE_ICON("path-mode-bezier"));
@@ -355,6 +345,18 @@ PencilToolbar::maxpressure_value_changed()
}
void
+PencilToolbar::pressurestep_value_changed()
+{
+ // quit if run by the attr_changed listener
+ if (_freeze) {
+ return;
+ }
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble( "/tools/freehand/pencil/pressurestep", _pressurestep_adj->get_value());
+}
+
+void
PencilToolbar::use_pencil_pressure() {
bool pressure = _pressure_item->get_active();
auto prefs = Inkscape::Preferences::get();
@@ -362,11 +364,29 @@ PencilToolbar::use_pencil_pressure() {
if (pressure) {
_minpressure->set_visible(true);
_maxpressure->set_visible(true);
- _shape_item->set_visible (false);
+ _pressurestep->set_visible(true);
+ _shape_item->set_visible(false);
+ _simplify->set_visible(false);
+ _flatten_simplify->set_visible(false);
+ _flatten_spiro_bspline->set_visible(false);
+ for (auto button : _mode_buttons) {
+ button->set_sensitive(false);
+ }
} else {
+ guint freehandMode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
+
_minpressure->set_visible(false);
_maxpressure->set_visible(false);
- _shape_item->set_visible (true);
+ _pressurestep->set_visible(false);
+ _shape_item->set_visible(true);
+ _simplify->set_visible(true);
+ _flatten_simplify->set_visible(true);
+ if (freehandMode == 1 || freehandMode == 2) {
+ _flatten_spiro_bspline->set_visible(true);
+ }
+ for (auto button : _mode_buttons) {
+ button->set_sensitive(true);
+ }
}
}
@@ -375,7 +395,6 @@ PencilToolbar::add_advanced_shape_options(bool tool_is_pencil)
{
/*advanced shape options */
_shape_item = Gtk::manage(new Gtk::ToolItem());
-
auto hbox = Gtk::manage(new Gtk::Box());
_shape_item->add(*hbox);
diff --git a/src/ui/toolbar/pencil-toolbar.h b/src/ui/toolbar/pencil-toolbar.h
index 35129212f..81db52595 100644
--- a/src/ui/toolbar/pencil-toolbar.h
+++ b/src/ui/toolbar/pencil-toolbar.h
@@ -53,7 +53,8 @@ private:
Gtk::ToggleToolButton *_pressure_item;
UI::Widget::SpinButtonToolItem *_minpressure;
UI::Widget::SpinButtonToolItem *_maxpressure;
-
+ UI::Widget::SpinButtonToolItem *_pressurestep;
+
XML::Node *_repr;
Gtk::ToolButton *_flatten_spiro_bspline;
Gtk::ToolButton *_flatten_simplify;
@@ -61,12 +62,14 @@ private:
Gtk::ToolItem *_shape_item;
Gtk::ComboBoxText *_shape_combo;
+
Gtk::ToggleToolButton *_simplify;
bool _freeze;
Glib::RefPtr<Gtk::Adjustment> _minpressure_adj;
Glib::RefPtr<Gtk::Adjustment> _maxpressure_adj;
+ Glib::RefPtr<Gtk::Adjustment> _pressurestep_adj;
Glib::RefPtr<Gtk::Adjustment> _tolerance_adj;
void add_freehand_mode_toggle(bool tool_is_pencil);
@@ -74,6 +77,7 @@ private:
Glib::ustring const freehand_tool_name();
void minpressure_value_changed();
void maxpressure_value_changed();
+ void pressurestep_value_changed();
void use_pencil_pressure();
void tolerance_value_changed();
void add_advanced_shape_options(bool tool_is_pencil);
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index 0c82b4dec..f669788dd 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -32,6 +32,7 @@
#include "live_effects/lpe-powerstroke.h"
#include "svg/svg.h"
+#include "svg/svg-color.h"
#include "object/sp-item-group.h"
#include "object/sp-path.h"
@@ -231,70 +232,93 @@ static void spdc_paste_curve_as_freehand_shape(Geom::PathVector const &newpath,
lpe->getRepr()->setAttribute("prop_scale", os.str().c_str());
}
-static void spdc_apply_powerstroke_shape(std::vector<Geom::Point> points, FreehandBase *dc, SPItem *item)
+void
+spdc_apply_style(SPObject *obj)
+{
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ if (obj->style) {
+ if (obj->style->stroke.isPaintserver()) {
+ SPPaintServer * server = obj->style->getStrokePaintServer();
+ if (server) {
+ Glib::ustring str;
+ str += "url(#";
+ str += server->getId();
+ str += ")";
+ sp_repr_css_set_property (css, "fill", str.c_str());
+ }
+ } else if (obj->style->stroke.isColor()) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), obj->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(obj->style->stroke_opacity.value)));
+ sp_repr_css_set_property (css, "fill", c);
+ } else {
+ sp_repr_css_set_property (css, "fill", "none");
+ }
+ } else {
+ sp_repr_css_unset_property (css, "fill");
+ }
+
+ sp_repr_css_set_property(css, "fill-rule", "nonzero");
+ sp_repr_css_set_property(css, "stroke", "none");
+
+ sp_desktop_apply_css_recursive(obj, css, true);
+ sp_repr_css_attr_unref (css);
+}
+static void spdc_apply_powerstroke_shape(std::vector<Geom::Point> points, FreehandBase *dc, SPItem *item, gint maxrecursion = 0)
{
using namespace Inkscape::LivePathEffect;
if (SP_IS_PENCIL_CONTEXT(dc)) {
PencilTool *pt = SP_PENCIL_CONTEXT(dc);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ SPDocument *document = SP_ACTIVE_DOCUMENT;
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (!document || !desktop) {
+ return;
+ }
if (dc->tablet_enabled) {
- Geom::Affine transform_coordinate = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2dt_affine().inverse();
- item->transform = transform_coordinate;
- SPShape *sp_shape = dynamic_cast<SPShape *>(item);
- if (sp_shape) {
- SPCurve *c = sp_shape->getCurve();
- if (!c) {
- return;
- }
- if(pt->points.empty()){
- SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
- const char *stroke_width = sp_repr_css_property(css_item, "stroke-width", "0");
- double swidth;
- sp_svg_number_read_d(stroke_width, &swidth);
- swidth = prefs->getDouble("/live_effect/power_stroke/width", swidth/2);
- if (!swidth) {
- swidth = swidth/2;
- }
- pt->points.emplace_back(0, swidth);
- }
- Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE();
- LPEPowerStroke* ps = nullptr;
- Glib::ustring pref_path_pp = "/live_effects/powerstroke/powerpencil";
- prefs->setBool(pref_path_pp, true);
- if (lpe) {
- ps = static_cast<LPEPowerStroke*>(lpe);
- }
- if (!lpe || !ps) {
- Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), item);
- Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE();
- ps = static_cast<LPEPowerStroke*>(lpe);
- }
- if (ps) {
- if (pt->sa) {
- std::vector<Geom::Point> sa_points;
- if (pt->sa->start) {
- sa_points = ps->offset_points.reverse_controlpoints(false);
- } else {
- sa_points = ps->offset_points.data();
+ SPObject *elemref = nullptr;
+ if ((elemref = document->getObjectById("power_stroke_preview"))) {
+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(elemref), false, true);
+ if (SP_SHAPE(elemref)->getCurve() != pt->curvepressure) {
+ elemref->getRepr()->setAttribute("style", nullptr);
+ SPObject *successor = dynamic_cast<SPObject *>(elemref);
+ sp_desktop_apply_style_tool(desktop, successor->getRepr(), Glib::ustring("/tools/freehand/pencil").data(), false);
+ spdc_apply_style(successor);
+ sp_lpe_item_enable_path_effects(SP_LPE_ITEM(item), false);
+ item->getRepr()->setAttribute("style", elemref->getRepr()->attribute("style"));
+ item->getRepr()->setAttribute("inkscape:original-d", elemref->getRepr()->attribute("inkscape:original-d"));
+ SP_LPE_ITEM(item)->set(SP_ATTR_INKSCAPE_PATH_EFFECT, elemref->getRepr()->attribute("inkscape:path-effect"));
+ sp_lpe_item_enable_path_effects(SP_LPE_ITEM(item), true);
+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, true);
+ //successor->deleteObject(true);
+ //successor = nullptr;
+ } else {
+ using namespace Inkscape::LivePathEffect;
+ Effect* lpe = SP_LPE_ITEM(elemref)->getCurrentLPE();
+ if (lpe) {
+ SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true);
+ LivePathEffectObject * lpeobj = lpe->getLPEObj();
+ if (lpeobj) {
+ SP_OBJECT(lpeobj)->deleteObject(true);
+ lpeobj = nullptr;
}
- sa_points.insert(sa_points.end(), pt->points.begin(), pt->points.end());
- pt->points = sa_points;
- sa_points.clear();
}
- Geom::Path path = c->get_pathvector()[0];
- if (!path.empty()) {
- pt->powerStrokeInterpolate(path);
+ elemref->deleteObject(true);
+ elemref = nullptr;
+ maxrecursion ++;
+ if (maxrecursion < 5) {
+ pt->addPowerStrokePencil(true);
+ spdc_apply_powerstroke_shape(points, dc, item, maxrecursion);
}
- bool transform_stroke = prefs->getBool("/options/transform/stroke", true);
- prefs->setBool("/options/transform/stroke", true);
- ps->offset_points.param_set_and_write_new_value(pt->points);
- ps->offset_points.param_transform_multiply(transform_coordinate.inverse(), false);
- prefs->setBool("/options/transform/stroke", transform_stroke);
}
- prefs->setBool(pref_path_pp, false);
- return;
+ } else {
+ maxrecursion ++;
+ if (maxrecursion < 5) {
+ pt->addPowerStrokePencil(true);
+ spdc_apply_powerstroke_shape(points, dc, item, maxrecursion);
+ }
}
+ return;
}
}
Effect::createAndApply(POWERSTROKE, dc->desktop->doc(), item);
@@ -349,8 +373,8 @@ static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem
lpe->getRepr()->setAttribute("threshold", threshold);
lpe->getRepr()->setAttribute("smooth_angles", "360");
lpe->getRepr()->setAttribute("helper_size", "0");
- lpe->getRepr()->setAttribute("simplifyindividualpaths", "false");
- lpe->getRepr()->setAttribute("simplifyJustCoalesce", "false");
+ lpe->getRepr()->setAttribute("simplify_individual_paths", "false");
+ lpe->getRepr()->setAttribute("simplify_just_coalesce", "false");
}
enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, BEND_CLIPBOARD, LAST_APPLIED };
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 00e5dee46..23f4bba69 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -22,7 +22,7 @@
#include <2geom/sbasis-to-bezier.h>
#include <2geom/bezier-utils.h>
#include "ui/tools/pencil-tool.h"
-
+#include <2geom/svg-path-parser.h>
#include "desktop.h"
#include "inkscape.h"
@@ -40,6 +40,7 @@
#include "display/sp-canvas.h"
#include "live_effects/lpe-powerstroke-interpolators.h"
+#include "live_effects/lpe-powerstroke.h"
#include "object/sp-path.h"
#include "object/sp-lpe-item.h"
@@ -55,8 +56,8 @@
#include "xml/node.h"
#include "xml/sp-css-attr.h"
#include <glibmm/i18n.h>
-#include <thread>
-#include <chrono>
+// #include <thread>
+// #include <chrono>
namespace Inkscape {
namespace UI {
@@ -82,7 +83,6 @@ PencilTool::PencilTool()
, _req_tangent(0, 0)
, _is_drawing(false)
, sketch_n(0)
- , _powerpreview(nullptr)
, _curve(nullptr)
, _previous_pressure(0.0)
, _last_point(Geom::Point())
@@ -95,6 +95,7 @@ void PencilTool::setup() {
this->enableSelectionCue();
}
this->_curve = new SPCurve();
+ this->curvepressure = new SPCurve();
FreehandBase::setup();
this->_is_drawing = false;
@@ -107,6 +108,9 @@ PencilTool::~PencilTool() {
if (this->_curve) {
this->_curve->unref();
}
+ if (this->curvepressure) {
+ this->curvepressure->unref();
+ }
}
void PencilTool::_extinput(GdkEvent *event) {
@@ -115,8 +119,6 @@ void PencilTool::_extinput(GdkEvent *event) {
is_tablet = true;
} else {
this->pressure = DDC_DEFAULT_PRESSURE;
- //If no pressure device ignore pressure button
- tablet_enabled = false;
is_tablet = false;
}
}
@@ -203,8 +205,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
pencil_drag_origin_w = Geom::Point(bevent.x,bevent.y);
pencil_within_tolerance = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- tablet_enabled = prefs->getBool("/tools/freehand/pencil/pressure", false) ||
- prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3;
+ tablet_enabled = prefs->getBool("/tools/freehand/pencil/pressure", false);
switch (this->_state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Current segment will be finished with release */
@@ -214,7 +215,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
/* Set first point of sequence */
SnapManager &m = desktop->namedview->snap_manager;
if (bevent.state & GDK_CONTROL_MASK) {
- m.setup(desktop, true, _powerpreview);
+ m.setup(desktop, true);
if (!(bevent.state & GDK_SHIFT_MASK)) {
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_NODE_HANDLE);
}
@@ -233,7 +234,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
}
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path"));
} else {
- m.setup(desktop, true, _powerpreview);
+ m.setup(desktop, true);
if (tablet_enabled && this->pressure) {
// This is the first click of a new curve; deselect item so that
// this curve is not combined with it (unless it is drawn from its
@@ -355,7 +356,7 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
// whether we're going into freehand mode or not
this->ps.push_back(this->p[0]);
if (tablet_enabled) {
- this->_wps.push_back(this->pressure);
+ this->_wps.push_back(this->pressure/10);
}
}
this->_addFreehandPoint(p, mevent.state);
@@ -387,9 +388,9 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
// Show the pre-snap indicator to communicate to the user where we would snap to if he/she were to
// a) press the mousebutton to start a freehand drawing, or
// b) release the mousebutton to finish a freehand drawing
- if (!this->sp_event_context_knot_mouseover()) {
+ if (!tablet_enabled && !this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop, true, _powerpreview);
+ m.setup(desktop, true);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
m.unSetup();
}
@@ -477,8 +478,16 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
/* Write curves to object */
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand"));
this->_interpolate();
- this->removePowerStrokePreview();
- spdc_concat_colors_and_flush(this, FALSE);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ tablet_enabled = prefs->getBool("/tools/freehand/pencil/pressure", false);
+ if (tablet_enabled) {
+ gint prevmode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
+ prefs->setInt("/tools/freehand/pencil/freehand-mode", 0);
+ spdc_concat_colors_and_flush(this, FALSE);
+ prefs->setInt("/tools/freehand/pencil/freehand-mode", prevmode);
+ } else {
+ spdc_concat_colors_and_flush(this, FALSE);
+ }
this->points.clear();
this->sa = nullptr;
this->ea = nullptr;
@@ -690,50 +699,6 @@ void PencilTool::_finishEndpoint() {
}
}
-void
-PencilTool::removePowerStrokePreview()
-{
- SPDocument * document = SP_ACTIVE_DOCUMENT;
- if (!document) {
- return;
- }
- SPObject *elemref = nullptr;
- if (future.valid()) {
- std::future_status status = future.wait_for(std::chrono::milliseconds(100));
- while (status == std::future_status::deferred) {
- status = future.wait_for(std::chrono::milliseconds(100));
- }
- }
- if ((elemref = document->getObjectById("power_stroke_preview"))) {
- using namespace Inkscape::LivePathEffect;
- Effect* lpe = SP_LPE_ITEM(elemref)->getCurrentLPE();
- if (lpe) {
- SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true);
- LivePathEffectObject * lpeobj = lpe->getLPEObj();
- if (lpeobj) {
- SP_OBJECT(lpeobj)->deleteObject(true);
- lpeobj = nullptr;
- }
- }
- elemref->deleteObject(true);
- elemref = nullptr;
- }
- if ((elemref = document->getObjectById("tmp_power_stroke_preview"))) {
- using namespace Inkscape::LivePathEffect;
- Effect* lpe = SP_LPE_ITEM(elemref)->getCurrentLPE();
- if (lpe) {
- SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true);
- LivePathEffectObject * lpeobj = lpe->getLPEObj();
- if (lpeobj) {
- SP_OBJECT(lpeobj)->deleteObject(true);
- lpeobj = nullptr;
- }
- }
- elemref->deleteObject(true);
- elemref = nullptr;
- }
-}
-
static inline double
square(double const x)
{
@@ -741,13 +706,19 @@ square(double const x)
}
void
-PencilTool::addPowerStrokePencil()
+PencilTool::addPowerStrokePencil(bool force)
{
+ static int pscounter = 11;
+ if (pscounter > 10 || force) {
+ pscounter = 0;
+ } else {
+ pscounter++;
+ return;
+ }
using namespace Inkscape::LivePathEffect;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- double step = prefs->getIntLimited("/tools/freehand/pencil/ps-step-pressure",5, 1, 100)/100.0;
- double min = prefs->getIntLimited("/tools/freehand/pencil/minpressure", 0, 1, 100) / 100.0;
- double max = prefs->getIntLimited("/tools/freehand/pencil/maxpressure", 100, 1, 100) / 100.0;
+ double min = prefs->getIntLimited("/tools/freehand/pencil/minpressure", 10, 1, 100) / 100.0;
+ double max = prefs->getIntLimited("/tools/freehand/pencil/maxpressure", 40, 1, 100) / 100.0;
Geom::Affine transform_coordinate = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2dt_affine();
if (min > max){
min = max;
@@ -755,23 +726,16 @@ PencilTool::addPowerStrokePencil()
double dezoomify_factor = 0.05 * 1000/SP_EVENT_CONTEXT(this)->desktop->current_zoom();//\/100 we want 100% = 1;
double last_pressure = this->_wps.back();
double pressure_shrunk = (last_pressure * (max - min)) + min;
- step = (step * (max - min)) + min;
//We need half width for power stroke
- double pressure_computed = (pressure_shrunk * dezoomify_factor)/2.0;
+ double pressure_computed = (pressure_shrunk * dezoomify_factor)/5.0;
this->_last_point = this->ps.back();
this->_last_point *= transform_coordinate.inverse();
- if (this->ps.size() == 1 ||
- std::abs(_previous_pressure - pressure_shrunk) > step ||
- _previous_pressure == 0.0 ||
- (_previous_pressure > step && pressure_shrunk < step))
- {
- _previous_pressure = pressure_shrunk;
- this->_points_pressure.push_back(Geom::Point(0, pressure_computed));
- this->_points_pos.push_back(this->_last_point);
- }
+ this->_points_pressure.push_back(Geom::Point(0, pressure_computed));
+ this->_points_pos.push_back(this->_last_point);
if (this->_curve && this->ps.size() > 1) {
-
- std::future_status status;
+ // Example og work with std::future
+ // Retain for other works
+ /* std::future_status status;
bool stop = false;
bool nofuture = false;
try {
@@ -786,123 +750,147 @@ PencilTool::addPowerStrokePencil()
}
}
if (nofuture || status == std::future_status::ready) {
- if (!stop && status == std::future_status::ready) {
- const gchar *tmpid = "tmp_power_stroke_preview";
- const gchar *id = "power_stroke_preview";
- SPDocument * document = SP_ACTIVE_DOCUMENT;
- if (!document) {
- return;
- }
- SPObject *elemref = document->getObjectById(id);
- SPObject *tmpelemref = document->getObjectById(tmpid);
- using namespace Inkscape::LivePathEffect;
- if (tmpelemref) {
- bool failed = true;
- if (elemref->getRepr()->attribute("style") != "opacity:0") {
- failed = false;
- }
- SPObject *toremove = failed ? elemref : tmpelemref;
- SPObject *toretain = !failed ? elemref : tmpelemref;
- using namespace Inkscape::LivePathEffect;
- Effect* lpe = SP_LPE_ITEM(toremove)->getCurrentLPE();
- SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true);
- LivePathEffectObject * lpeobj = lpe->getLPEObj();
- if (lpeobj) {
- SP_OBJECT(lpeobj)->deleteObject(true);
- lpeobj = nullptr;
- }
- toremove->deleteObject(true);
- toremove = nullptr;
- toretain->getRepr()->setAttribute("id", tmpid);
- } else if (elemref) {
- elemref->getRepr()->setAttribute("id", tmpid);
+ if (!stop && status == std::future_status::ready) { */
+
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return;
+ }
+ const gchar *id = "power_stroke_preview";
+ SPObject *toremove = document->getObjectById(id);
+ using namespace Inkscape::LivePathEffect;
+ if (toremove) {
+ toremove->getRepr()->setAttribute("id","tmp_power_stroke_preview");
+ }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double tol = prefs->getDoubleLimited("/tools/freehand/pencil/base-simplify", 25.0, 1.0, 100.0) * 0.4;
+ double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2);
+ int n_points = this->ps.size();
+ // worst case gives us a segment per point
+ int max_segs = 4 * n_points;
+ std::vector<Geom::Point> b(max_segs);
+ std::vector<Geom::Point> pts;
+ curvepressure->reset();
+ int const n_segs = Geom::bezier_fit_cubic_r(b.data(), this->ps.data(), n_points, tolerance_sq, max_segs);
+ if (n_segs > 0) {
+ /* Fit and draw and reset state */
+ curvepressure->moveto(b[0]);
+ for (int c = 0; c < n_segs; c++) {
+ curvepressure->curveto(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
+ }
+ }
+ Geom::Path path = curvepressure->get_pathvector()[0];
+
+ /* gdouble size = Geom::L2(original_pathv.boundsFast()->dimensions());
+ //size /= Geom::Affine(0,0,0,0,0,0).descrim();
+ Path* pathliv = Path_for_pathvector(original_pathv);
+ size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions());
+ //size /= sp_lpe_item->i2doc_affine().descrim();
+ pathliv->ConvertEvenLines(tol * size);
+ pathliv->Simplify(tol * size);
+
+ Geom::Path path = Geom::parse_svg_path(pathliv->svg_dump_path())[0];*/
+ if (!path.empty()) {
+ Geom::Affine transform_coordinate = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2dt_affine().inverse();
+ path *= transform_coordinate;
+ // std::vector<Geom::Point> points_preview = this->points;
+ // points_preview.push_back(Geom::Point(path.size() - 1, points_preview[points_preview.size()-1][Geom::Y]));
+ // future = std::async(std::launch::async, [path, points_preview] {
+ using namespace Inkscape::LivePathEffect;
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if (!document) {
+ return;
+ // return true;
+ }
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
+ Inkscape::XML::Node *pp = nullptr;
+ pp = xml_doc->createElement("svg:path");
+ pp->setAttribute("sodipodi:insensitive", "true");
+ gchar * pvector_str = sp_svg_write_path(path);
+ if (pvector_str) {
+ pp->setAttribute("d" , pvector_str);
+ g_free(pvector_str);
+ }
+ pp->setAttribute("id", "power_stroke_preview");
+ Inkscape::GC::release(pp);
+
+ SPShape *powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(pp));
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(powerpreview);
+ if (!lpeitem) {
+ return;
+ // return true;
+ }
+ tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0);
+ tol = tol/(100.0*(102.0-tol));
+ std::ostringstream threshold;
+ threshold << tol;
+ Effect::createAndApply(SIMPLIFY, desktop->doc(), SP_ITEM(lpeitem));
+ Effect* lpe = lpeitem->getCurrentLPE();
+ if (lpe) {
+ Glib::ustring pref_path = "/live_effects/simplify/smooth_angles";
+ bool valid = prefs->getEntry(pref_path).isValid();
+ if (!valid){
+ lpe->getRepr()->setAttribute("smooth_angles", "360");
}
+ lpe->getRepr()->setAttribute("threshold", threshold.str());
+ lpe->getRepr()->setAttribute("steps", "1");
+ lpe->getRepr()->setAttribute("helper_size", "0");
+ lpe->getRepr()->setAttribute("simplify_individual_paths", "false");
+ lpe->getRepr()->setAttribute("simplify_just_coalesce", "false");
}
+ sp_lpe_item_update_patheffect(lpeitem, false, true);
+ curvepressure = powerpreview->getCurve();
+ path = curvepressure->get_pathvector()[0];
+ powerStrokeInterpolate(path);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- SPCurve *curve = new SPCurve();
- double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
- bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0);
- if(simplify){
- double tol2 = prefs->getDoubleLimited("/tools/freehand/pencil/base-simplify", 25.0, 1.0, 100.0) * 0.4;
- tol = std::min(tol,tol2);
- }
- double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2);
- int n_points = this->ps.size();
- // worst case gives us a segment per point
- int max_segs = 4 * n_points;
- std::vector<Geom::Point> b(max_segs);
- int const n_segs = Geom::bezier_fit_cubic_r(b.data(), this->ps.data(), n_points, tolerance_sq, max_segs);
- if (n_segs > 0) {
- /* Fit and draw and reset state */
- curve->moveto(b[0]);
- for (int c = 0; c < n_segs; c++) {
- curve->curveto(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
+ Glib::ustring pref_path_pp = "/live_effects/powerstroke/powerpencil";
+ prefs->setBool(pref_path_pp, true);
+ Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), lpeitem);
+ lpe = lpeitem->getCurrentLPE();
+ Inkscape::LivePathEffect::LPEPowerStroke *pspreview = static_cast<LPEPowerStroke*>(lpe);
+ sp_lpe_item_enable_path_effects(lpeitem, false);
+ if (pspreview) {
+ Glib::ustring pref_path = "/live_effects/powerstroke/interpolator_type";
+ bool valid = prefs->getEntry(pref_path).isValid();
+ if (!valid){
+ pspreview->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom");
+ }
+ pspreview->getRepr()->setAttribute("sort_points", "true");
+ pspreview->offset_points.param_set_and_write_new_value(this->points);
+ if (powerpreview->getCurve() != curvepressure) {
+ pp->setAttribute("style", "fill:#888888;opacity:1;fill-rule:nonzero;stroke:none;");
+ } else if (toremove) {
+ toremove->getRepr()->setAttribute("id","power_stroke_preview");
+ toremove = powerpreview;
}
}
- Geom::Path path = curve->get_pathvector()[0];
- delete curve;
- if (!path.empty()) {
- Geom::Affine transform_coordinate = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2dt_affine().inverse();
- path *= transform_coordinate;
- powerStrokeInterpolate(path);
- std::vector<Geom::Point> points_preview = this->points;
- points_preview.push_back(Geom::Point(path.size() - 1, points_preview[points_preview.size()-1][Geom::Y]));
- future = std::async(std::launch::async, [path, points_preview] {
- using namespace Inkscape::LivePathEffect;
- SPDocument * document = SP_ACTIVE_DOCUMENT;
- if (!document) {
- return true;
- }
- Inkscape::XML::Document *xml_doc = document->getReprDoc();
- Inkscape::XML::Node *pp = nullptr;
- pp = xml_doc->createElement("svg:path");
- pp->setAttribute("sodipodi:insensitive", "true");
- gchar * pvector_str = sp_svg_write_path(path);
- if (pvector_str) {
- pp->setAttribute("d" , pvector_str);
- pp->setAttribute("style", "opacity:0");
- g_free(pvector_str);
- }
- pp->setAttribute("id", "power_stroke_preview");
- Inkscape::GC::release(pp);
- SPShape *powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(pp));
- SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(powerpreview);
- if (!lpeitem) {
- return true;
- }
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- Glib::ustring pref_path_pp = "/live_effects/powerstroke/powerpencil";
- Glib::ustring pref_path_ps = "/live_effects/powerstroke/powerpencilstyle";
- prefs->setBool(pref_path_pp, true);
- prefs->setBool(pref_path_ps, true);
- Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), lpeitem);
- Effect* lpe = lpeitem->getCurrentLPE();
- Inkscape::LivePathEffect::LPEPowerStroke *pspreview = static_cast<LPEPowerStroke*>(lpe);
- if (pspreview) {
- sp_lpe_item_enable_path_effects(lpeitem, false);
- Glib::ustring pref_path = "/live_effects/powerstroke/interpolator_type";
- bool valid = prefs->getEntry(pref_path).isValid();
- if (!valid){
- pspreview->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom");
- }
- pspreview->getRepr()->setAttribute("sort_points", "true");
- pspreview->offset_points.param_set_and_write_new_value(points_preview);
- sp_lpe_item_enable_path_effects(lpeitem, true);
- }
- if (powerpreview->getCurve() != powerpreview->getCurveBeforeLPE()) {
- pp->setAttribute("style", "fill:#888888;opacity:0.7;fill-rule:nonzero;stroke:none;");
- }
- prefs->setBool(pref_path_pp, false);
- prefs->setBool(pref_path_ps, false);
- return true;
- });
- } else {
- std::cout << "stopped" << std::endl;
+ sp_lpe_item_enable_path_effects(lpeitem, true);
+
+ if (toremove) {
+ using namespace Inkscape::LivePathEffect;
+ Effect* lpe = SP_LPE_ITEM(toremove)->getCurrentLPE();
+ SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true);
+ LivePathEffectObject * lpeobj = lpe->getLPEObj();
+ if (lpeobj) {
+ SP_OBJECT(lpeobj)->deleteObject(true);
+ lpeobj = nullptr;
+ }
+ lpe = SP_LPE_ITEM(toremove)->getCurrentLPE();
+ SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true);
+ lpeobj = lpe->getLPEObj();
+ if (lpeobj) {
+ SP_OBJECT(lpeobj)->deleteObject(true);
+ lpeobj = nullptr;
+ }
+ toremove->deleteObject(true);
+ toremove = nullptr;
}
+ prefs->setBool(pref_path_pp, false);
+ // return true;
+ // });
}
}
-
}
void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) {
@@ -916,10 +904,8 @@ void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) {
this->_fitAndSplit();
this->ps.push_back(p);
if (tablet_enabled) {
- if (this->pressure != 0) {
- this->_wps.push_back(this->pressure);
- this->addPowerStrokePencil();
- }
+ this->_wps.push_back(this->pressure/10);
+ this->addPowerStrokePencil(false);
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), nullptr);
for (auto i:this->green_bpaths) {
sp_canvas_item_destroy(i);
@@ -937,6 +923,14 @@ PencilTool::powerStrokeInterpolate(Geom::Path path) {
}
using Geom::X;
using Geom::Y;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double step = prefs->getDoubleLimited("/tools/freehand/pencil/pressurestep", 5.0, 0.0, 100.0)/100.0;
+ double min = prefs->getIntLimited("/tools/freehand/pencil/minpressure", 10, 1, 100) / 100.0;
+ double max = prefs->getIntLimited("/tools/freehand/pencil/maxpressure", 40, 1, 100) / 100.0;
+ if (min > max){
+ min = max;
+ }
+ step = (step * (max - min)) + min;
SPItem *item = selection ? selection->singleItem() : nullptr;
gint points_size = this->_points_pos.size();
std::vector<Geom::Point> tmp_points;
@@ -944,16 +938,23 @@ PencilTool::powerStrokeInterpolate(Geom::Path path) {
Geom::Point prev = Geom::Point(Geom::infinity(), Geom::infinity());
size_t i = 0;
for (auto pospoint: this->_points_pos) {
- double pos = Geom::nearest_time(pospoint, path);
Geom::Point pp = pospoint;
- pp[Geom::X] = pos;
+ pp[Geom::X] = (path.size()/(double)this->_points_pos.size()) * i;
pp[Geom::Y] = this->_points_pressure[i][Geom::Y];
- if (!Geom::are_near(prev[Geom::X], pos, 0.2))
+ if (this->_points_pos.size() - 1 == i ||
+ (!Geom::are_near(prev[Geom::X], pp[Geom::X], 0.2) &&
+ !Geom::are_near(prev[Geom::Y], pp[Geom::Y], step)))
{
tmp_points.push_back(pp);
+ prev = pp;
+ std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAA" << std::endl;
}
+ std::cout << pp << std::endl;
+ std::cout << step << std::endl;
+ std::cout << path.size() << std::endl;
+ std::cout << i << std::endl;
+ std::cout << ":::::::::::::::::::" << std::endl;
++i;
- prev = pp;
}
this->points = tmp_points;
tmp_points.clear();
diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h
index 03b631f95..a4c9cbe39 100644
--- a/src/ui/tools/pencil-tool.h
+++ b/src/ui/tools/pencil-tool.h
@@ -11,14 +11,13 @@
#define SEEN_PENCIL_CONTEXT_H
-#include "live_effects/lpe-powerstroke.h"
#include "ui/tools/freehand-base.h"
#include <2geom/piecewise.h>
#include <2geom/d2.h>
#include <2geom/sbasis.h>
#include <2geom/pathvector.h>
-#include <future>
+// #include <future>
class SPShape;
@@ -49,13 +48,12 @@ public:
Geom::Point p[16];
std::vector<Geom::Point> ps;
std::vector<Geom::Point> points;
- void addPowerStrokePencil(SPCurve *& c);
- void addPowerStrokePencil();
- void removePowerStrokePreview();
+ void addPowerStrokePencil(bool force);
void powerStrokeInterpolate(Geom::Path);
Geom::Piecewise<Geom::D2<Geom::SBasis> > sketch_interpolation; // the current proposal from the sketched paths
unsigned sketch_n; // number of sketches done
static const std::string prefsPath;
+ SPCurve * curvepressure;
const std::string& getPrefsPath() override;
protected:
@@ -85,13 +83,11 @@ private:
Geom::Point _last_point;
double _previous_pressure;
SPCurve * _curve;
- SPShape *_powerpreview;
- Inkscape::LivePathEffect::LPEPowerStroke * _pspreview;
Geom::Point _req_tangent;
bool _is_drawing;
PencilState _state;
gint _npoints;
- std::future<bool> future;
+ // std::future<bool> future;
};
}
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 079a61de5..5a33616c5 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -724,14 +724,16 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
gtk_stack_add_named((GtkStack *)grouper, holder, aux_toolboxes[i].type_name);
sp_set_font_size_smaller( holder );
gtk_widget_set_name( holder, aux_toolboxes[i].ui_name );
-
+ gtk_widget_show(sub_toolbox);
+ gtk_widget_show(holder);
} else {
g_warning("Could not create toolbox %s", aux_toolboxes[i].ui_name);
}
}
gtk_container_add(GTK_CONTAINER(toolbox), grouper);
gtk_stack_set_visible_child_name((GtkStack *)grouper, "/tools/select");
- gtk_widget_show_all(grouper);
+ // do not use show_all to get good display of hidden widgets at start
+ gtk_widget_show(grouper);
}
void update_aux_toolbox(SPDesktop * /*desktop*/, ToolBase *eventcontext, GtkWidget *toolbox)
@@ -822,8 +824,6 @@ void ToolboxFactory::showAuxToolbox(GtkWidget *toolbox_toplevel)
return;
}
gtk_widget_show(toolbox);
-
- gtk_widget_show_all(shown_toolbox);
}
#define MODE_LABEL_WIDTH 70