Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_marker_painter.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <KoColor.h>
10#include <KoColorSpace.h>
11
12#include "kis_paint_device.h"
13
14#include "kis_algebra_2d.h"
16
17
19{
20 Private(KisPaintDeviceSP _device, const KoColor &_color) : device(_device), color(_color) {}
21
23 const KoColor &color;
24};
25
27 : m_d(new Private(device, color))
28{
29}
30
34
35
36
38{
39 if (number < -ValidNumberRangeValue || number > ValidNumberRangeValue)
40 return false;
41 return true;
42}
43
45{
46 return isNumberInValidRange(rect.x())
48 && isNumberInValidRange(rect.width())
49 && isNumberInValidRange(rect.height());
50}
51
52void KisMarkerPainter::fillHalfBrushDiff(const QPointF &p1, const QPointF &p2, const QPointF &p3,
53 const QPointF &center, qreal radius)
54{
55 KoColor currentColor(m_d->color);
56
57 const int pixelSize = m_d->device->pixelSize();
58 const KoColorSpace *cs = m_d->device->colorSpace();
59
60 const qreal fadedRadius = radius + 1;
61 QRectF boundRect(center.x() - fadedRadius, center.y() - fadedRadius,
62 2 * fadedRadius, 2 * fadedRadius);
63
66 KisAlgebra2D::OuterCircle outer(center, radius);
67
68 boundRect = KisAlgebra2D::cutOffRect(boundRect, plane1);
69 boundRect = KisAlgebra2D::cutOffRect(boundRect, plane2);
70
71 QRect alignedRect = boundRect.toAlignedRect();
72
74
75 KisSequentialIterator it(m_d->device, alignedRect);
76
77 while (it.nextPixel()) {
78 QPoint pt(it.x(), it.y());
79
80 qreal value1 = plane1.value(pt);
81 if (value1 < 0) continue;
82
83 qreal value2 = plane2.value(pt);
84 if (value2 < 0) continue;
85
86 qreal value3 = outer.fadeSq(pt);
87 if (value3 > 1.0) continue;
88
89 // qreal fadePos =
90 // value1 < 0 || value2 < 0 ?
91 // qMax(-value1, -value2) : value3;
92 qreal fadePos = value3;
93
94 const quint8 srcAlpha = fadePos > 0 ? quint8((1.0 - fadePos) * 255.0) : 255;
95 const quint8 dstAlpha = cs->opacityU8(it.rawData());
96
97 if (srcAlpha > dstAlpha) {
98 currentColor.setOpacity(srcAlpha);
99 memcpy(it.rawData(), currentColor.data(), pixelSize);
100 }
101 }
102}
103
104void KisMarkerPainter::fillFullCircle(const QPointF &center, qreal radius)
105{
106 KoColor currentColor(m_d->color);
107
108 const int pixelSize = m_d->device->pixelSize();
109 const KoColorSpace *cs = m_d->device->colorSpace();
110
111 const qreal fadedRadius = radius + 1;
112 QRectF boundRect(center.x() - fadedRadius, center.y() - fadedRadius,
113 2 * fadedRadius, 2 * fadedRadius);
114
115 KisAlgebra2D::OuterCircle outer(center, radius);
116
117 QRect alignedRect = boundRect.toAlignedRect();
118
120
121 KisSequentialIterator it(m_d->device, alignedRect);
122 while (it.nextPixel()) {
123 QPoint pt(it.x(), it.y());
124
125 qreal value3 = outer.fadeSq(pt);
126 if (value3 > 1.0) continue;
127
128 const quint8 srcAlpha = value3 > 0 ? quint8((1.0 - value3) * 255.0) : 255;
129 const quint8 dstAlpha = cs->opacityU8(it.rawData());
130
131 if (srcAlpha > dstAlpha) {
132 currentColor.setOpacity(srcAlpha);
133 memcpy(it.rawData(), currentColor.data(), pixelSize);
134 }
135 }
136}
137
138void KisMarkerPainter::fillCirclesDiff(const QPointF &c1, qreal r1,
139 const QPointF &c2, qreal r2)
140{
142
143 if (n.size() < 2) {
144 fillFullCircle(c2, r2);
145 } else {
146 const QPointF diff = c2 - c1;
147 const qreal normDiffInv = 1.0 / KisAlgebra2D::norm(diff);
148 const QPointF direction = diff * normDiffInv;
149 const QPointF p = c1 + r1 * direction;
150 const QPointF q = c2 + r2 * direction;
151
152 fillHalfBrushDiff(n[0], p, q, c2, r2);
153 fillHalfBrushDiff(q, p, n[1], c2, r2);
154 }
155}
156
QPointF r2
const Params2D p
QPointF r1
QPointF p2
QPointF p3
QPointF p1
qreal fadeSq(const QPointF &pt) const
qreal value(const QPointF &pt) const
static const qint32 ValidNumberRangeValue
Any number bigger than this or lower than -this is considered invalid.
void fillFullCircle(const QPointF &center, qreal radius)
void fillHalfBrushDiff(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &center, qreal radius)
const QScopedPointer< Private > m_d
bool isRectInValidRange(const QRect &rect)
void fillCirclesDiff(const QPointF &c1, qreal r1, const QPointF &c2, qreal r2)
bool isNumberInValidRange(qint32 number)
KisMarkerPainter(KisPaintDeviceSP device, const KoColor &color)
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE int y() const
virtual quint8 opacityU8(const quint8 *pixel) const =0
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
quint8 * data()
Definition KoColor.h:144
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QVector< QPointF > intersectTwoCircles(const QPointF &center1, qreal r1, const QPointF &center2, qreal r2)
qreal norm(const T &a)
QRectF cutOffRect(const QRectF &rc, const KisAlgebra2D::RightHalfPlane &p)
Private(KisPaintDeviceSP _device, const KoColor &_color)