60 int width = dab->
bounds().width();
61 int height = dab->
bounds().height();
63 int centerX = width * 0.5;
64 int centerY = height * 0.5;
70 quint8 * dabPointer = dab->
data();
77 for (
int y = 0; y < height; y++) {
78 for (
int x = 0; x < width; x++) {
82 memcpy(bristleColor.
data(), dabPointer, pixelSize);
84 bristle =
new Bristle(x - centerX, y - centerY, alpha);
90 dabPointer += pixelSize;
100 qreal x1 = pi1.
pos().x();
101 qreal y1 = pi1.
pos().y();
103 qreal x2 = pi2.
pos().x();
104 qreal y2 = pi2.
pos().y();
112 qreal angle = rotation;
114 qreal mousePressure = 1.0;
116 qreal
distance = sqrt(dx * dx + dy * dy);
118 scale *= mousePressure;
121 qreal pressure = mousePressure * (pi2.
pressure() * 2);
143 dbgKrita <<
"Can't soak the ink from the layer";
149 qreal fx1, fy1, fx2, fy2;
150 qreal randomX, randomY;
153 float inkDepletion = 0.0;
157 qreal threshold = 1.0 - pi2.
pressure();
158 for (
int i = 0; i < bristleCount; i++) {
176 m_transform.map(bristle->x(), bristle->y(), &fx1, &fy1);
178 m_transform.map(bristle->x(), bristle->y(), &fx2, &fy2);
182 fx1 = bristle->prevX();
183 fy1 = bristle->prevY();
184 m_transform.map(bristle->x(), bristle->y(), &fx2, &fy2);
187 bristle->setPrevX(fx2);
188 bristle->setPrevY(fy2);
204 bristlePathSize -= 1;
208 for (
int i = 0; i < bristlePathSize ; i++) {
229 bristle->setInkAmount(1.0 - inkDepletion);
230 bristle->upIncrement();
241 if (bristle->
counter() >= inkDepletionSize - 1) {
266 (1.0 - inkDepletion)) - 1.0;
307 int ix = qRound(pos.x());
308 int iy = qRound(pos.y());
324 int ipx = int (pos.x());
325 int ipy = int (pos.y());
326 qreal fx = qAbs(pos.x() - ipx);
327 qreal fy = qAbs(pos.y() - ipy);
329 quint8 btl = qRound((1.0 - fx) * (1.0 - fy) * opacity);
330 quint8 btr = qRound((fx) * (1.0 - fy) * opacity);
331 quint8 bbl = qRound((1.0 - fx) * (fy) * opacity);
332 quint8 bbr = qRound((fx) * (fy) * opacity);
363 int ipx = int (pos.x());
364 int ipy = int (pos.y());
365 qreal fx = qAbs(pos.x() - ipx);
366 qreal fy = qAbs(pos.y() - ipy);
368 quint8 btl = qRound((1.0 - fx) * (1.0 - fy) * opacity);
369 quint8 btr = qRound((fx) * (1.0 - fy) * opacity);
370 quint8 bbl = qRound((1.0 - fx) * (fy) * opacity);
371 quint8 bbr = qRound((fx) * (fy) * opacity);
403 static const double scale = 20.0;
404 static const double minPressure = 0.02;
408 double factor = 1.0 -
distance / scale;
409 if (factor < 0.0) factor = 0.0;
411 double result = ((4.0 * oldPressure) + minPressure + factor) / 5.0;
425 for (
int i = 0; i < size; i++) {
427 int x = qRound(b->x() + point.x());
428 int y = qRound(b->y() + point.y());
431 b->setColor(bristleColor);
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
const quint8 OPACITY_TRANSPARENT_U8
const qreal OPACITY_OPAQUE_F
const quint8 OPACITY_OPAQUE_U8
const QString COMPOSITE_OVER
qreal distance(const QPointF &p1, const QPointF &p2)
void setColor(const KoColor &color)
QHash< QString, QVariant > m_params
void paintParticle(QPointF pos, const KoColor &color, qreal weight)
paint wu particle by copying the color and setup just the opacity, weight is complementary to opacity...
const KoCompositeOp * m_compositeOp
QVector< Bristle * > m_bristles
void plotPixel(int wx, int wy, const KoColor &color)
composite single pixel to dab
void opacityDepletion(Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
simulate running out of ink through opacity decreasing
const KisHairyProperties * m_properties
void saturationDepletion(Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
simulate running out of saturation
KoColorTransformation * m_transfo
void colorifyBristles(KisPaintDeviceSP source, QPointF point)
similar to sample input color in spray
void addBristleInk(Bristle *bristle, const QPointF &pos, const KoColor &color)
paints single bristle
double computeMousePressure(double distance)
compute mouse pressure according distance
void darkenPixel(int wx, int wy, const KoColor &color)
check the opacity of dab pixel and if the opacity is less than color, it will copy color to dab
void fromDabWithDensity(KisFixedPaintDeviceSP dab, qreal density)
set the shape of the bristles according the dab
KisRandomAccessorSP m_dabAccessor
void paintLine(KisPaintDeviceSP dab, KisPaintDeviceSP layer, const KisPaintInformation &pi1, const KisPaintInformation &pi2, qreal scale, qreal rotation)
qreal fetchInkDepletion(Bristle *bristle, int inkDepletionSize)
fetch actual ink status according depletion curve
virtual quint8 * rawData()=0
void sampleOldColor(typename Traits::coord_type x, typename Traits::coord_type y, quint8 *dst)
quint32 pixelSize() const
const KoColorSpace * colorSpace() const
quint8 bristleInkAmountWeight
quint8 inkDepletionWeight
quint8 bristleLengthWeight
QVector< qreal > inkDepletionCurve
const KoColorSpace * colorSpace() const
KisRandomAccessorSP createRandomAccessorNG()
virtual void moveTo(qint32 x, qint32 y)=0
qreal generateNormalized() const
virtual quint32 pixelSize() const =0
virtual qreal opacityF(const quint8 *pixel) const =0
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
KoColorTransformation * createColorTransformation(const QString &id, const QHash< QString, QVariant > ¶meters) const
const KoCompositeOp * compositeOp(const QString &id, const KoColorSpace *srcSpace=nullptr) const
void setOpacity(quint8 alpha)
const QVector< QPointF > & getLinearTrajectory(const QPointF &start, const QPointF &end, double space)
constexpr const T & kisBoundFast(const T &min, const T &val, const T &max)
void composite(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, float opacity, const QBitArray &channelFlags=QBitArray()) const