Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_hairy_paintop.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "kis_hairy_paintop.h"
9
10#include <cmath>
11#include <QRect>
12
13#include <kis_image.h>
14#include <kis_debug.h>
15
16#include "kis_paint_device.h"
17#include "kis_painter.h"
18#include <kis_vec.h>
19
22#include <kis_brush_option.h>
25#include <kis_lod_transform.h>
28
29
30#include "kis_brush.h"
31
33 : KisPaintOp(painter)
34 , m_opacityOption(settings.data(), node)
35 , m_sizeOption(settings.data())
36 , m_rotationOption(settings.data())
37{
38 Q_UNUSED(image);
39 Q_ASSERT(settings);
40
41 m_hairyBristleOption.read(settings.data());
42 m_hairyInkOption.read(settings.data());
43
44 m_dev = node ? node->paintDevice() : 0;
45
46 KisBrushOptionProperties brushOption;
47 brushOption.readOptionSetting(settings, settings->resourcesInterface(), settings->canvasResourcesInterface());
48 KisBrushSP brush = brushOption.brush();
50
51 // properly initialize fake paint information to avoid warnings
52 KisPaintInformation fakePaintInformation;
53 fakePaintInformation.setRandomSource(new KisRandomSource());
54 fakePaintInformation.setPerStrokeRandomSource(new KisPerStrokeRandomSource());
55
56 if (brush->brushApplication() == IMAGESTAMP) {
57 dab = brush->paintDevice(source()->colorSpace(), KisDabShape(), fakePaintInformation);
58 } else {
59 brush->mask(dab, painter->paintColor(), KisDabShape(), fakePaintInformation);
60 }
61
64
67}
68
70{
71 KisBrushOptionProperties brushOption;
72 return brushOption.prepareLinkedResources(settings, resourcesInterface);
73}
74
102
103
108
110{
111 Q_UNUSED(info);
112 return KisSpacingInformation(0.5);
113}
114
115
117{
118 Q_UNUSED(currentDistance);
119 if (!painter()) return;
120
121 if (!m_dab) {
123 }
124 else {
125 m_dab->clear();
126 }
127
133 KisPaintInformation pi(pi2);
135 pi.registerDistanceInformation(currentDistance);
136
137 // Hairy Brush is capable of working with zero scale,
138 // so no additional checks for 'zero'ness are needed
139 qreal scale = m_sizeOption.apply(pi);
140 scale *= KisLodTransform::lodToScale(painter()->device());
141 qreal rotation = m_rotationOption.apply(pi);
143
144 const bool mirrorFlip = pi1.canvasMirroredH() != pi1.canvasMirroredV();
145
146 // we don't use spacing here (the brush itself is used only once
147 // during initialization), so we should just skip the distance info
148 // update
149
150 m_brush.paintLine(m_dab, m_dev, pi1, pi, scale * m_hairyBristleOption.scaleFactor, mirrorFlip ? -rotation : rotation);
151
152 //QRect rc = m_dab->exactBounds();
153 QRect rc = m_dab->extent();
154 painter()->bitBlt(rc.topLeft(), m_dab, rc);
156
157 // we don't use spacing in hairy brush, but history is
158 // still important for us
159 currentDistance->registerPaintedDab(pi,
162}
void setInkColor(const KoColor &color)
set ink color for the whole bristle shape
Definition hairy_brush.h:65
void fromDabWithDensity(KisFixedPaintDeviceSP dab, qreal density)
set the shape of the bristles according the dab
void setProperties(KisHairyProperties *properties)
set parameters for the brush engine
Definition hairy_brush.h:69
void paintLine(KisPaintDeviceSP dab, KisPaintDeviceSP layer, const KisPaintInformation &pi1, const KisPaintInformation &pi2, qreal scale, qreal rotation)
static QList< KoResourceLoadResult > prepareLinkedResources(const KisPaintOpSettingsSP settings, KisResourcesInterfaceSP resourcesInterface)
KisOpacityOption m_opacityOption
KisHairyProperties m_properties
KisSpacingInformation updateSpacingImpl(const KisPaintInformation &info) const override
KisHairyBristleOptionData m_hairyBristleOption
KisPaintDeviceSP m_dev
KisHairyInkOptionData m_hairyInkOption
KisHairyPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image)
KisRotationOption m_rotationOption
KisSpacingInformation paintAt(const KisPaintInformation &info) override
void paintLine(const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance) override
KisSizeOption m_sizeOption
KisPaintDeviceSP m_dab
quint8 bristleInkAmountWeight
Definition hairy_brush.h:46
quint8 inkDepletionWeight
Definition hairy_brush.h:47
quint8 bristleLengthWeight
Definition hairy_brush.h:45
QVector< qreal > inkDepletionCurve
Definition hairy_brush.h:31
static qreal lodToScale(int levelOfDetail)
void apply(KisPainter *painter, const KisPaintInformation &info) const
virtual void clear()
KisPaintDeviceSP createCompositionSourceDevice() const
virtual const KoColorSpace * compositionSourceColorSpace() const
QRect extent() const
void setRandomSource(KisRandomSourceSP value)
DistanceInformationRegistrar registerDistanceInformation(KisDistanceInformation *distance)
void setPerStrokeRandomSource(KisPerStrokeRandomSourceSP value)
KoColor paintColor
void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
KisPaintDeviceSP device
QList< KoResourceLoadResult > prepareLinkedResources(const KisPropertiesConfigurationPointer settings, KisResourcesInterfaceSP resourcesInterface) const
void readOptionSetting(KisPropertiesConfigurationPointer settings, KisResourcesInterfaceSP resourcesInterface, KoCanvasResourcesInterfaceSP canvasResourcesInterface)
qreal apply(const KisPaintInformation &info) const
qreal apply(const KisPaintInformation &info) const
@ IMAGESTAMP
Definition kis_brush.h:40
virtual KisPaintDeviceSP paintDevice() const =0
const QVector< qreal > floatTransfer(int size=256) const
void registerPaintedDab(const KisPaintInformation &info, const KisSpacingInformation &spacing, const KisTimingInformation &timing)
bool read(const KisPropertiesConfiguration *setting)
bool read(const KisPropertiesConfiguration *setting)
KisPainter * painter
KisFixedPaintDeviceSP dab
KisPaintDeviceSP source() const
KisFixedPaintDeviceSP cachedDab()