summaryrefslogtreecommitdiffstats
path: root/src/ui/tools/pencil-tool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tools/pencil-tool.cpp')
-rw-r--r--src/ui/tools/pencil-tool.cpp166
1 files changed, 96 insertions, 70 deletions
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 1e1650d44..1d0646cc2 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -211,7 +211,12 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
}
if (anchor) {
p = anchor->dp;
- this->overwrite_curve = anchor->curve;
+ //Put the start overwrite curve always on the same direction
+ if (anchor->start) {
+ this->sa_overwrited = anchor->curve->create_reverse();
+ } else {
+ this->sa_overwrited = anchor->curve->copy();
+ }
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path"));
} else {
m.setup(desktop, true);
@@ -282,18 +287,28 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
// (indicating they intend to move the object, not click), then always process the
// motion notify coordinates as given (no snapping back to origin)
if (input_has_pressure && pencil_within_tolerance) {
- p = desktop->w2d(pencil_drag_origin_w);
anchor = spdc_test_inside(this, pencil_drag_origin_w);
+ if (anchor) {
+ this->sa = anchor;
+ //Put the start overwrite curve always on the same direction
+ if (anchor->start) {
+ this->sa_overwrited = this->sa->curve->create_reverse();
+ } else {
+ this->sa_overwrited = this->sa->curve->copy();
+ }
+ p = anchor->dp;
+ this->_setStartpoint(p);
+ desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path"));
+ }
}
+ if (input_has_pressure) {
+ this->state = SP_PENCIL_CONTEXT_FREEHAND;
+ }
pencil_within_tolerance = false;
switch (this->state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Set red endpoint */
- if (input_has_pressure) {
- this->state = SP_PENCIL_CONTEXT_FREEHAND;
- return false;
- }
if (anchor) {
p = anchor->dp;
} else {
@@ -317,7 +332,6 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
this->green_anchor = sp_draw_anchor_new(this, this->green_curve, TRUE, this->p[0]);
}
if (anchor) {
- std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl;
p = anchor->dp;
}
if ( this->npoints != 0) { // buttonpress may have happened before we entered draw context!
@@ -745,6 +759,36 @@ PencilTool::removePowerStrokePreview()
_powerpreview = NULL;
}
}
+
+void PencilTool::_startAnchorToCurve() {
+ if (!this->sa_overwrited->is_unset()) {
+ Geom::Point A(0,0);
+ Geom::Point B(0,0);
+ Geom::Point C(0,0);
+ Geom::Point D(0,0);
+ Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>( this->sa_overwrited->last_segment() );
+ //We obtain the last segment 4 points in the previous curve
+ if ( cubic && !this->green_curve->is_unset()){
+ A = (*cubic)[0];
+ B = (*cubic)[1];
+ C = *this->green_curve->last_point() + (1./3.)*(this->green_curve->last_segment()->initialPoint() - *this->green_curve->last_point());
+ D = (*cubic)[3];
+ SPCurve *previous = new SPCurve();
+ previous->moveto(A);
+ previous->curveto(B, C, D);
+ if ( this->sa_overwrited->get_segment_count() == 1) {
+ this->sa_overwrited = previous->copy();
+ } else {
+ //we eliminate the last segment
+ this->sa_overwrited->backspace();
+ //and we add it again with the recreation
+ this->sa_overwrited->append_continuous(previous->copy(), 0.0625);
+ }
+ previous->unref();
+ }
+ }
+}
+
void
PencilTool::addPowerStrokePencil(SPCurve * c)
{
@@ -759,7 +803,7 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
min = max;
}
bool live = false;
- SPCurve * curve;
+ SPCurve * curve = new SPCurve();
if (sa) {
Effect* lpe = SP_LPE_ITEM(white_item)->getCurrentLPE();
LPEPowerStroke* ps = static_cast<LPEPowerStroke*>(lpe);
@@ -770,6 +814,7 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
this->points = ps->offset_points.data();
}
}
+ //_startAnchorToCurve();
}
if(!c) {
live = true;
@@ -785,40 +830,25 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
stroreps.clear();
strorewps.clear();
prefs->setDouble("/tools/freehand/pencil/tolerance", tol);
- if (sa) {
- curve = sa->curve;
- if(prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 1 ||
- prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 2)
- {
- curve = overwrite_curve;
- }
- if (sa->start) {
- SPCurve *ret = curve->create_reverse();
- curve->unref();
- curve = ret->copy();
- ret->unref();
- }
- if (!green_curve->is_empty()) {
- if (curve->is_empty()) {
- curve = green_curve->copy();
- } else {
- green_curve->move_endpoints(curve->first_path()->finalPoint(), green_curve->first_path()->finalPoint());
- curve->append_continuous( green_curve, 0.0625);
- }
+ if (sa && sa->curve) {
+ curve = sa_overwrited->copy();
+ if (!green_curve->is_unset()) {
+ curve->append_continuous( green_curve, 0.0625);
if (!red_curve->is_empty()) {
curve->append_continuous( red_curve, 0.0625);
}
}
} else {
- if (!green_curve->is_empty()) {
+ if (!green_curve->is_unset()) {
curve = green_curve->copy();
if (!red_curve->is_empty()) {
curve->append_continuous( red_curve, 0.0625);
}
- } else {
- curve = NULL;
}
}
+ if (curve->is_empty()) {
+ curve = NULL;
+ }
red_curve = previous_red->copy();
green_curve = previous_green->copy();
previous_red->unref();
@@ -844,28 +874,24 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
bool start = true;
auto pressure = this->wps.begin();
size_t counter = 0;
- Geom::Point position = *this->ps.begin();
- if (!live) {
- position *= transformCoordinate.inverse();
- }
- double pos = Geom::nearest_time(position, path);
for (auto point = this->ps.begin(); point != this->ps.end(); ++point, ++pressure) {
counter++;
double pressure_shrunk = (*pressure * (max - min)) + min;
//We need half width for power stroke
pressure_computed = pressure_shrunk * dezoomify_factor/2.0;
//remove start pressure gap
+ Geom::Point position = *point;
+ if (!live) {
+ position *= transformCoordinate.inverse();
+ }
+ double pos = Geom::nearest_time(position, path);
if (start) {
start = false;
this->points.push_back(Geom::Point(pos + 0.01, pressure_computed));
previous_pressure = pressure_shrunk;
continue;
}
- position = *point;
- if (!live) {
- position *= transformCoordinate.inverse();
- }
- pos = Geom::nearest_time(position, path);
+
if (pos < 1e6 && std::abs(previous_pressure - pressure_shrunk) > gap_pressure && pos < path.size() - 1) {
previous_pressure = pressure_shrunk;
this->points.push_back(Geom::Point(pos, pressure_computed));
@@ -959,27 +985,27 @@ void PencilTool::_interpolate(bool realize) {
- if (realize && this->ps.size() > 3) {
- Geom::Point start_point = *this->ps.begin();
- while ( this->ps.size() > 6 && Geom::distance(*(this->ps.begin()+1), start_point) < smoothlenght) {
- this->ps.erase(this->ps.begin() + 1);
- this->wps.erase(this->wps.begin() + 1);
- }
- }
- //Smooth last segments
- if (realize && this->ps.size() > 3) {
- Geom::Point last_point = *this->ps.end();
- bool erased = false;
- while ( this->ps.size() > 6 && Geom::distance(*this->ps.end(), last_point) < smoothlenght) {
- this->ps.pop_back();
- this->wps.pop_back();
- erased = true;
- }
- if (erased) {
- this->wps.push_back(this->wps[this->wps.size()-1]);
- this->ps.push_back(last_point);
- }
- }
+// if (realize && this->ps.size() > 3) {
+// Geom::Point start_point = *this->ps.begin();
+// while ( this->ps.size() > 6 && Geom::distance(*(this->ps.begin()+1), start_point) < smoothlenght) {
+// this->ps.erase(this->ps.begin() + 1);
+// this->wps.erase(this->wps.begin() + 1);
+// }
+// }
+// //Smooth last segments
+// if (realize && this->ps.size() > 3) {
+// Geom::Point last_point = *this->ps.end();
+// bool erased = false;
+// while ( this->ps.size() > 6 && Geom::distance(*this->ps.end(), last_point) < smoothlenght) {
+// this->ps.pop_back();
+// this->wps.pop_back();
+// erased = true;
+// }
+// if (erased) {
+// this->wps.push_back(this->wps[this->wps.size()-1]);
+// this->ps.push_back(last_point);
+// }
+// }
}
double tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2);
@@ -1002,7 +1028,7 @@ void PencilTool::_interpolate(bool realize) {
if (n_segs > 0) {
/* Fit and draw and reset state */
- this->green_curve->moveto(b[0]);
+ this->green_curve->moveto(this->ps[0]);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
for (int c = 0; c < n_segs; c++) {
@@ -1014,14 +1040,14 @@ void PencilTool::_interpolate(bool realize) {
point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
this->green_curve->curveto(point_at1,point_at2,b[4*c+3]);
} else {
- //force retracted handle at end if power stroke
- if (c == n_segs - 1 && input_has_pressure) {
- this->green_curve->curveto(b[4 * c + 1], b[4 * c + 3], b[4 * c + 3]);
- } else if (c == 0 && input_has_pressure) {
- this->green_curve->curveto(b[4 * c], b[4 * c + 2], b[4 * c + 3]);
- } else {
+// //force retracted handle at end if power stroke
+// if (c == n_segs - 1 && input_has_pressure) {
+// this->green_curve->curveto(b[4 * c + 1], b[4 * c + 3], b[4 * c + 3]);
+// } else if (c == 0 && input_has_pressure && !this->sa) {
+// this->green_curve->curveto(b[4 * c], b[4 * c + 2], b[4 * c + 3]);
+// } else {
this->green_curve->curveto(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
- }
+ // }
}
}
if (!input_has_pressure) {