From 6ff4da4367db057c78ee3bce2dc66bb3be99f0a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 13 Jul 2019 19:53:51 +0200 Subject: PoewePencil improvements --- src/live_effects/lpe-powerstroke.cpp | 68 +++--- src/live_effects/lpe-powerstroke.h | 2 +- src/ui/dialog/inkscape-preferences.cpp | 11 - src/ui/dialog/inkscape-preferences.h | 1 - src/ui/toolbar/pencil-toolbar.cpp | 107 +++++---- src/ui/toolbar/pencil-toolbar.h | 6 +- src/ui/tools/freehand-base.cpp | 132 ++++++----- src/ui/tools/pencil-tool.cpp | 385 +++++++++++++++++---------------- src/ui/tools/pencil-tool.h | 12 +- src/widgets/toolbox.cpp | 8 +- 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")); @@ -354,6 +344,18 @@ PencilToolbar::maxpressure_value_changed() prefs->setDouble( "/tools/freehand/pencil/maxpressure", _maxpressure_adj->get_value()); } +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(); @@ -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 _minpressure_adj; Glib::RefPtr _maxpressure_adj; + Glib::RefPtr _pressurestep_adj; Glib::RefPtr _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 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 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(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(lpe); - } - if (!lpe || !ps) { - Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), item); - Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - ps = static_cast(lpe); - } - if (ps) { - if (pt->sa) { - std::vector 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(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 -#include -#include +// #include +// #include 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 b(max_segs); + std::vector 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 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(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 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(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 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(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(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 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 +// #include class SPShape; @@ -49,13 +48,12 @@ public: Geom::Point p[16]; std::vector ps; std::vector points; - void addPowerStrokePencil(SPCurve *& c); - void addPowerStrokePencil(); - void removePowerStrokePreview(); + void addPowerStrokePencil(bool force); void powerStrokeInterpolate(Geom::Path); Geom::Piecewise > 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 future; + // std::future 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 -- cgit v1.2.3