diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h index fd6bb57bb..e66406433 100644 --- a/src/app/tools/controllers.h +++ b/src/app/tools/controllers.h @@ -75,6 +75,10 @@ public: output.addPoint(input[0]); } else if (input.size() >= 2) { + // The freehand controller returns only the last two points to + // interwine because we accumulate (TracePolicy::Accumulate) the + // previously painted points (i.e. don't want to redraw all the + // stroke from the very beginning) output.addPoint(input[input.size()-2]); output.addPoint(input[input.size()-1]); } diff --git a/src/app/tools/intertwiners.h b/src/app/tools/intertwiners.h index a21575703..5336fca05 100644 --- a/src/app/tools/intertwiners.h +++ b/src/app/tools/intertwiners.h @@ -73,14 +73,20 @@ class IntertwineAsLines : public Intertwine { // user confirms a line draw while he is holding down the SHIFT key), so // we have to ignore printing the first pixel of the line. bool m_retainedTracePolicyLast = false; - Stroke m_pts; + + // In freehand-like tools, on each mouse movement we draw only the + // line between the last two mouse points in the stroke (the + // complete stroke is not re-painted again), so we want to indicate + // if this is the first stroke of all (the only one that needs the + // first pixel of the line algorithm) + bool m_firstStroke = true; public: bool snapByAngle() override { return true; } void prepareIntertwine() override { - m_pts.reset(); m_retainedTracePolicyLast = false; + m_firstStroke = true; } void joinStroke(ToolLoop* loop, const Stroke& stroke) override { @@ -89,41 +95,35 @@ public: // new joinStroke() is like a fresh start. Without this fix, the // first stage on LineFreehand will draw a "star" like pattern // with lines from the first point to the last point. - if (loop->getTracePolicy() == TracePolicy::Last) { + if (loop->getTracePolicy() == TracePolicy::Last) m_retainedTracePolicyLast = true; - m_pts.reset(); - } if (stroke.size() == 0) return; else if (stroke.size() == 1) { - if (m_pts.empty()) - m_pts = stroke; doPointshapePoint(stroke[0].x, stroke[0].y, loop); - return; } else { + Stroke pts; doc::AlgoLineWithAlgoPixel lineAlgo = getLineAlgo(loop); for (int c=0; c+1getController()->isFreehand() && - !loop->getFilled() && - m_retainedTracePolicyLast ? 1: 0); + (m_retainedTracePolicyLast || !m_firstStroke) ? 1: 0); - for (int c=start; cvalidateDstImage(gfx::Region(m_toolLoop->getDstImage()->bounds())); } } - else if (m_toolLoop->getBrush()->type() == kImageBrushType) { - m_toolLoop->invalidateDstImage(); - m_toolLoop->validateDstImage(gfx::Region(m_toolLoop->getDstImage()->bounds())); - } m_toolLoop->validateDstImage(m_dirtyArea);