13#include <QPainterPath>
79 m_path.setFillRule(Qt::WindingFill);
85 Q_FOREACH (
const QRect &
rect, changedRegion.
rects()) {
98 Q_FOREACH (
const QRect &
rect, changedRegion.
rects()) {
107 const qreal fadeFactor = 0.6;
109 QPointF diff = pi2.
pos() - pi1.
pos();
110 qreal realLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
112 if (realLength < 0.1)
return pi2.
pos();
124 Q_UNUSED(currentDistance);
147 const QPointF pos1 = pi1.
pos();
148 QPointF pos2 = pi2.
pos();
154 int length = (pos2 - pos1).manhattanLength();
182 if (
m_path.elementCount() % 16 == 0) {
198 const int timeThreshold = 40;
201 QRect pathBounds =
m_path.boundingRect().toRect();
202 int distanceMetric = qMax(pathBounds.width(), pathBounds.height());
204 if (elapsedTime > timeThreshold ||
217 const int pathSizeThreshold = 128;
220 if (distanceMetric < pathSizeThreshold) {
224 changedRect.adjust(-1, -1, 1, 1);
226 changedRegion = changedRect.toRect();
263 const QPointF &startPoint,
264 const QPointF &endPoint,
266 qreal distanceThreshold,
269 qreal
length = (endPoint - startPoint).manhattanLength();
271 if (lastSegment ||
length > distanceThreshold) {
273 path.lineTo(startPoint);
282 path.lineTo(endPoint);
291 qreal maxDimension = qMax(
bounds.width(),
bounds.height());
292 return qMax(0.01 * maxDimension, 1.0);
297 QPointF diff =
p1 -
p2;
298 qreal realLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
299 return realLength > 0.5 ?
p1 + diff *
distance / realLength :
p1;
304 QPointF lastPoint = path.currentPosition();
306 QPainterPath newPath;
307 int count = path.elementCount();
308 int curveElementCounter = 0;
312 for (
int i = 0; i < count; i++) {
313 QPainterPath::Element e = path.elementAt(i);
315 case QPainterPath::MoveToElement: {
316 newPath.moveTo(
getAngle(QPointF(e.x, e.y), lastPoint, speed));
319 case QPainterPath::LineToElement: {
320 newPath.lineTo(
getAngle(QPointF(e.x, e.y), lastPoint, speed));
323 case QPainterPath::CurveToElement: {
324 curveElementCounter = 0;
325 endPoint =
getAngle(QPointF(e.x, e.y), lastPoint, speed);
328 case QPainterPath::CurveToDataElement: {
329 curveElementCounter++;
331 if (curveElementCounter == 1) {
332 ctrl1 =
getAngle(QPointF(e.x, e.y), lastPoint, speed);
334 else if (curveElementCounter == 2) {
335 ctrl2 =
getAngle(QPointF(e.x, e.y), lastPoint, speed);
336 newPath.cubicTo(ctrl1, ctrl2, endPoint);
qreal length(const QPointF &vec)
const QString COMPOSITE_COPY
qreal distance(const QPointF &p1, const QPointF &p2)
void paintLine(const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance) override
KisPaintDeviceSP m_originalDevice
KisSpacingInformation paintAt(const KisPaintInformation &info) override
~KisExperimentPaintOp() override
QPointF m_savedSpeedPoint
QVector< QPointF > m_savedPoints
QPainterPath m_lastPaintedPath
KisPainter * m_originalPainter
KisPainter::FillStyle m_fillStyle
QPointF speedCorrectedPosition(const KisPaintInformation &pi1, const KisPaintInformation &pi2)
int m_savedSmoothingDistance
KisExperimentPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image)
QPointF m_savedSmoothingPoint
int m_savedUpdateDistance
static qreal simplifyThreshold(const QRectF &bounds)
KisExperimentOpOptionData m_experimentOption
void paintRegion(const KisRegion &changedRegion)
KisSpacingInformation updateSpacingImpl(const KisPaintInformation &info) const override
static QPointF getAngle(const QPointF &p1, const QPointF &p2, qreal distance)
static QPainterPath applyDisplace(const QPainterPath &path, int speed)
KisPaintDeviceSP createCompositionSourceDevice() const
@ FillStyleForegroundColor
bool hasMirroring() const
void renderDabWithMirroringNonIncremental(QRect rc, KisPaintDeviceSP dab)
void setFillStyle(FillStyle fillStyle)
Set the current style with which to fill.
void fillPainterPath(const QPainterPath &path)
void setPattern(const KoPatternSP pattern)
Set the current pattern.
void setPaintColor(const KoColor &color)
void setAntiAliasPolygonFill(bool antiAliasPolygonFill)
Set whether a polygon's filled area should be anti-aliased or not. The default is true.
void setCompositeOpId(const KoCompositeOp *op)
QRect boundingRect() const
QVector< QRect > rects() const
bool tryMergePoints(QPainterPath &path, const QPointF &startPoint, const QPointF &endPoint, qreal &distance, qreal distanceThreshold, bool lastSegment)
QPainterPath trySimplifyPath(const QPainterPath &path, qreal lengthThreshold)
trySimplifyPath Tries to simplify a QPainterPath
KisRegion splitPath(const QPainterPath &path)
KisRegion splitTriangles(const QPointF ¢er, const QVector< QPointF > &points)
bool isDisplacementEnabled
bool read(const KisPropertiesConfiguration *setting)
ExperimentFillType fillType
KisPaintDeviceSP source() const