summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2017-08-25 13:32:29 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-08-25 13:32:29 +0000
commit6d99fed16aeeb21341e5d28f52534b2a0b94f876 (patch)
tree5caf1bbcf66d2c7e04092ef482c00cad63d3d076 /src/ui
parent[LP:1634022] xcf export - Guides and grids wrongly positionned. Guides and gr... (diff)
downloadinkscape-6d99fed16aeeb21341e5d28f52534b2a0b94f876.tar.gz
inkscape-6d99fed16aeeb21341e5d28f52534b2a0b94f876.zip
Starting with powerpencil
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/tools/freehand-base.cpp62
-rw-r--r--src/ui/tools/freehand-base.h15
-rw-r--r--src/ui/tools/pen-tool.cpp4
-rw-r--r--src/ui/tools/pencil-tool.cpp78
-rw-r--r--src/ui/tools/pencil-tool.h60
5 files changed, 177 insertions, 42 deletions
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index 76d2df8c5..05afd8058 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -32,6 +32,7 @@
#include "macros.h"
#include "message-stack.h"
#include "ui/tools/pen-tool.h"
+#include "ui/tools/pencil-tool.h"
#include "ui/tools/lpe-tool.h"
#include "selection-chemistry.h"
#include "sp-item-group.h"
@@ -41,6 +42,10 @@
// clipboard support
#include "ui/clipboard.h"
+#define MIN_PRESSURE 0.0
+#define MAX_PRESSURE 1.0
+#define DEFAULT_PRESSURE 1.0
+
using Inkscape::DocumentUndo;
namespace Inkscape {
@@ -89,6 +94,7 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape)
, waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE)
, red_curve_is_valid(false)
, anchor_statusbar(false)
+ , pressure(DEFAULT_PRESSURE)
{
}
@@ -222,12 +228,56 @@ 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(const std::vector<Geom::Point> & points, FreehandBase *dc, SPItem *item)
+static void spdc_apply_powerstroke_shape(std::vector<Geom::Point> points, FreehandBase *dc, SPItem *item)
{
using namespace Inkscape::LivePathEffect;
+ if (SP_IS_PENCIL_CONTEXT(dc)) {
+ PencilTool *pt = SP_PENCIL_CONTEXT(dc);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 3) {
+ SPShape *sp_shape = dynamic_cast<SPShape *>(item);
+ Geom::PathVector pathvector;
+ if (sp_shape) {
+ pathvector = sp_shape->getCurve()->get_pathvector();
+ size_t counter = 0;
+ auto wps = pt->wps.begin();
+ double previous_pos = 0.0;
+ for (auto pps = pt->pps.begin(); pps != pt->pps.end(); ++pps,++wps) {
+ counter++;
+ Geom::Affine transformCoordinate = item->i2dt_affine();
+ Geom::Point position = *pps;
+ position *= transformCoordinate.inverse();
+ double pos = Geom::nearest_time(position, paths_to_pw(pathvector));
+ double width = *wps;
+ if(pos > 1e6) {
+ pos = 0;;
+ }
+ if(pos > pathvector[0].size() ) {
+ pos = pathvector[0].size();
+ }
+ if ((pos - previous_pos) < pt->min_distance ||
+ (counter == pt->wps.size() || (pos - previous_pos) < 0.1) )
+ {
+ continue;
+ }
+ previous_pos = pos;
+ if (!Geom::are_near(width, 0.0, 0.1) ) {
+ points.push_back(Geom::Point(pos,width));
+ }
+ }
+ }
+ Effect::createAndApply(POWERSTROKE, dc->desktop->doc(), item);
+ Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE();
+
+ static_cast<LPEPowerStroke*>(lpe)->offset_points.param_set_and_write_new_value(points);
+ return;
+ }
+ }
+
Effect::createAndApply(POWERSTROKE, dc->desktop->doc(), item);
Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE();
+
static_cast<LPEPowerStroke*>(lpe)->offset_points.param_set_and_write_new_value(points);
// write powerstroke parameters:
@@ -321,7 +371,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
}
bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0);
if(simplify){
- double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0);
+ double tol = prefs->getDoubleLimited(tool_name(dc) + "/tolerance", 10.0, 1.0, 100.0);
tol = tol/(100.0*(102.0-tol));
std::ostringstream ss;
ss << tol;
@@ -339,7 +389,13 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
if (sp_shape) {
curve = sp_shape->getCurve();
}
-
+ if (SP_IS_PENCIL_CONTEXT(dc)) {
+ if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 3) {
+ std::vector<Geom::Point> points;
+ spdc_apply_powerstroke_shape(points, dc, item);
+ shape = NONE;
+ }
+ }
bool shape_applied = false;
SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
const char *cstroke = sp_repr_css_property(css_item, "stroke", "none");
diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h
index a3069aa09..11c5ac124 100644
--- a/src/ui/tools/freehand-base.h
+++ b/src/ui/tools/freehand-base.h
@@ -44,8 +44,8 @@ namespace Tools {
class FreehandBase : public ToolBase {
public:
- FreehandBase(gchar const *const *cursor_shape);
- virtual ~FreehandBase();
+ FreehandBase(gchar const *const *cursor_shape);
+ virtual ~FreehandBase();
Inkscape::Selection *selection;
SPCanvasItem *grab;
@@ -98,12 +98,15 @@ public:
bool red_curve_is_valid;
bool anchor_statusbar;
+
+ gdouble pressure;
+ virtual void set(const Inkscape::Preferences::Entry& val);
protected:
- virtual void setup();
- virtual void finish();
- virtual void set(const Inkscape::Preferences::Entry& val);
- virtual bool root_handler(GdkEvent* event);
+
+ virtual void setup();
+ virtual void finish();
+ virtual bool root_handler(GdkEvent* event);
};
/**
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index 77cb5b6f8..b3497d006 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -1774,9 +1774,9 @@ void PenTool::_bsplineSpiroBuild()
//LivePathEffectObject *lpeobj = static_cast<LivePathEffectObject*> (curve);
//Effect *spr = static_cast<Effect*> ( new LPEbspline(lpeobj) );
//spr->doEffect(curve);
- if(this->bspline){
+ if (this->bspline) {
LivePathEffect::sp_bspline_do_effect(curve, 0);
- }else{
+ } else {
LivePathEffect::sp_spiro_do_effect(curve);
}
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 99b8103c3..23a442b11 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -63,6 +63,11 @@ PencilTool::PencilTool()
, state(SP_PENCIL_CONTEXT_IDLE)
, req_tangent(0, 0)
, is_drawing(false)
+ , previous_pressure(0.0)
+ , gap_pressure(1.0)
+ , min_distance(0.2)
+ , start_clamp(DDC_MIN_PRESSURE)
+ , end_clamp(DDC_MAX_PRESSURE)
, sketch_n(0)
{
}
@@ -79,9 +84,19 @@ void PencilTool::setup() {
this->anchor_statusbar = false;
}
+
+
PencilTool::~PencilTool() {
}
+void PencilTool::_extinput(GdkEvent *event) {
+ if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &this->pressure)) {
+ this->pressure = CLAMP (this->pressure, start_clamp, end_clamp);
+ } else {
+ this->pressure = DDC_DEFAULT_PRESSURE;
+ }
+}
+
/** Snaps new node relative to the previous node. */
void PencilTool::_endpointSnap(Geom::Point &p, guint const state) {
if ((state & GDK_CONTROL_MASK)) { //CTRL enables constrained snapping
@@ -110,6 +125,7 @@ bool PencilTool::root_handler(GdkEvent* event) {
break;
case GDK_MOTION_NOTIFY:
+ this->_extinput(event);
ret = this->_handleMotionNotify(event->motion);
break;
@@ -138,7 +154,6 @@ bool PencilTool::root_handler(GdkEvent* event) {
bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
bool ret = false;
-
if ( bevent.button == 1 && !this->space_panning) {
Inkscape::Selection *selection = desktop->getSelection();
@@ -165,7 +180,10 @@ 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();
+ if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) {
+ this->state = SP_PENCIL_CONTEXT_FREEHAND;
+ }
switch (this->state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Current segment will be finished with release */
@@ -224,7 +242,7 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
}
bool ret = false;
-
+
if (this->space_panning || (mevent.state & GDK_BUTTON2_MASK) || (mevent.state & GDK_BUTTON3_MASK)) {
// allow scrolling
return false;
@@ -244,9 +262,8 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
/* Test whether we hit any anchor. */
SPDrawAnchor *anchor = spdc_test_inside(this, Geom::Point(mevent.x, mevent.y));
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (pencil_within_tolerance) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
if ( Geom::LInfty( Geom::Point(mevent.x,mevent.y) - pencil_drag_origin_w ) < tolerance ) {
return false; // Do not drag if we're within tolerance from origin.
@@ -261,6 +278,10 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
switch (this->state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Set red endpoint */
+ if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) {
+ this->state = SP_PENCIL_CONTEXT_FREEHAND;
+ return true;
+ }
if (anchor) {
p = anchor->dp;
} else {
@@ -294,6 +315,9 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
// - We cannot do this in the button press handler because at that point we don't know yet
// wheter we're going into freehand mode or not
this->ps.push_back(this->p[0]);
+ this->pps.push_back(this->p[0]);
+ double pressure_computed = pow(this->pressure,3);
+ this->wps.push_back(pressure_computed);
}
this->_addFreehandPoint(p, mevent.state);
ret = true;
@@ -400,6 +424,9 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
spdc_concat_colors_and_flush(this, FALSE);
this->sa = NULL;
this->ea = NULL;
+ this->ps.clear();
+ this->wps.clear();
+ this->pps.clear();
if (this->green_anchor) {
this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
@@ -608,7 +635,43 @@ void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) {
if ( ( p != this->p[ this->npoints - 1 ] )
&& in_svg_plane(p) )
{
+
+ this->p[this->npoints++] = p;
+ this->_fitAndSplit();
+ SPCurve *c;
+ if (sa) {
+ c = sa->curve;
+ if (!green_curve->is_empty()) {
+ c->append_continuous( green_curve, 0.0625);
+ }
+ } else {
+ if (!green_curve->is_empty()) {
+ c = green_curve;
+ } else {
+ c = new SPCurve();
+ }
+ }
+ if (red_curve_is_valid && !red_curve->is_empty()) {
+ c->append_continuous(red_curve, 0.0625);
+ }
+ Geom::PathVector pathvector = c->get_pathvector();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double pressure = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3 ? this->pressure :1;
this->ps.push_back(p);
+ double pressure_computed = pow(this->pressure, 3) * 25;
+// std::cout << previous_pressure <<"previous_pressure\n";
+// std::cout << pressure_computed <<"pressure_computed\n";
+// std::cout << std::abs(previous_pressure - pressure_computed) <<"std::abs(previous_pressure - pressure_computed)\n";
+// std::cout << gap_pressure <<"gap_pressure\n";
+// std::cout << Geom::distance(this->pps[this->pps.size()-1], p) << "distance\n";
+
+ if (previous_pressure == 0.0 ||
+ std::abs(previous_pressure - pressure_computed) > gap_pressure )
+ {
+ previous_pressure = pressure_computed;
+ this->pps.push_back(p);
+ this->wps.push_back(pressure_computed);
+ }
this->p[this->npoints++] = p;
this->_fitAndSplit();
}
@@ -690,8 +753,7 @@ void PencilTool::_interpolate() {
: Geom::unit_vector(req_vec) );
}
}
-
- this->ps.clear();
+ //this->ps = b;
}
@@ -786,6 +848,8 @@ void PencilTool::_sketchInterpolate() {
}
this->ps.clear();
+ this->pps.clear();
+ this->wps.clear();
}
void PencilTool::_fitAndSplit() {
diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h
index e8d156dbd..b6e9680d2 100644
--- a/src/ui/tools/pencil-tool.h
+++ b/src/ui/tools/pencil-tool.h
@@ -11,8 +11,12 @@
#include <2geom/d2.h>
#include <2geom/sbasis.h>
-#define SP_PENCIL_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::PencilTool*>((ToolBase*)obj))
-#define SP_IS_PENCIL_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::PencilTool*>((const ToolBase*)obj) != NULL)
+
+#define DDC_MIN_PRESSURE 0.0
+#define DDC_MAX_PRESSURE 1.0
+#define DDC_DEFAULT_PRESSURE 1.0
+#define SP_PENCIL_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::PencilTool*>((Inkscape::UI::Tools::ToolBase*)obj))
+#define SP_IS_PENCIL_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::PencilTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)
namespace Inkscape {
namespace UI {
@@ -30,8 +34,8 @@ enum PencilState {
*/
class PencilTool : public FreehandBase {
public:
- PencilTool();
- virtual ~PencilTool();
+ PencilTool();
+ virtual ~PencilTool();
Geom::Point p[16];
gint npoints;
@@ -41,35 +45,43 @@ public:
bool is_drawing;
std::vector<Geom::Point> ps;
+ std::vector<Geom::Point> pps;
+ std::vector<double> wps;
+ double previous_pressure;
+ double gap_pressure;
+ double min_distance;
+ double start_clamp;
+ double end_clamp;
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;
+ static const std::string prefsPath;
- virtual const std::string& getPrefsPath();
+ virtual const std::string& getPrefsPath();
protected:
- virtual void setup();
- virtual bool root_handler(GdkEvent* event);
+
+ virtual void setup();
+ virtual bool root_handler(GdkEvent* event);
private:
- bool _handleButtonPress(GdkEventButton const &bevent);
- bool _handleMotionNotify(GdkEventMotion const &mevent);
- bool _handleButtonRelease(GdkEventButton const &revent);
- bool _handleKeyPress(GdkEventKey const &event);
- bool _handleKeyRelease(GdkEventKey const &event);
-
- void _setStartpoint(Geom::Point const &p);
- void _setEndpoint(Geom::Point const &p);
- void _finishEndpoint();
- void _addFreehandPoint(Geom::Point const &p, guint state);
- void _fitAndSplit();
- void _interpolate();
- void _sketchInterpolate();
-
- void _cancel();
- void _endpointSnap(Geom::Point &p, guint const state);
+ bool _handleButtonPress(GdkEventButton const &bevent);
+ bool _handleMotionNotify(GdkEventMotion const &mevent);
+ bool _handleButtonRelease(GdkEventButton const &revent);
+ bool _handleKeyPress(GdkEventKey const &event);
+ bool _handleKeyRelease(GdkEventKey const &event);
+
+ void _setStartpoint(Geom::Point const &p);
+ void _setEndpoint(Geom::Point const &p);
+ void _finishEndpoint();
+ void _addFreehandPoint(Geom::Point const &p, guint state);
+ void _fitAndSplit();
+ void _interpolate();
+ void _sketchInterpolate();
+ void _extinput(GdkEvent *event);
+ void _cancel();
+ void _endpointSnap(Geom::Point &p, guint const state);
};
}