Krita Source Code Documentation
Loading...
Searching...
No Matches
HairyBrush Class Reference

#include <hairy_brush.h>

Public Member Functions

void fromDabWithDensity (KisFixedPaintDeviceSP dab, qreal density)
 set the shape of the bristles according the dab
 
 HairyBrush ()
 
void paintLine (KisPaintDeviceSP dab, KisPaintDeviceSP layer, const KisPaintInformation &pi1, const KisPaintInformation &pi2, qreal scale, qreal rotation)
 
void setInkColor (const KoColor &color)
 set ink color for the whole bristle shape
 
void setProperties (KisHairyProperties *properties)
 set parameters for the brush engine
 
 ~HairyBrush ()
 

Private Member Functions

void addBristleInk (Bristle *bristle, const QPointF &pos, const KoColor &color)
 paints single bristle
 
void colorifyBristles (KisPaintDeviceSP source, QPointF point)
 similar to sample input color in spray
 
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
 
qreal fetchInkDepletion (Bristle *bristle, int inkDepletionSize)
 fetch actual ink status according depletion curve
 
bool firstStroke () const
 
void initAndCache ()
 
void opacityDepletion (Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
 simulate running out of ink through opacity decreasing
 
void paintParticle (QPointF pos, const KoColor &color)
 paint wu particle using composite operation
 
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 of the color
 
void plotPixel (int wx, int wy, const KoColor &color)
 composite single pixel to dab
 
void repositionBristles (double angle, double slope)
 
void saturationDepletion (Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
 simulate running out of saturation
 

Private Attributes

QVector< Bristle * > m_bristles
 
KoColor m_color
 
const KoCompositeOpm_compositeOp {nullptr}
 
int m_counter {0}
 
KisPaintDeviceSP m_dab
 
KisRandomAccessorSP m_dabAccessor
 
double m_lastAngle {0.0}
 
double m_oldPressure {1.0}
 
QHash< QString, QVariant > m_params
 
quint32 m_pixelSize {0}
 
const KisHairyPropertiesm_properties {nullptr}
 
int m_saturationId {-1}
 
Trajectory m_trajectory
 
KoColorTransformationm_transfo {nullptr}
 
QTransform m_transform
 

Detailed Description

Definition at line 56 of file hairy_brush.h.

Constructor & Destructor Documentation

◆ HairyBrush()

HairyBrush::HairyBrush ( )

Definition at line 28 of file hairy_brush.cpp.

29{
30 m_counter = 0;
31 m_lastAngle = 0.0;
32 m_oldPressure = 1.0f;
33
34 m_saturationId = -1;
35}
double m_oldPressure
double m_lastAngle
int m_saturationId

References m_counter, m_lastAngle, m_oldPressure, and m_saturationId.

◆ ~HairyBrush()

HairyBrush::~HairyBrush ( )

Definition at line 37 of file hairy_brush.cpp.

38{
39 delete m_transfo;
40 qDeleteAll(m_bristles.begin(), m_bristles.end());
41 m_bristles.clear();
42}
QVector< Bristle * > m_bristles
KoColorTransformation * m_transfo

References m_bristles, and m_transfo.

Member Function Documentation

◆ addBristleInk()

void HairyBrush::addBristleInk ( Bristle * bristle,
const QPointF & pos,
const KoColor & color )
inlineprivate

paints single bristle

Definition at line 296 of file hairy_brush.cpp.

297{
298 Q_UNUSED(bristle);
299 if (m_properties->antialias) {
301 paintParticle(pos, color);
302 } else {
303 paintParticle(pos, color, 1.0);
304 }
305 }
306 else {
307 int ix = qRound(pos.x());
308 int iy = qRound(pos.y());
310 plotPixel(ix, iy, color);
311 }
312 else {
313 darkenPixel(ix, iy, color);
314 }
315 }
316}
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...
void plotPixel(int wx, int wy, const KoColor &color)
composite single pixel to dab
const KisHairyProperties * m_properties
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

References KisHairyProperties::antialias, darkenPixel(), m_properties, paintParticle(), plotPixel(), and KisHairyProperties::useCompositing.

◆ colorifyBristles()

void HairyBrush::colorifyBristles ( KisPaintDeviceSP source,
QPointF point )
private

similar to sample input color in spray

Definition at line 418 of file hairy_brush.cpp.

419{
420 KoColor bristleColor(m_dab->colorSpace());
421 KisCrossDeviceColorSamplerInt colorSampler(source, bristleColor);
422
423 Bristle *b = 0;
424 int size = m_bristles.size();
425 for (int i = 0; i < size; i++) {
426 b = m_bristles[i];
427 int x = qRound(b->x() + point.x());
428 int y = qRound(b->y() + point.y());
429
430 colorSampler.sampleOldColor(x, y, bristleColor.data());
431 b->setColor(bristleColor);
432 }
433
434}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisPaintDeviceSP m_dab
const KoColorSpace * colorSpace() const
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisPaintDevice::colorSpace(), KoColor::data(), m_bristles, m_dab, KisCrossDeviceColorSamplerImpl< Traits >::sampleOldColor(), and source().

◆ computeMousePressure()

double HairyBrush::computeMousePressure ( double distance)
private

compute mouse pressure according distance

Definition at line 401 of file hairy_brush.cpp.

402{
403 static const double scale = 20.0;
404 static const double minPressure = 0.02;
405
406 double oldPressure = m_oldPressure;
407
408 double factor = 1.0 - distance / scale;
409 if (factor < 0.0) factor = 0.0;
410
411 double result = ((4.0 * oldPressure) + minPressure + factor) / 5.0;
412
413 m_oldPressure = result;
414 return result;
415}
qreal distance(const QPointF &p1, const QPointF &p2)

References distance(), and m_oldPressure.

◆ darkenPixel()

void HairyBrush::darkenPixel ( int wx,
int wy,
const KoColor & color )
inlineprivate

check the opacity of dab pixel and if the opacity is less than color, it will copy color to dab

Definition at line 393 of file hairy_brush.cpp.

394{
395 m_dabAccessor->moveTo(wx, wy);
397 memcpy(m_dabAccessor->rawData(), color.data(), m_pixelSize);
398 }
399}
KisRandomAccessorSP m_dabAccessor
quint32 m_pixelSize
virtual quint8 * rawData()=0
virtual void moveTo(qint32 x, qint32 y)=0
virtual quint8 opacityU8(const quint8 *pixel) const =0
quint8 * data()
Definition KoColor.h:144
quint8 opacityU8() const
Definition KoColor.cpp:341

References KisPaintDevice::colorSpace(), KoColor::data(), m_dab, m_dabAccessor, m_pixelSize, KisRandomConstAccessorNG::moveTo(), KoColor::opacityU8(), KoColorSpace::opacityU8(), and KisBaseAccessor::rawData().

◆ fetchInkDepletion()

qreal HairyBrush::fetchInkDepletion ( Bristle * bristle,
int inkDepletionSize )
inlineprivate

fetch actual ink status according depletion curve

Definition at line 239 of file hairy_brush.cpp.

240{
241 if (bristle->counter() >= inkDepletionSize - 1) {
242 return m_properties->inkDepletionCurve[inkDepletionSize - 1];
243 } else {
244 return m_properties->inkDepletionCurve[bristle->counter()];
245 }
246}
int counter() const
Definition bristle.h:45
QVector< qreal > inkDepletionCurve
Definition hairy_brush.h:31

References Bristle::counter(), KisHairyProperties::inkDepletionCurve, and m_properties.

◆ firstStroke()

bool HairyBrush::firstStroke ( ) const
inlineprivate

Definition at line 127 of file hairy_brush.h.

127 {
128 return (m_counter == 1);
129 }

References m_counter.

◆ fromDabWithDensity()

void HairyBrush::fromDabWithDensity ( KisFixedPaintDeviceSP dab,
qreal density )

set the shape of the bristles according the dab

Definition at line 58 of file hairy_brush.cpp.

59{
60 int width = dab->bounds().width();
61 int height = dab->bounds().height();
62
63 int centerX = width * 0.5;
64 int centerY = height * 0.5;
65
66 // make mask
67 Bristle * bristle = nullptr;
68 qreal alpha;
69
70 quint8 * dabPointer = dab->data();
71 quint8 pixelSize = dab->pixelSize();
72 const KoColorSpace * cs = dab->colorSpace();
73 KoColor bristleColor(cs);
74
75 KisRandomSource randomSource(0);
76
77 for (int y = 0; y < height; y++) {
78 for (int x = 0; x < width; x++) {
79 alpha = cs->opacityF(dabPointer);
80 if (alpha != 0.0) {
81 if (density == 1.0 || randomSource.generateNormalized() <= density) {
82 memcpy(bristleColor.data(), dabPointer, pixelSize);
83
84 bristle = new Bristle(x - centerX, y - centerY, alpha); // using value from image as length of bristle
85 bristle->setColor(bristleColor);
86
87 m_bristles.append(bristle);
88 }
89 }
90 dabPointer += pixelSize;
91 }
92 }
93}
void setColor(const KoColor &color)
Definition bristle.cpp:49
const KoColorSpace * colorSpace() const
virtual qreal opacityF(const quint8 *pixel) const =0

References KisFixedPaintDevice::bounds(), KisFixedPaintDevice::colorSpace(), KisFixedPaintDevice::data(), KoColor::data(), KisRandomSource::generateNormalized(), m_bristles, KoColorSpace::opacityF(), KisFixedPaintDevice::pixelSize(), and Bristle::setColor().

◆ initAndCache()

void HairyBrush::initAndCache ( )
private

Definition at line 45 of file hairy_brush.cpp.

46{
49
52 if (m_transfo) {
54 }
55 }
56}
const QString COMPOSITE_OVER
QHash< QString, QVariant > m_params
const KoCompositeOp * m_compositeOp
virtual quint32 pixelSize() const =0
KoColorTransformation * createColorTransformation(const QString &id, const QHash< QString, QVariant > &parameters) const
const KoCompositeOp * compositeOp(const QString &id, const KoColorSpace *srcSpace=nullptr) const
virtual int parameterId(const QString &name) const

References KisPaintDevice::colorSpace(), COMPOSITE_OVER, KoColorSpace::compositeOp(), KoColorSpace::createColorTransformation(), m_compositeOp, m_dab, m_params, m_pixelSize, m_properties, m_saturationId, m_transfo, KoColorTransformation::parameterId(), KoColorSpace::pixelSize(), and KisHairyProperties::useSaturation.

◆ opacityDepletion()

void HairyBrush::opacityDepletion ( Bristle * bristle,
KoColor & bristleColor,
qreal pressure,
qreal inkDepletion )
private

simulate running out of ink through opacity decreasing

Definition at line 277 of file hairy_brush.cpp.

278{
279 qreal opacity = OPACITY_OPAQUE_F;
281 opacity = pressure * m_properties->pressureWeight +
284 (1.0 - inkDepletion) * m_properties->inkDepletionWeight;
285 }
286 else {
287 opacity =
288 bristle->length() *
289 bristle->inkAmount();
290 }
291
292 opacity = kisBoundFast(0.0, opacity, 1.0);
293 bristleColor.setOpacity(opacity);
294}
const qreal OPACITY_OPAQUE_F
float length() const
Definition bristle.h:37
float inkAmount() const
Definition bristle.h:53
quint8 bristleInkAmountWeight
Definition hairy_brush.h:46
quint8 inkDepletionWeight
Definition hairy_brush.h:47
quint8 bristleLengthWeight
Definition hairy_brush.h:45
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
constexpr const T & kisBoundFast(const T &min, const T &val, const T &max)
Definition kis_global.h:37

References KisHairyProperties::bristleInkAmountWeight, KisHairyProperties::bristleLengthWeight, Bristle::inkAmount(), KisHairyProperties::inkDepletionWeight, kisBoundFast(), Bristle::length(), m_properties, OPACITY_OPAQUE_F, KisHairyProperties::pressureWeight, KoColor::setOpacity(), and KisHairyProperties::useWeights.

◆ paintLine()

void HairyBrush::paintLine ( KisPaintDeviceSP dab,
KisPaintDeviceSP layer,
const KisPaintInformation & pi1,
const KisPaintInformation & pi2,
qreal scale,
qreal rotation )

Definition at line 96 of file hairy_brush.cpp.

97{
98 m_counter++;
99
100 qreal x1 = pi1.pos().x();
101 qreal y1 = pi1.pos().y();
102
103 qreal x2 = pi2.pos().x();
104 qreal y2 = pi2.pos().y();
105
106 qreal dx = x2 - x1;
107 qreal dy = y2 - y1;
108
109 // TODO:this angle is different from the drawing angle in sensor (info.angle()). The bug is caused probably due to
110 // not computing the drag vector properly in paintBezierLine when smoothing is used
111 //qreal angle = atan2(dy, dx);
112 qreal angle = rotation;
113
114 qreal mousePressure = 1.0;
115 if (m_properties->useMousePressure) { // want pressure from mouse movement
116 qreal distance = sqrt(dx * dx + dy * dy);
117 mousePressure = (1.0 - computeMousePressure(distance));
118 scale *= mousePressure;
119 }
120 // this pressure controls shear and ink depletion
121 qreal pressure = mousePressure * (pi2.pressure() * 2);
122
123 Bristle *bristle = 0;
124 KoColor bristleColor(dab->colorSpace());
125
127
128 m_dab = dab;
129
130 // initialization block
131 if (firstStroke()) {
132 initAndCache();
133 }
134
135 /*If this is first time the brush touches the canvas and
136 we are using soak ink while ink depletion is enabled...*/
139 if (layer) {
140 colorifyBristles(layer, pi1.pos());
141 }
142 else {
143 dbgKrita << "Can't soak the ink from the layer";
144 }
145 }
146
147 KisRandomSourceSP randomSource = pi2.randomSource();
148
149 qreal fx1, fy1, fx2, fy2;
150 qreal randomX, randomY;
151 qreal shear;
152
153 float inkDepletion = 0.0;
154 int inkDepletionSize = m_properties->inkDepletionCurve.size();
155 int bristleCount = m_bristles.size();
156 int bristlePathSize;
157 qreal threshold = 1.0 - pi2.pressure();
158 for (int i = 0; i < bristleCount; i++) {
159
160 if (!m_bristles.at(i)->enabled()) continue;
161 bristle = m_bristles[i];
162
163 randomX = (randomSource->generateNormalized() * 2 - 1.0) * m_properties->randomFactor;
164 randomY = (randomSource->generateNormalized() * 2 - 1.0) * m_properties->randomFactor;
165
166 shear = pressure * m_properties->shearFactor;
167
168 m_transform.reset();
169 m_transform.rotateRadians(-angle);
170 m_transform.scale(scale, scale);
171 m_transform.translate(randomX, randomY);
172 m_transform.shear(shear, shear);
173
175 // transform start dab
176 m_transform.map(bristle->x(), bristle->y(), &fx1, &fy1);
177 // transform end dab
178 m_transform.map(bristle->x(), bristle->y(), &fx2, &fy2);
179 }
180 else {
181 // continue the path of the bristle from the previous position
182 fx1 = bristle->prevX();
183 fy1 = bristle->prevY();
184 m_transform.map(bristle->x(), bristle->y(), &fx2, &fy2);
185 }
186 // remember the end point
187 bristle->setPrevX(fx2);
188 bristle->setPrevY(fy2);
189
190 // all coords relative to device position
191 fx1 += x1;
192 fy1 += y1;
193
194 fx2 += x2;
195 fy2 += y2;
196
197 if (m_properties->threshold && (bristle->length() < threshold)) continue;
198 // paint between first and last dab
199 const QVector<QPointF> bristlePath = m_trajectory.getLinearTrajectory(QPointF(fx1, fy1), QPointF(fx2, fy2), 1.0);
200 bristlePathSize = m_trajectory.size();
201
202 // avoid overlapping bristle caps with antialias on
203 if (m_properties->antialias) {
204 bristlePathSize -= 1;
205 }
206
207 memcpy(bristleColor.data(), bristle->color().data() , m_pixelSize);
208 for (int i = 0; i < bristlePathSize ; i++) {
209
211 inkDepletion = fetchInkDepletion(bristle, inkDepletionSize);
212
213 if (m_properties->useSaturation && m_transfo != 0) {
214 saturationDepletion(bristle, bristleColor, pressure, inkDepletion);
215 }
216
218 opacityDepletion(bristle, bristleColor, pressure, inkDepletion);
219 }
220
221 }
222 else {
223 if (bristleColor.opacityU8() != 0) {
224 bristleColor.setOpacity(bristle->length());
225 }
226 }
227
228 addBristleInk(bristle, bristlePath.at(i), bristleColor);
229 bristle->setInkAmount(1.0 - inkDepletion);
230 bristle->upIncrement();
231 }
232
233 }
234 m_dab = nullptr;
235 m_dabAccessor = nullptr;
236}
bool firstStroke() const
QTransform m_transform
void initAndCache()
void opacityDepletion(Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
simulate running out of ink through opacity decreasing
void saturationDepletion(Bristle *bristle, KoColor &bristleColor, qreal pressure, qreal inkDepletion)
simulate running out of saturation
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
Trajectory m_trajectory
double computeMousePressure(double distance)
compute mouse pressure according distance
qreal fetchInkDepletion(Bristle *bristle, int inkDepletionSize)
fetch actual ink status according depletion curve
KisRandomAccessorSP createRandomAccessorNG()
KisRandomSourceSP randomSource() const
const QPointF & pos() const
qreal pressure() const
The pressure of the value (from 0.0 to 1.0)
qreal generateNormalized() const
const QVector< QPointF > & getLinearTrajectory(const QPointF &start, const QPointF &end, double space)
int size() const
Definition trajectory.h:23
#define dbgKrita
Definition kis_debug.h:45

References addBristleInk(), KisHairyProperties::antialias, colorifyBristles(), KisPaintDevice::colorSpace(), computeMousePressure(), KisHairyProperties::connectedPath, KisPaintDevice::createRandomAccessorNG(), KoColor::data(), dbgKrita, distance(), fetchInkDepletion(), firstStroke(), KisRandomSource::generateNormalized(), Trajectory::getLinearTrajectory(), initAndCache(), KisHairyProperties::inkDepletionCurve, KisHairyProperties::inkDepletionEnabled, m_bristles, m_counter, m_dab, m_dabAccessor, m_pixelSize, m_properties, m_trajectory, m_transfo, m_transform, opacityDepletion(), KoColor::opacityU8(), KisPaintInformation::pos(), KisPaintInformation::pressure(), KisHairyProperties::randomFactor, KisPaintInformation::randomSource(), saturationDepletion(), KoColor::setOpacity(), KisHairyProperties::shearFactor, Trajectory::size(), KisHairyProperties::threshold, KisHairyProperties::useMousePressure, KisHairyProperties::useOpacity, KisHairyProperties::useSaturation, and KisHairyProperties::useSoakInk.

◆ paintParticle() [1/2]

void HairyBrush::paintParticle ( QPointF pos,
const KoColor & color )
private

paint wu particle using composite operation

Definition at line 357 of file hairy_brush.cpp.

358{
359 // opacity top left, right, bottom left, right
360 memcpy(m_color.data(), color.data(), m_pixelSize);
361 quint8 opacity = color.opacityU8();
362
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);
367
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);
372
373 m_color.setOpacity(btl);
374 plotPixel(ipx , ipy, m_color);
375
376 m_color.setOpacity(btr);
377 plotPixel(ipx + 1 , ipy, m_color);
378
379 m_color.setOpacity(bbl);
380 plotPixel(ipx , ipy + 1, m_color);
381
382 m_color.setOpacity(bbr);
383 plotPixel(ipx + 1 , ipy + 1, m_color);
384}
KoColor m_color

References KoColor::data(), m_color, m_pixelSize, KoColor::opacityU8(), plotPixel(), and KoColor::setOpacity().

◆ paintParticle() [2/2]

void HairyBrush::paintParticle ( QPointF pos,
const KoColor & color,
qreal weight )
private

paint wu particle by copying the color and setup just the opacity, weight is complementary to opacity of the color

Definition at line 318 of file hairy_brush.cpp.

319{
320 // opacity top left, right, bottom left, right
321 quint8 opacity = color.opacityU8();
322 opacity *= weight;
323
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);
328
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);
333
334 const KoColorSpace * cs = m_dab->colorSpace();
335
336 m_dabAccessor->moveTo(ipx , ipy);
337 btl = quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, btl + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
338 memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
339 cs->setOpacity(m_dabAccessor->rawData(), btl, 1);
340
341 m_dabAccessor->moveTo(ipx + 1, ipy);
342 btr = quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, btr + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
343 memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
344 cs->setOpacity(m_dabAccessor->rawData(), btr, 1);
345
346 m_dabAccessor->moveTo(ipx, ipy + 1);
347 bbl = quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, bbl + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
348 memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
349 cs->setOpacity(m_dabAccessor->rawData(), bbl, 1);
350
351 m_dabAccessor->moveTo(ipx + 1, ipy + 1);
352 bbr = quint8(kisBoundFast<quint16>(OPACITY_TRANSPARENT_U8, bbr + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
353 memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
354 cs->setOpacity(m_dabAccessor->rawData(), bbr, 1);
355}
const quint8 OPACITY_TRANSPARENT_U8
const quint8 OPACITY_OPAQUE_U8
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0

References KisPaintDevice::colorSpace(), KoColor::data(), m_dab, m_dabAccessor, KisRandomConstAccessorNG::moveTo(), OPACITY_OPAQUE_U8, OPACITY_TRANSPARENT_U8, KoColor::opacityU8(), KoColorSpace::opacityU8(), KoColorSpace::pixelSize(), KisBaseAccessor::rawData(), and KoColorSpace::setOpacity().

◆ plotPixel()

void HairyBrush::plotPixel ( int wx,
int wy,
const KoColor & color )
inlineprivate

composite single pixel to dab

Definition at line 387 of file hairy_brush.cpp.

388{
389 m_dabAccessor->moveTo(wx, wy);
391}
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

References KoCompositeOp::composite(), KoColor::data(), m_compositeOp, m_dabAccessor, m_pixelSize, KisRandomConstAccessorNG::moveTo(), OPACITY_OPAQUE_F, and KisBaseAccessor::rawData().

◆ repositionBristles()

void HairyBrush::repositionBristles ( double angle,
double slope )
private

◆ saturationDepletion()

void HairyBrush::saturationDepletion ( Bristle * bristle,
KoColor & bristleColor,
qreal pressure,
qreal inkDepletion )
private

simulate running out of saturation

Definition at line 249 of file hairy_brush.cpp.

250{
251 qreal saturation;
253 // new weighted way (experiment)
254 saturation = (
255 (pressure * m_properties->pressureWeight) +
256 (bristle->length() * m_properties->bristleLengthWeight) +
258 ((1.0 - inkDepletion) * m_properties->inkDepletionWeight)) - 1.0;
259 }
260 else {
261 // old way of computing saturation
262 saturation = (
263 pressure *
264 bristle->length() *
265 bristle->inkAmount() *
266 (1.0 - inkDepletion)) - 1.0;
267
268 }
272 m_transfo->setParameter(3, 1);//sets the type to
273 m_transfo->setParameter(4, false);//sets the colorize to none.
274 m_transfo->transform(bristleColor.data(), bristleColor.data() , 1);
275}
virtual void setParameter(int id, const QVariant &parameter)
virtual void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const =0

References KisHairyProperties::bristleInkAmountWeight, KisHairyProperties::bristleLengthWeight, KoColor::data(), Bristle::inkAmount(), KisHairyProperties::inkDepletionWeight, Bristle::length(), m_properties, m_saturationId, m_transfo, KoColorTransformation::parameterId(), KisHairyProperties::pressureWeight, KoColorTransformation::setParameter(), KoColorTransformation::transform(), and KisHairyProperties::useWeights.

◆ setInkColor()

void HairyBrush::setInkColor ( const KoColor & color)
inline

set ink color for the whole bristle shape

Definition at line 65 of file hairy_brush.h.

65 {
66 m_color = color;
67 }

References m_color.

◆ setProperties()

void HairyBrush::setProperties ( KisHairyProperties * properties)
inline

set parameters for the brush engine

Definition at line 69 of file hairy_brush.h.

69 {
70 m_properties = properties;
71 }

References m_properties.

Member Data Documentation

◆ m_bristles

QVector<Bristle*> HairyBrush::m_bristles
private

Definition at line 105 of file hairy_brush.h.

◆ m_color

KoColor HairyBrush::m_color
private

Definition at line 121 of file hairy_brush.h.

◆ m_compositeOp

const KoCompositeOp* HairyBrush::m_compositeOp {nullptr}
private

Definition at line 114 of file hairy_brush.h.

114{nullptr};

◆ m_counter

int HairyBrush::m_counter {0}
private

Definition at line 117 of file hairy_brush.h.

117{0};

◆ m_dab

KisPaintDeviceSP HairyBrush::m_dab
private

Definition at line 112 of file hairy_brush.h.

◆ m_dabAccessor

KisRandomAccessorSP HairyBrush::m_dabAccessor
private

Definition at line 113 of file hairy_brush.h.

◆ m_lastAngle

double HairyBrush::m_lastAngle {0.0}
private

Definition at line 119 of file hairy_brush.h.

119{0.0};

◆ m_oldPressure

double HairyBrush::m_oldPressure {1.0}
private

Definition at line 120 of file hairy_brush.h.

120{1.0};

◆ m_params

QHash<QString, QVariant> HairyBrush::m_params
private

Definition at line 110 of file hairy_brush.h.

◆ m_pixelSize

quint32 HairyBrush::m_pixelSize {0}
private

Definition at line 115 of file hairy_brush.h.

115{0};

◆ m_properties

const KisHairyProperties* HairyBrush::m_properties {nullptr}
private

Definition at line 103 of file hairy_brush.h.

103{nullptr};

◆ m_saturationId

int HairyBrush::m_saturationId {-1}
private

Definition at line 123 of file hairy_brush.h.

123{-1};

◆ m_trajectory

Trajectory HairyBrush::m_trajectory
private

Definition at line 109 of file hairy_brush.h.

◆ m_transfo

KoColorTransformation* HairyBrush::m_transfo {nullptr}
private

Definition at line 124 of file hairy_brush.h.

124{nullptr};

◆ m_transform

QTransform HairyBrush::m_transform
private

Definition at line 106 of file hairy_brush.h.


The documentation for this class was generated from the following files: