21#include "strokeinterpolator.h"
24#include <QPainterPath>
26#include "pointerevent.h"
28StrokeInterpolator::StrokeInterpolator()
37void StrokeInterpolator::reset()
39 mStrokeStarted =
false;
40 pressureQueue.clear();
45 mStabilizerLevel = -1;
48void StrokeInterpolator::setPressure(
float pressure)
50 mTabletPressure = pressure;
53void StrokeInterpolator::pointerPressEvent(
PointerEvent* event)
58 mCurrentPressPixel =
event->viewportPos();
61 mLastPixel = mCurrentPixel =
event->viewportPos();
63 mStrokeStarted =
true;
64 setPressure(
event->pressure());
66 mTabletInUse = mTabletInUse ||
event->isTabletEvent();
69void StrokeInterpolator::pointerMoveEvent(
PointerEvent* event)
72 if (mStabilizerLevel != -1)
74 smoothMousePos(
event->viewportPos());
79 mLastPixel = mCurrentPixel;
80 mCurrentPixel =
event->viewportPos();
81 mLastInterpolated = mCurrentPixel;
83 if(
event->isTabletEvent())
85 setPressure(
event->pressure());
89void StrokeInterpolator::pointerReleaseEvent(
PointerEvent* event)
94 pointerMoveEvent(
event);
97 mStrokeStarted =
false;
98 mTabletInUse = mTabletInUse && !
event->isTabletEvent();
101void StrokeInterpolator::setStabilizerLevel(
int level)
103 mStabilizerLevel = level;
106void StrokeInterpolator::smoothMousePos(
QPointF pos)
111 if (mStabilizerLevel == StabilizationLevel::NONE)
113 mLastPixel = mCurrentPixel;
115 mLastInterpolated = mCurrentPixel;
117 else if (mStabilizerLevel == StabilizationLevel::SIMPLE)
120 smoothPos =
QPointF((pos.
x() + mCurrentPixel.
x()) / 2.0, (pos.
y() + mCurrentPixel.
y()) / 2.0);
121 mLastPixel = mCurrentPixel;
122 mCurrentPixel = smoothPos;
123 mLastInterpolated = mCurrentPixel;
126 while (strokeQueue.size() >= STROKE_QUEUE_LENGTH)
128 strokeQueue.pop_front();
131 strokeQueue.push_back(smoothPos);
133 else if (mStabilizerLevel == StabilizationLevel::STRONG)
135 smoothPos =
QPointF((pos.
x() + mLastInterpolated.
x()) / 2.0, (pos.
y() + mLastInterpolated.
y()) / 2.0);
137 mLastInterpolated = mCurrentPixel;
138 mCurrentPixel = smoothPos;
139 mLastPixel = mLastInterpolated;
156 if (mStabilizerLevel == StabilizationLevel::SIMPLE)
160 pressureQueue.clear();
162 mLastPixel = firstPoint;
164 else if (mStabilizerLevel == StabilizationLevel::STRONG)
168 pressureQueue.clear();
170 const int sampleSize = 5;
171 Q_ASSERT(sampleSize > 0);
174 for (
int i = sampleSize; i > 0; i--)
176 strokeQueue.
enqueue(firstPoint);
180 mLastInterpolated = firstPoint;
186 else if (mStabilizerLevel == StabilizationLevel::NONE)
190 pressureQueue.clear();
192 mLastPixel = firstPoint;
197void StrokeInterpolator::interpolatePoll()
203 strokeQueue.
enqueue(mLastInterpolated);
206void StrokeInterpolator::interpolatePollAndPaint()
209 if (!strokeQueue.isEmpty())
221 if (mStabilizerLevel == StabilizationLevel::SIMPLE)
223 result = tangentInpolOp(result);
226 else if (mStabilizerLevel == StabilizationLevel::STRONG)
231 result = meanInpolOp(result, x, y, pressure);
234 else if (mStabilizerLevel == StabilizationLevel::NONE)
236 result = noInpolOp(result);
243 setPressure(getPressure());
245 points << mLastPixel << mLastPixel << mCurrentPixel << mCurrentPixel;
249 mLastPixel = mCurrentPixel;
256 static const qreal smoothness = 1.f;
257 QLineF line(mLastPixel, mCurrentPixel);
259 qreal scaleFactor = line.length() * 3.f;
261 if (!mHasTangent && scaleFactor > 0.01f)
269 m_previousTangent = (mCurrentPixel - mLastPixel) * smoothness / (3.0 * scaleFactor);
273 if (_line.length() < 2)
275 m_previousTangent =
QPointF(0, 0);
280 QPointF c1 = mLastPixel + m_previousTangent * scaleFactor;
281 QPointF newTangent = (mCurrentPixel - c1) * smoothness / (3.0 * scaleFactor);
283 if (scaleFactor == 0)
295 QPointF c2 = mCurrentPixel - newTangent * scaleFactor;
298 points << mLastPixel << c1 << c2 << mCurrentPixel;
300 m_previousTangent = newTangent;
309 for (
int i = 0; i < strokeQueue.size(); i++)
311 x += strokeQueue[i].x();
312 y += strokeQueue[i].y();
313 pressure += getPressure();
317 x /= strokeQueue.size();
318 y /= strokeQueue.size();
319 pressure /= strokeQueue.size();
322 QPointF mNewInterpolated(x, y);
324 points << mLastPixel << mLastInterpolated << mNewInterpolated << mCurrentPixel;
328 mLastPixel = mNewInterpolated;
333void StrokeInterpolator::interpolateEnd()
337 if (mStabilizerLevel == StabilizationLevel::STRONG)
339 if (!strokeQueue.isEmpty())
345 Q_ASSERT(sampleSize > 0);
346 for (
int i = sampleSize; i > 0; i--)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual bool event(QEvent *e)
void setInterval(int msec)