Krita Source Code Documentation
Loading...
Searching...
No Matches
KisPainter Struct Reference

#include <kis_painter.h>

+ Inheritance diagram for KisPainter:

Public Types

enum  FillStyle {
  FillStyleNone , FillStyleForegroundColor , FillStyleBackgroundColor , FillStylePattern ,
  FillStyleGenerator
}
 This enum contains the styles with which we can fill things like polygons and ellipses. More...
 
enum  StrokeStyle { StrokeStyleNone , StrokeStyleBrush }
 The style of the brush stroke around polygons and so. More...
 

Public Member Functions

void addDirtyRect (const QRect &r)
 
void addDirtyRects (const QVector< QRect > &rects)
 
bool antiAliasPolygonFill ()
 Return whether a polygon's filled area should be anti-aliased or not.
 
void applyDevice (const QRect &applyRect, const KisRenderedDab &dab, KisRandomAccessorSP dstIt, const KoColorSpace *srcColorSpace, KoCompositeOp::ParameterInfo &localParamInfo)
 
void applyDeviceWithSelection (const QRect &applyRect, const KisRenderedDab &dab, KisRandomAccessorSP dstIt, KisRandomConstAccessorSP maskIt, const KoColorSpace *srcColorSpace, KoCompositeOp::ParameterInfo &localParamInfo)
 
const KoColorbackgroundColor () const
 Returns the current background color.
 
void begin (KisPaintDeviceSP device)
 
void begin (KisPaintDeviceSP device, KisSelectionSP selection)
 
void beginTransaction (const KUndo2MagicString &transactionName=KUndo2MagicString(), int timedID=-1)
 Begin an undoable paint operation.
 
void bitBlt (const QPoint &pos, const KisPaintDeviceSP srcDev, const QRect &srcRect)
 
void bitBlt (qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
 
void bitBltOldData (const QPoint &pos, const KisPaintDeviceSP srcDev, const QRect &srcRect)
 
void bitBltOldData (qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
 
void bitBltWithFixedSelection (qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 selX, qint32 selY, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
 
void bitBltWithFixedSelection (qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 srcWidth, qint32 srcHeight)
 
void bltFixed (const QPoint &pos, const KisFixedPaintDeviceSP srcDev, const QRect &srcRect)
 
void bltFixed (const QRect &rc, const QList< KisRenderedDab > allSrcDevices)
 
void bltFixed (qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
 
void bltFixedWithFixedSelection (qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 selX, qint32 selY, qint32 srcX, qint32 srcY, quint32 srcWidth, quint32 srcHeight)
 
void bltFixedWithFixedSelection (qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, quint32 srcWidth, quint32 srcHeight)
 
const QVector< QPair< QPointF, QPointF > > calculateAllMirroredPoints (const QPair< QPointF, QPointF > &pair)
 
const QVector< QPointF > calculateAllMirroredPoints (const QPointF &pos)
 
const QVector< QRect > calculateAllMirroredRects (const QRect &rc)
 
template<class T >
QVector< T > calculateMirroredObjects (const T &object)
 
QBitArray channelFlags ()
 
const KoCompositeOpcompositeOp (const KoColorSpace *srcCS)
 
QString compositeOpId ()
 Returns the current composite op Id.
 
void copyMirrorInformationFrom (const KisPainter *other)
 
void deleteTransaction ()
 
KisPaintDeviceSP device ()
 
const KisPaintDeviceSP device () const
 Returns the current paint device.
 
void drawDDALine (const QPointF &start, const QPointF &end)
 
void drawLine (const QPointF &start, const QPointF &end)
 
void drawLine (const QPointF &start, const QPointF &end, qreal width, bool antialias)
 
void drawPainterPath (const QPainterPath &path, const QPen &pen)
 
void drawPainterPath (const QPainterPath &path, const QPen &pen, const QRect &requestedRect)
 
void drawThickLine (const QPointF &start, const QPointF &end, int startWidth, int endWidth)
 
void drawWobblyLine (const QPointF &start, const QPointF &end)
 
void drawWuLine (const QPointF &start, const QPointF &end)
 
void end ()
 
KUndo2CommandendAndTakeTransaction ()
 
void endTransaction (KisPostExecutionUndoAdapter *undoAdapter)
 
void endTransaction (KisUndoAdapter *undoAdapter)
 Finish the undoable paint operation.
 
void fill (qint32 x, qint32 y, qint32 width, qint32 height, const KoColor &color)
 
void fillPainterPath (const QPainterPath &path)
 
void fillPainterPath (const QPainterPath &path, const QRect &requestedRect)
 
void fillPainterPathImpl (const QPainterPath &path, const QRect &requestedRect)
 
FillStyle fillStyle () const
 Returns the current fill style.
 
qreal flow () const
 
const KisFilterConfigurationSP generator () const
 
void getBezierCurvePoints (const QPointF &pos1, const QPointF &control1, const QPointF &control2, const QPointF &pos2, vQPointF &points) const
 
const KoAbstractGradientSP gradient () const
 
bool hasDirtyRegion () const
 
bool hasHorizontalMirroring () const
 
bool hasMirroring () const
 
bool hasVerticalMirroring () const
 
bool isOpacityUnit () const
 
 KisPainter ()
 Construct painter without a device.
 
 KisPainter (KisPaintDeviceSP device)
 Construct a painter, and begin painting on the device.
 
 KisPainter (KisPaintDeviceSP device, KisSelectionSP selection)
 Construct a painter, and begin painting on the device. All actions will be masked by the given selection.
 
void mirrorDab (Qt::Orientation direction, KisRenderedDab *dab, bool skipMirrorPixels=false) const
 
void mirrorRect (Qt::Orientation direction, QRect *rc) const
 
qreal opacityF () const
 Returns the opacity that is used in painting.
 
void paintAt (const KisPaintInformation &pos, KisDistanceInformation *savedDist)
 
void paintBezierCurve (const KisPaintInformation &pi1, const QPointF &control1, const QPointF &control2, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)
 
const KoColorpaintColor () const
 Returns the color that will be used to paint with.
 
void paintEllipse (const qreal x, const qreal y, const qreal w, const qreal h)
 
void paintEllipse (const QRectF &rect)
 
void paintLine (const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)
 
KisPaintOppaintOp () const
 
void paintPainterPath (const QPainterPath &path)
 
void paintPolygon (const vQPointF &points)
 
void paintPolyline (const QVector< QPointF > &points, int index=0, int numPoints=-1)
 
void paintRect (const qreal x, const qreal y, const qreal w, const qreal h)
 
void paintRect (const QRectF &rect)
 
const KoPatternSP pattern () const
 Returns the currently set pattern.
 
QTransform patternTransform ()
 get the current transform on the pattern.
 
KisPaintOpPresetSP preset () const
 Return the paintop preset.
 
 Private (KisPainter *_q)
 
 Private (KisPainter *_q, const KoColorSpace *cs)
 
void putTransaction (KisTransaction *transaction)
 continue a transaction started somewhere else
 
void renderDabWithMirroringNonIncremental (QRect rc, KisPaintDeviceSP dab)
 
void renderMirrorMask (QRect rc, KisFixedPaintDeviceSP dab)
 
void renderMirrorMask (QRect rc, KisFixedPaintDeviceSP dab, KisFixedPaintDeviceSP mask)
 
void renderMirrorMask (QRect rc, KisPaintDeviceSP dab)
 
void renderMirrorMask (QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask)
 
void renderMirrorMaskSafe (QRect rc, KisFixedPaintDeviceSP dab, bool preserveDab)
 
void renderMirrorMaskSafe (QRect rc, KisFixedPaintDeviceSP dab, KisFixedPaintDeviceSP mask, bool preserveDab)
 
void renderMirrorMaskSafe (QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask, bool preserveMask)
 
void revertTransaction ()
 Cancel all the changes made by the painter.
 
KisRunnableStrokeJobsInterfacerunnableStrokeJobsInterface () const
 
KisSelectionSP selection ()
 
void setAntiAliasPolygonFill (bool antiAliasPolygonFill)
 Set whether a polygon's filled area should be anti-aliased or not. The default is true.
 
void setAverageOpacity (qreal averageOpacity)
 
void setBackgroundColor (const KoColor &color)
 
void setChannelFlags (QBitArray channelFlags)
 
void setColorConversionFlags (KoColorConversionTransformation::ConversionFlags conversionFlags)
 
void setCompositeOpId (const KoCompositeOp *op)
 
void setCompositeOpId (const QString &op)
 Set the composite op for this painter by string.
 
void setFillStyle (FillStyle fillStyle)
 Set the current style with which to fill.
 
void setFlow (qreal flow)
 
void setGenerator (KisFilterConfigurationSP generator)
 Set the current generator (a generator can be used to fill an area.
 
void setGradient (const KoAbstractGradientSP gradient)
 
void setMaskImageSize (qint32 width, qint32 height)
 
void setMirrorInformation (const QPointF &axesCenter, bool mirrorHorizontally, bool mirrorVertically)
 
void setOpacityF (qreal opacity)
 
void setOpacityToUnit ()
 
void setOpacityU8 (quint8 opacity)
 Set the opacity which is used in painting (like filling polygons)
 
void setOpacityUpdateAverage (qreal opacity)
 
void setPaintColor (const KoColor &color)
 
void setPaintOpPreset (KisPaintOpPresetSP preset, KisNodeSP node, KisImageSP image)
 
void setPattern (const KoPatternSP pattern)
 Set the current pattern.
 
void setPatternTransform (QTransform transform)
 Set the transform on the pattern.
 
void setProgress (KoUpdater *progressUpdater)
 
void setRenderingIntent (KoColorConversionTransformation::Intent intent)
 
void setRunnableStrokeJobsInterface (KisRunnableStrokeJobsInterface *interface)
 
void setSelection (KisSelectionSP selection)
 
void setStrokeStyle (StrokeStyle strokeStyle)
 Set the current brush stroke style.
 
StrokeStyle strokeStyle () const
 Returns the current brush stroke style.
 
QVector< QRect > takeDirtyRegion ()
 
KisTransactiontakeTransaction ()
 take transaction out of the reach of KisPainter
 
bool tryReduceSourceRect (const KisPaintDevice *srcDev, QRect *srcRect, qint32 *srcX, qint32 *srcY, qint32 *srcWidth, qint32 *srcHeight, qint32 *dstX, qint32 *dstY)
 
virtual ~KisPainter ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Static Public Member Functions

static qreal blendAverageOpacity (qreal opacity, qreal averageOpacity)
 
static bool checkDeviceHasTransparency (KisPaintDeviceSP dev)
 
static KisPaintDeviceSP convertToAlphaAsAlpha (KisPaintDeviceSP src)
 
static KisPaintDeviceSP convertToAlphaAsGray (KisPaintDeviceSP src)
 
static KisPaintDeviceSP convertToAlphaAsPureAlpha (KisPaintDeviceSP src)
 
static void copyAreaOptimized (const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
 
static void copyAreaOptimized (const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect, KisSelectionSP selection)
 
static void copyAreaOptimizedOldData (const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
 

Public Attributes

bool antiAliasPolygonFill {true}
 
QPointF axesCenter
 
KoColor backgroundColor
 
const KoCompositeOpcachedCompositeOp {nullptr}
 
const KoColorSpacecachedSourceColorSpace {nullptr}
 
const KoColorSpacecolorSpace {nullptr}
 
QString compositeOpId
 
KoColorConversionTransformation::ConversionFlags conversionFlags {KoColorConversionTransformation::Empty}
 
KoColor customColor
 
KisPaintDeviceSP device
 
QVector< QRect > dirtyRects
 
QPointF duplicateOffset
 
QScopedPointer< KisRunnableStrokeJobsInterfacefakeRunnableStrokeJobsInterface
 
KisFillPainterfillPainter {nullptr}
 
FillStyle fillStyle {FillStyleNone}
 
KisFilterConfigurationSP generator
 
KoAbstractGradientSP gradient
 
bool isOpacityUnit {true}
 
qint32 maskImageHeight {255}
 
qint32 maskImageWidth {255}
 
QPainter * maskPainter {nullptr}
 
bool mirrorHorizontally {false}
 
bool mirrorVertically {false}
 
KoColor paintColor
 
KisPaintOppaintOp {nullptr}
 
KisPaintOpPresetSP paintOpPreset
 
KoCompositeOp::ParameterInfo paramInfo
 
KoPatternSP pattern
 
QTransform patternTransform
 
quint32 pixelSize {0}
 
KisPaintDeviceSP polygon
 
QImage polygonMaskImage
 
KoColorProfileprofile {nullptr}
 
KoUpdaterprogressUpdater {nullptr}
 
KisPainterq {nullptr}
 
KoColorConversionTransformation::Intent renderingIntent {KoColorConversionTransformation::IntentPerceptual}
 
KisRunnableStrokeJobsInterfacerunnableStrokeJobsInterface {nullptr}
 
KisSelectionSP selection
 
KisPaintLayersourceLayer {nullptr}
 
StrokeStyle strokeStyle {StrokeStyleBrush}
 
KisTransactiontransaction {nullptr}
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Protected Member Functions

void fillPolygon (const vQPointF &points, FillStyle fillStyle)
 Fill the polygon defined by points with the fillStyle.
 
void init ()
 Initialize, set everything to '0' or defaults.
 
KoUpdaterprogressUpdater ()
 

Private Member Functions

template<bool useOldSrcData>
void bitBltImpl (qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
 
void compositeOnePixel (quint8 *dst, const KoColor &color)
 
float frac (float value)
 
float invertFrac (float value)
 
 KisPainter (const KisPainter &)
 
KisPainteroperator= (const KisPainter &)
 

Private Attributes

Private *const d
 

Detailed Description

KisPainter contains the graphics primitives necessary to draw on a KisPaintDevice. This is the same kind of abstraction as used in Qt itself, where you have QPainter and QPaintDevice.

However, KisPainter works on a tiled image and supports different color models, and that's a lot more complicated.

KisPainter supports transactions that can group various paint operations in one undoable step.

For more complex operations, you might want to have a look at the subclasses of KisPainter: KisConvolutionPainter, KisFillPainter and KisGradientPainter

KisPainter sets a number of default values, like COMPOSITE_OVER for compositeop, OPACITY_OPAQUE for opacity and no selection for selection.

Definition at line 65 of file kis_painter.h.

Member Enumeration Documentation

◆ FillStyle

This enum contains the styles with which we can fill things like polygons and ellipses.

Enumerator
FillStyleNone 
FillStyleForegroundColor 
FillStyleBackgroundColor 
FillStylePattern 
FillStyleGenerator 

Definition at line 718 of file kis_painter.h.

◆ StrokeStyle

The style of the brush stroke around polygons and so.

Enumerator
StrokeStyleNone 
StrokeStyleBrush 

Definition at line 745 of file kis_painter.h.

745 {
748 };

Constructor & Destructor Documentation

◆ KisPainter() [1/4]

KisPainter::KisPainter ( )

Construct painter without a device.

Definition at line 61 of file kis_painter.cc.

62 : d(new Private(this))
63{
64 init();
65}
void init()
Initialize, set everything to '0' or defaults.
Private *const d

References init().

◆ KisPainter() [2/4]

KisPainter::KisPainter ( KisPaintDeviceSP device)

Construct a painter, and begin painting on the device.

Definition at line 67 of file kis_painter.cc.

68 : d(new Private(this, device->colorSpace()))
69{
70 init();
71 Q_ASSERT(device);
73}
const KoColorSpace * colorSpace() const
void begin(KisPaintDeviceSP device)
KisPaintDeviceSP device

References begin(), device, and init().

◆ KisPainter() [3/4]

KisPainter::KisPainter ( KisPaintDeviceSP device,
KisSelectionSP selection )

Construct a painter, and begin painting on the device. All actions will be masked by the given selection.

Definition at line 75 of file kis_painter.cc.

76 : d(new Private(this, device->colorSpace()))
77{
78 init();
79 Q_ASSERT(device);
81 d->selection = selection;
82}
KisSelectionSP selection

References begin(), d, device, init(), and selection.

◆ ~KisPainter()

KisPainter::~KisPainter ( )
virtual

Definition at line 92 of file kis_painter.cc.

93{
94 // TODO: Maybe, don't be that strict?
95 // deleteTransaction();
96 end();
97
98 delete d->paintOp;
99 delete d->maskPainter;
100 delete d->fillPainter;
101 delete d;
102}

References d, and end().

◆ KisPainter() [4/4]

KisPainter::KisPainter ( const KisPainter & )
private

Member Function Documentation

◆ addDirtyRect()

void KisPainter::addDirtyRect ( const QRect & r)

Add r to the current set of dirty rects

Definition at line 409 of file kis_painter.cc.

410{
411 QRect r = rc.normalized();
412 if (r.isValid()) {
413 d->dirtyRects.append(rc);
414 }
415}

References d.

◆ addDirtyRects()

void KisPainter::addDirtyRects ( const QVector< QRect > & rects)

Add rects to the current set of dirty rects

Definition at line 417 of file kis_painter.cc.

418{
419 d->dirtyRects.reserve(d->dirtyRects.size() + rects.size());
420
421 Q_FOREACH (const QRect &rc, rects) {
422 const QRect r = rc.normalized();
423 if (r.isValid()) {
424 d->dirtyRects.append(rc);
425 }
426 }
427}

References d.

◆ antiAliasPolygonFill()

bool KisPainter::antiAliasPolygonFill ( )

Return whether a polygon's filled area should be anti-aliased or not.

◆ applyDevice()

void KisPainter::applyDevice ( const QRect & applyRect,
const KisRenderedDab & dab,
KisRandomAccessorSP dstIt,
const KoColorSpace * srcColorSpace,
KoCompositeOp::ParameterInfo & localParamInfo )

◆ applyDeviceWithSelection()

void KisPainter::applyDeviceWithSelection ( const QRect & applyRect,
const KisRenderedDab & dab,
KisRandomAccessorSP dstIt,
KisRandomConstAccessorSP maskIt,
const KoColorSpace * srcColorSpace,
KoCompositeOp::ParameterInfo & localParamInfo )

◆ backgroundColor()

const KoColor & KisPainter::backgroundColor ( ) const

Returns the current background color.

◆ begin() [1/2]

void KisPainter::begin ( KisPaintDeviceSP device)

Start painting on the specified device. Not undoable.

Definition at line 291 of file kis_painter.cc.

292{
293 begin(device, d->selection);
294}

References begin(), d, and device.

◆ begin() [2/2]

void KisPainter::begin ( KisPaintDeviceSP device,
KisSelectionSP selection )

Start painting on the specified paint device. All actions will be masked by the given selection.

Definition at line 296 of file kis_painter.cc.

297{
298 if (!device) return;
299 d->selection = selection;
300 Q_ASSERT(device->colorSpace());
301
302 end();
303
304 d->device = device;
305 d->colorSpace = device->colorSpace();
306 d->compositeOpId = COMPOSITE_OVER;
307 d->cachedCompositeOp = nullptr;
308 d->pixelSize = device->pixelSize();
309}
const QString COMPOSITE_OVER
quint32 pixelSize() const

References KisPaintDevice::colorSpace(), COMPOSITE_OVER, d, device, end(), KisPaintDevice::pixelSize(), and selection.

◆ beginTransaction()

void KisPainter::beginTransaction ( const KUndo2MagicString & transactionName = KUndo2MagicString(),
int timedID = -1 )

Begin an undoable paint operation.

Definition at line 318 of file kis_painter.cc.

319{
320 Q_ASSERT_X(!d->transaction, "KisPainter::beginTransaction()",
321 "You asked for a new transaction while still having "
322 "another one. Please finish the first one with "
323 "end/deleteTransaction() first");
324
325 d->transaction = new KisTransaction(transactionName, d->device);
326 Q_CHECK_PTR(d->transaction);
327 d->transaction->undoCommand()->setTimedID(timedID);
328}

References d.

◆ bitBlt() [1/2]

void KisPainter::bitBlt ( const QPoint & pos,
const KisPaintDeviceSP srcDev,
const QRect & srcRect )

Convenience method that uses QPoint and QRect.

Parameters
posthe destination coordinate, it replaces dstX and dstY.
srcDevthe source device.
srcRectthe rectangle describing the area to blast from srcDev into the current paint device. srcRect replaces srcX, srcY, srcWidth and srcHeight.

Definition at line 831 of file kis_painter.cc.

832{
833 bitBlt(pos.x(), pos.y(), srcDev, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
834}
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)

References bitBlt().

◆ bitBlt() [2/2]

void KisPainter::bitBlt ( qint32 dstX,
qint32 dstY,
const KisPaintDeviceSP srcDev,
qint32 srcX,
qint32 srcY,
qint32 srcWidth,
qint32 srcHeight )

Blast a region of srcWidth

Parameters
srcWidthand srcHeight
srcHeightfrom
srcDevonto the current paint device.
srcXand
srcYset the x and y positions of the origin top-left corner,
dstXand
dstYthose of the destination. Any pixel read outside the limits of
srcDevwill return the default pixel, this is a property of KisPaintDevice.
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
srcXthe source x-coordinate
srcYthe source y-coordinate
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 822 of file kis_painter.cc.

826{
827 bitBltImpl<false>(dstX, dstY, srcDev, srcX, srcY, srcWidth, srcHeight);
828}

◆ bitBltImpl()

template<bool useOldSrcData>
void KisPainter::bitBltImpl ( qint32 dstX,
qint32 dstY,
const KisPaintDeviceSP srcDev,
qint32 srcX,
qint32 srcY,
qint32 srcWidth,
qint32 srcHeight )
private

An optimization, which crops the source rect by the bounds of the source device when it is possible

Definition at line 658 of file kis_painter.cc.

662{
663 /* This check for nonsense ought to be a Q_ASSERT. However, when paintops are just
664 initializing they perform some dummy passes with those parameters, and it must not crash */
665 if (srcWidth == 0 || srcHeight == 0) return;
666 if (srcDev.isNull()) return;
667 if (d->device.isNull()) return;
668
669 QRect srcRect = QRect(srcX, srcY, srcWidth, srcHeight);
670
671 if (d->compositeOpId == COMPOSITE_COPY) {
672 if(!d->selection && d->isOpacityUnit &&
673 srcX == dstX && srcY == dstY &&
674 d->device->fastBitBltPossible(srcDev) &&
675 (!srcDev->defaultBounds()->wrapAroundMode() ||
676 srcDev->defaultBounds()->imageBorderRect().contains(srcRect))) {
677
678 if(useOldSrcData) {
679 d->device->fastBitBltOldData(srcDev, srcRect);
680 } else {
681 d->device->fastBitBlt(srcDev, srcRect);
682 }
683
684 addDirtyRect(srcRect);
685 return;
686 }
687 }
688 else {
693 if (d->tryReduceSourceRect(srcDev, &srcRect,
694 &srcX, &srcY,
695 &srcWidth, &srcHeight,
696 &dstX, &dstY)) return;
697 }
698
699 qint32 dstY_ = dstY;
700 qint32 srcY_ = srcY;
701 qint32 rowsRemaining = srcHeight;
702
703 const KoCompositeOp *compositeOp = d->compositeOp(srcDev->colorSpace());
704
705 // Read below
707 KisRandomAccessorSP dstIt = d->device->createRandomAccessorNG();
708
709 /* Here be a huge block of verbose code that does roughly the same than
710 the other bit blit operations. This one is longer than the rest in an effort to
711 optimize speed and memory use */
712 if (d->selection) {
713 KisPaintDeviceSP selectionProjection(d->selection->projection());
714 KisRandomConstAccessorSP maskIt = selectionProjection->createRandomConstAccessorNG();
715
716 while (rowsRemaining > 0) {
717
718 qint32 dstX_ = dstX;
719 qint32 srcX_ = srcX;
720 qint32 columnsRemaining = srcWidth;
721 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY_);
722 qint32 numContiguousSrcRows = srcIt->numContiguousRows(srcY_);
723 qint32 numContiguousSelRows = maskIt->numContiguousRows(dstY_);
724
725 qint32 rows = qMin(numContiguousDstRows, numContiguousSrcRows);
726 rows = qMin(rows, numContiguousSelRows);
727 rows = qMin(rows, rowsRemaining);
728
729 while (columnsRemaining > 0) {
730
731 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX_);
732 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(srcX_);
733 qint32 numContiguousSelColumns = maskIt->numContiguousColumns(dstX_);
734
735 qint32 columns = qMin(numContiguousDstColumns, numContiguousSrcColumns);
736 columns = qMin(columns, numContiguousSelColumns);
737 columns = qMin(columns, columnsRemaining);
738
739 qint32 srcRowStride = srcIt->rowStride(srcX_, srcY_);
740 srcIt->moveTo(srcX_, srcY_);
741
742 qint32 dstRowStride = dstIt->rowStride(dstX_, dstY_);
743 dstIt->moveTo(dstX_, dstY_);
744
745 qint32 maskRowStride = maskIt->rowStride(dstX_, dstY_);
746 maskIt->moveTo(dstX_, dstY_);
747
748 d->paramInfo.dstRowStart = dstIt->rawData();
749 d->paramInfo.dstRowStride = dstRowStride;
750 // if we don't use the oldRawData, we need to access the rawData of the source device.
751 d->paramInfo.srcRowStart = useOldSrcData ? srcIt->oldRawData() : static_cast<KisRandomAccessor2*>(srcIt.data())->rawData();
752 d->paramInfo.srcRowStride = srcRowStride;
753 d->paramInfo.maskRowStart = static_cast<KisRandomAccessor2*>(maskIt.data())->rawData();
754 d->paramInfo.maskRowStride = maskRowStride;
755 d->paramInfo.rows = rows;
756 d->paramInfo.cols = columns;
757 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
758
759 srcX_ += columns;
760 dstX_ += columns;
761 columnsRemaining -= columns;
762 }
763
764 srcY_ += rows;
765 dstY_ += rows;
766 rowsRemaining -= rows;
767 }
768 }
769 else {
770
771 while (rowsRemaining > 0) {
772
773 qint32 dstX_ = dstX;
774 qint32 srcX_ = srcX;
775 qint32 columnsRemaining = srcWidth;
776 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY_);
777 qint32 numContiguousSrcRows = srcIt->numContiguousRows(srcY_);
778
779 qint32 rows = qMin(numContiguousDstRows, numContiguousSrcRows);
780 rows = qMin(rows, rowsRemaining);
781
782 while (columnsRemaining > 0) {
783
784 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX_);
785 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(srcX_);
786
787 qint32 columns = qMin(numContiguousDstColumns, numContiguousSrcColumns);
788 columns = qMin(columns, columnsRemaining);
789
790 qint32 srcRowStride = srcIt->rowStride(srcX_, srcY_);
791 srcIt->moveTo(srcX_, srcY_);
792
793 qint32 dstRowStride = dstIt->rowStride(dstX_, dstY_);
794 dstIt->moveTo(dstX_, dstY_);
795
796 d->paramInfo.dstRowStart = dstIt->rawData();
797 d->paramInfo.dstRowStride = dstRowStride;
798 // if we don't use the oldRawData, we need to access the rawData of the source device.
799 d->paramInfo.srcRowStart = useOldSrcData ? srcIt->oldRawData() : static_cast<KisRandomAccessor2*>(srcIt.data())->rawData();
800 d->paramInfo.srcRowStride = srcRowStride;
801 d->paramInfo.maskRowStart = 0;
802 d->paramInfo.maskRowStride = 0;
803 d->paramInfo.rows = rows;
804 d->paramInfo.cols = columns;
805 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
806
807 srcX_ += columns;
808 dstX_ += columns;
809 columnsRemaining -= columns;
810 }
811
812 srcY_ += rows;
813 dstY_ += rows;
814 rowsRemaining -= rows;
815 }
816 }
817
818 addDirtyRect(QRect(dstX, dstY, srcWidth, srcHeight));
819
820}
const QString COMPOSITE_COPY
virtual quint8 * rawData()=0
virtual const quint8 * oldRawData() const =0
virtual bool wrapAroundMode() const =0
virtual QRect imageBorderRect() const
KisRandomConstAccessorSP createRandomConstAccessorNG() const
KisDefaultBoundsBaseSP defaultBounds() const
const KoCompositeOp * compositeOp(const KoColorSpace *srcCS)
void addDirtyRect(const QRect &r)
virtual qint32 rowStride(qint32 x, qint32 y) const =0
virtual qint32 numContiguousRows(qint32 y) const =0
virtual void moveTo(qint32 x, qint32 y)=0
virtual qint32 numContiguousColumns(qint32 x) const =0
bool isNull() const

References addDirtyRect(), KisPaintDevice::colorSpace(), COMPOSITE_COPY, compositeOp(), KisPaintDevice::createRandomConstAccessorNG(), d, KisSharedPtr< T >::data(), KisPaintDevice::defaultBounds(), KisDefaultBoundsBase::imageBorderRect(), KisSharedPtr< T >::isNull(), KisRandomConstAccessorNG::moveTo(), KisRandomConstAccessorNG::numContiguousColumns(), KisRandomConstAccessorNG::numContiguousRows(), KisBaseConstAccessor::oldRawData(), KisBaseAccessor::rawData(), KisRandomConstAccessorNG::rowStride(), and KisDefaultBoundsBase::wrapAroundMode().

◆ bitBltOldData() [1/2]

void KisPainter::bitBltOldData ( const QPoint & pos,
const KisPaintDeviceSP srcDev,
const QRect & srcRect )

Convenience method that uses QPoint and QRect.

Parameters
posthe destination coordinate, it replaces dstX and dstY.
srcDevthe source device.
srcRectthe rectangle describing the area to blast from
srcDevinto the current paint device. srcRect replaces srcX, srcY, srcWidth and srcHeight.

Definition at line 845 of file kis_painter.cc.

846{
847 bitBltOldData(pos.x(), pos.y(), srcDev, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
848}
void bitBltOldData(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)

References bitBltOldData().

◆ bitBltOldData() [2/2]

void KisPainter::bitBltOldData ( qint32 dstX,
qint32 dstY,
const KisPaintDeviceSP srcDev,
qint32 srcX,
qint32 srcY,
qint32 srcWidth,
qint32 srcHeight )

The same as bitBlt() but reads data from oldData() part of the device

Parameters
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
srcXthe source x-coordinate
srcYthe source y-coordinate
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 836 of file kis_painter.cc.

840{
841 bitBltImpl<true>(dstX, dstY, srcDev, srcX, srcY, srcWidth, srcHeight);
842}

◆ bitBltWithFixedSelection() [1/2]

void KisPainter::bitBltWithFixedSelection ( qint32 dstX,
qint32 dstY,
const KisPaintDeviceSP srcDev,
const KisFixedPaintDeviceSP selection,
qint32 selX,
qint32 selY,
qint32 srcX,
qint32 srcY,
qint32 srcWidth,
qint32 srcHeight )

Blasts a

Parameters
selectionof srcWidth
srcWidthand srcHeight
srcHeightof
srcDevon the current paint device. There is parameters to control where the area begins in each distinct device, explained below.
selectioncan be used as a mask to shape
srcDevto something interesting in the same step it is rendered to the current paint device.
selection's colorspace must be alpha8 (the colorspace for selections/transparency), the rectangle formed by
selX

param selY ,

Parameters
srcWidthand
srcHeightmust not go beyond its limits, and they must be different from zero.
selectionand KisPainter's selection (the user selection) are fused together through the composite operation COMPOSITE_MULT. Any pixel read outside the limits of
srcDevwill return the default pixel, this is a property of KisPaintDevice.
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
selectionthe custom selection to apply on the source device
selXthe selection x-coordinate
selYthe selection y-coordinate
srcXthe source x-coordinate
srcYthe source y-coordinate
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

An optimization, which crops the source rect by the bounds of the source device when it is possible

Definition at line 510 of file kis_painter.cc.

516{
517 // TODO: get selX and selY working as intended
518
519 /* This check for nonsense ought to be a Q_ASSERT. However, when paintops are just
520 initializing they perform some dummy passes with those parameters, and it must not crash */
521 if (srcWidth == 0 || srcHeight == 0) return;
522 if (srcDev.isNull()) return;
523 if (d->device.isNull()) return;
524
525 // Check that selection has an alpha colorspace, crash if false
526 Q_ASSERT(selection->colorSpace() == KoColorSpaceRegistry::instance()->alpha8());
527
528 const KoCompositeOp *compositeOp = d->compositeOp(srcDev->colorSpace());
529
530 QRect srcRect = QRect(srcX, srcY, srcWidth, srcHeight);
531
532 // save selection offset in case tryReduceSourceRect() will change rects
533 const int xSelectionOffset = selX - srcX;
534 const int ySelectionOffset = selY - srcY;
535
540 if (d->tryReduceSourceRect(srcDev, &srcRect,
541 &srcX, &srcY,
542 &srcWidth, &srcHeight,
543 &dstX, &dstY)) return;
544
545 const QRect selRect = QRect(srcX + xSelectionOffset,
546 srcY + ySelectionOffset,
547 srcWidth, srcHeight);
548
549 /* Trying to read outside a KisFixedPaintDevice is inherently wrong and shouldn't be done,
550 so crash if someone attempts to do this. Don't resize YET as it would obfuscate the mistake. */
551 KIS_SAFE_ASSERT_RECOVER_RETURN(selection->bounds().contains(selRect));
552 Q_UNUSED(selRect); // only used by the above Q_ASSERT
553
554
555 /* Create an intermediate byte array to hold information before it is written
556 to the current paint device (d->device) */
557 quint8* dstBytes = 0;
558 try {
559 dstBytes = new quint8[srcWidth * srcHeight * d->device->pixelSize()];
560 } catch (const std::bad_alloc&) {
561 warnKrita << "KisPainter::bitBltWithFixedSelection std::bad_alloc for " << srcWidth << " * " << srcHeight << " * " << d->device->pixelSize() << "dst bytes";
562 return;
563 }
564
565 d->device->readBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
566
567 // Copy the relevant bytes of raw data from srcDev
568 quint8* srcBytes = 0;
569 try {
570 srcBytes = new quint8[srcWidth * srcHeight * srcDev->pixelSize()];
571 } catch (const std::bad_alloc&) {
572 warnKrita << "KisPainter::bitBltWithFixedSelection std::bad_alloc for " << srcWidth << " * " << srcHeight << " * " << d->device->pixelSize() << "src bytes";
573 return;
574 }
575
576 srcDev->readBytes(srcBytes, srcX, srcY, srcWidth, srcHeight);
577
578 const QRect selBounds = selection->bounds();
579 const quint8 *selRowStart = selection->data() +
580 (selBounds.width() * (selRect.y() - selBounds.top()) + (selRect.x() - selBounds.left())) * selection->pixelSize();
581
582 /*
583 * This checks whether there is nothing selected.
584 */
585 if (!d->selection) {
586 /* As there's nothing selected, blit to dstBytes (intermediary bit array),
587 ignoring d->selection (the user selection)*/
588 d->paramInfo.dstRowStart = dstBytes;
589 d->paramInfo.dstRowStride = srcWidth * d->device->pixelSize();
590 d->paramInfo.srcRowStart = srcBytes;
591 d->paramInfo.srcRowStride = srcWidth * srcDev->pixelSize();
592 d->paramInfo.maskRowStart = selRowStart;
593 d->paramInfo.maskRowStride = selBounds.width() * selection->pixelSize();
594 d->paramInfo.rows = srcHeight;
595 d->paramInfo.cols = srcWidth;
596 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
597 }
598 else {
599 /* Read the user selection (d->selection) bytes into an array, ready
600 to merge in the next block*/
601 quint32 totalBytes = srcWidth * srcHeight * selection->pixelSize();
602 quint8* mergedSelectionBytes = 0;
603 try {
604 mergedSelectionBytes = new quint8[ totalBytes ];
605 } catch (const std::bad_alloc&) {
606 warnKrita << "KisPainter::bitBltWithFixedSelection std::bad_alloc for " << srcWidth << " * " << srcHeight << " * " << d->device->pixelSize() << "total bytes";
607 return;
608 }
609
610 d->selection->projection()->readBytes(mergedSelectionBytes, dstX, dstY, srcWidth, srcHeight);
611
612 KoCompositeOp::ParameterInfo multiplyParamInfo;
613 multiplyParamInfo.opacity = 1.0f;
614 multiplyParamInfo.flow = 1.0f;
615
616 // Merge selections here by multiplying them - compositeOP(COMPOSITE_MULT)
617 multiplyParamInfo.dstRowStart = mergedSelectionBytes;
618 multiplyParamInfo.dstRowStride = srcWidth * selection->pixelSize();
619 multiplyParamInfo.srcRowStart = selRowStart;
620 multiplyParamInfo.srcRowStride = selBounds.width() * selection->pixelSize();
621 multiplyParamInfo.maskRowStart = 0;
622 multiplyParamInfo.maskRowStride = 0;
623 multiplyParamInfo.rows = srcHeight;
624 multiplyParamInfo.cols = srcWidth;
626
627 // Blit to dstBytes (intermediary bit array)
628 d->paramInfo.dstRowStart = dstBytes;
629 d->paramInfo.dstRowStride = srcWidth * d->device->pixelSize();
630 d->paramInfo.srcRowStart = srcBytes;
631 d->paramInfo.srcRowStride = srcWidth * srcDev->pixelSize();
632 d->paramInfo.maskRowStart = mergedSelectionBytes;
633 d->paramInfo.maskRowStride = srcWidth * selection->pixelSize();
634 d->paramInfo.rows = srcHeight;
635 d->paramInfo.cols = srcWidth;
636 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
637 delete[] mergedSelectionBytes;
638 }
639
640 d->device->writeBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
641
642 delete[] dstBytes;
643 delete[] srcBytes;
644
645 addDirtyRect(QRect(dstX, dstY, srcWidth, srcHeight));
646}
const QString COMPOSITE_MULT
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
const KoCompositeOp * compositeOp(const QString &id, const KoColorSpace *srcSpace=nullptr) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define warnKrita
Definition kis_debug.h:87
static KoColorSpaceRegistry * instance()
const KoColorSpace * alpha8()
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 addDirtyRect(), KoColorSpaceRegistry::alpha8(), KisPaintDevice::colorSpace(), KoCompositeOp::ParameterInfo::cols, KoCompositeOp::composite(), COMPOSITE_MULT, compositeOp(), KoColorSpace::compositeOp(), d, KoCompositeOp::ParameterInfo::dstRowStart, KoCompositeOp::ParameterInfo::dstRowStride, KoCompositeOp::ParameterInfo::flow, KoColorSpaceRegistry::instance(), KisSharedPtr< T >::isNull(), KIS_SAFE_ASSERT_RECOVER_RETURN, KoCompositeOp::ParameterInfo::maskRowStart, KoCompositeOp::ParameterInfo::maskRowStride, KoCompositeOp::ParameterInfo::opacity, KisPaintDevice::pixelSize(), KisPaintDevice::readBytes(), KoCompositeOp::ParameterInfo::rows, selection, KoCompositeOp::ParameterInfo::srcRowStart, KoCompositeOp::ParameterInfo::srcRowStride, and warnKrita.

◆ bitBltWithFixedSelection() [2/2]

void KisPainter::bitBltWithFixedSelection ( qint32 dstX,
qint32 dstY,
const KisPaintDeviceSP srcDev,
const KisFixedPaintDeviceSP selection,
qint32 srcWidth,
qint32 srcHeight )

Convenience method that assumes selX, selY, srcX and srcY are equal to 0. Best used when selection and the desired area of srcDev have exactly the same dimensions and are specially made for each other.

Parameters
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
selectionthe custom selection to apply on the source device
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 649 of file kis_painter.cc.

653{
654 bitBltWithFixedSelection(dstX, dstY, srcDev, selection, 0, 0, 0, 0, srcWidth, srcHeight);
655}
void bitBltWithFixedSelection(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 selX, qint32 selY, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)

References bitBltWithFixedSelection(), and selection.

◆ blendAverageOpacity()

qreal KisPainter::blendAverageOpacity ( qreal opacity,
qreal averageOpacity )
static

Calculate average opacity value after painting a single dab with opacity

Definition at line 2698 of file kis_painter.cc.

2699{
2700 const float exponent = 0.1;
2701
2702 return averageOpacity < opacity ?
2703 opacity :
2704 exponent * opacity + (1.0 - exponent) * (averageOpacity);
2705}

◆ bltFixed() [1/3]

void KisPainter::bltFixed ( const QPoint & pos,
const KisFixedPaintDeviceSP srcDev,
const QRect & srcRect )

Convenience method that uses QPoint and QRect.

Parameters
posthe destination coordinate, it replaces dstX and dstY.
srcDevthe source device.
srcRectthe rectangle describing the area to blast from srcDev into the current paint device.
srcRectreplaces srcX, srcY, srcWidth and srcHeight.

Definition at line 1022 of file kis_painter.cc.

1023{
1024 bltFixed(pos.x(), pos.y(), srcDev, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
1025}
void bltFixed(qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)

References bltFixed().

◆ bltFixed() [2/3]

void KisPainter::bltFixed ( const QRect & rc,
const QList< KisRenderedDab > allSrcDevices )

Render the area rc from srcDevices on the destination device. If rc doesn't cross the device's rect, then the device is not rendered at all.

Definition at line 138 of file kis_painter_blt_multi_fixed.cpp.

139{
140 const KoColorSpace *srcColorSpace = 0;
141 QList<KisRenderedDab> devices;
142 QRect rc = applyRect;
143
144 if (d->selection) {
145 rc &= d->selection->selectedRect();
146 }
147
148 QRect totalDevicesRect;
149
150 Q_FOREACH (const KisRenderedDab &dab, allSrcDevices) {
151 if (rc.intersects(dab.realBounds())) {
152 devices.append(dab);
153 totalDevicesRect |= dab.realBounds();
154 }
155
156 if (!srcColorSpace) {
157 srcColorSpace = dab.device->colorSpace();
158 } else {
159 KIS_SAFE_ASSERT_RECOVER_RETURN(*srcColorSpace == *dab.device->colorSpace());
160 }
161 }
162
163 rc &= totalDevicesRect;
164
165 if (devices.isEmpty() || rc.isEmpty()) return;
166
167 KoCompositeOp::ParameterInfo localParamInfo = d->paramInfo;
168 KisRandomAccessorSP dstIt = d->device->createRandomAccessorNG();
169 KisRandomConstAccessorSP maskIt = d->selection ? d->selection->projection()->createRandomConstAccessorNG() : 0;
170
171 if (maskIt) {
172 Q_FOREACH (const KisRenderedDab &dab, devices) {
173 d->applyDeviceWithSelection(rc, dab, dstIt, maskIt, srcColorSpace, localParamInfo);
174 }
175 } else {
176 Q_FOREACH (const KisRenderedDab &dab, devices) {
177 d->applyDevice(rc, dab, dstIt, srcColorSpace, localParamInfo);
178 }
179 }
180
181
182#if 0
183 // the code above does basically the same thing as this one,
184 // but more efficiently :)
185
186 Q_FOREACH (KisFixedPaintDeviceSP dev, devices) {
187 const QRect copyRect = dev->bounds() & rc;
188 if (copyRect.isEmpty()) continue;
189
190 bltFixed(copyRect.topLeft(), dev, copyRect);
191 }
192#endif
193}
const KoColorSpace * colorSpace() const
KisFixedPaintDeviceSP device
QRect realBounds() const

References bltFixed(), KisFixedPaintDevice::bounds(), KisFixedPaintDevice::colorSpace(), d, KisRenderedDab::device, KIS_SAFE_ASSERT_RECOVER_RETURN, and KisRenderedDab::realBounds().

◆ bltFixed() [3/3]

void KisPainter::bltFixed ( qint32 dstX,
qint32 dstY,
const KisFixedPaintDeviceSP srcDev,
qint32 srcX,
qint32 srcY,
qint32 srcWidth,
qint32 srcHeight )

Blast a region of srcWidth srcWidth and srcHeight srcHeight from srcDev onto the current paint device. srcX and srcY set the x and y positions of the origin top-left corner, dstX and dstY those of the destination. srcDev is a KisFixedPaintDevice : this means that srcDev must have the same colorspace as the destination device.

Parameters
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
srcXthe source x-coordinate
srcYthe source y-coordinate
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 950 of file kis_painter.cc.

954{
955 /* This check for nonsense ought to be a Q_ASSERT. However, when paintops are just
956 initializing they perform some dummy passes with those parameters, and it must not crash */
957 if (srcWidth == 0 || srcHeight == 0) return;
958 if (srcDev.isNull()) return;
959 if (d->device.isNull()) return;
960
961 QRect srcRect = QRect(srcX, srcY, srcWidth, srcHeight);
962 QRect srcBounds = srcDev->bounds();
963
964 /* Trying to read outside a KisFixedPaintDevice is inherently wrong and shouldn't be done,
965 so crash if someone attempts to do this. Don't resize as it would obfuscate the mistake. */
966 KIS_SAFE_ASSERT_RECOVER_RETURN(srcBounds.contains(srcRect));
967 Q_UNUSED(srcRect); // only used in above assertion
968
969 const KoCompositeOp *compositeOp = d->compositeOp(srcDev->colorSpace());
970
971 /* Create an intermediate byte array to hold information before it is written
972 to the current paint device (aka: d->device) */
973 quint8* dstBytes = 0;
974 try {
975 dstBytes = new quint8[srcWidth * srcHeight * d->device->pixelSize()];
976 } catch (const std::bad_alloc&) {
977 warnKrita << "KisPainter::bltFixed std::bad_alloc for " << srcWidth << " * " << srcHeight << " * " << d->device->pixelSize() << "total bytes";
978 return;
979 }
980 d->device->readBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
981
982 const quint8 *srcRowStart = srcDev->data() +
983 (srcBounds.width() * (srcY - srcBounds.top()) + (srcX - srcBounds.left())) * srcDev->pixelSize();
984
985 d->paramInfo.dstRowStart = dstBytes;
986 d->paramInfo.dstRowStride = srcWidth * d->device->pixelSize();
987 d->paramInfo.srcRowStart = srcRowStart;
988 d->paramInfo.srcRowStride = srcBounds.width() * srcDev->pixelSize();
989 d->paramInfo.maskRowStart = 0;
990 d->paramInfo.maskRowStride = 0;
991 d->paramInfo.rows = srcHeight;
992 d->paramInfo.cols = srcWidth;
993
994 if (d->selection) {
995 /* d->selection is a KisPaintDevice, so first a readBytes is performed to
996 get the area of interest... */
997 KisPaintDeviceSP selectionProjection(d->selection->projection());
998 quint8* selBytes = 0;
999 try {
1000 selBytes = new quint8[srcWidth * srcHeight * selectionProjection->pixelSize()];
1001 }
1002 catch (const std::bad_alloc&) {
1003 delete[] dstBytes;
1004 return;
1005 }
1006
1007 selectionProjection->readBytes(selBytes, dstX, dstY, srcWidth, srcHeight);
1008 d->paramInfo.maskRowStart = selBytes;
1009 d->paramInfo.maskRowStride = srcWidth * selectionProjection->pixelSize();
1010 }
1011
1012 // ...and then blit.
1013 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
1014 d->device->writeBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
1015
1016 delete[] d->paramInfo.maskRowStart;
1017 delete[] dstBytes;
1018
1019 addDirtyRect(QRect(dstX, dstY, srcWidth, srcHeight));
1020}

References addDirtyRect(), KisFixedPaintDevice::bounds(), KisFixedPaintDevice::colorSpace(), compositeOp(), d, KisFixedPaintDevice::data(), KisSharedPtr< T >::isNull(), KIS_SAFE_ASSERT_RECOVER_RETURN, KisFixedPaintDevice::pixelSize(), KisPaintDevice::pixelSize(), KisPaintDevice::readBytes(), and warnKrita.

◆ bltFixedWithFixedSelection() [1/2]

void KisPainter::bltFixedWithFixedSelection ( qint32 dstX,
qint32 dstY,
const KisFixedPaintDeviceSP srcDev,
const KisFixedPaintDeviceSP selection,
qint32 selX,
qint32 selY,
qint32 srcX,
qint32 srcY,
quint32 srcWidth,
quint32 srcHeight )

Blasts a selection of srcWidth srcWidth and srcHeight srcHeight of srcDev on the current paint device. There is parameters to control the top-left corner of the area in each respective paint device (dstX, dstY, srcX, srcY). selection can be used as a mask to shape srcDev to something interesting in the same step it is rendered to the current paint device. srcDev is a KisFixedPaintDevice : this means that srcDev must have the same colorspace as the destination device. selection 's colorspace must be alpha8 (the colorspace for selections/transparency). The rectangle formed by the respective top-left coordinates of each device and srcWidth and srcHeight must not go beyond their limits, and they must be different from zero. selection and KisPainter's selection (the user selection) are fused together through the composite operation COMPOSITE_MULT.

Parameters
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
selectionthe selection stored in fixed device
selXthe selection x-coordinate
selYthe selection y-coordinate
srcXthe source x-coordinate
srcYthe source y-coordinate
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 1027 of file kis_painter.cc.

1033{
1034 // TODO: get selX and selY working as intended
1035
1036 /* This check for nonsense ought to be a Q_ASSERT. However, when paintops are just
1037 initializing they perform some dummy passes with those parameters, and it must not crash */
1038 if (srcWidth == 0 || srcHeight == 0) return;
1039 if (srcDev.isNull()) return;
1040 if (d->device.isNull()) return;
1041
1042 // Check that selection has an alpha colorspace, crash if false
1043 Q_ASSERT(selection->colorSpace() == KoColorSpaceRegistry::instance()->alpha8());
1044
1045 const KoCompositeOp *compositeOp = d->compositeOp(srcDev->colorSpace());
1046
1047 QRect srcRect = QRect(srcX, srcY, srcWidth, srcHeight);
1048 QRect selRect = QRect(selX, selY, srcWidth, srcHeight);
1049
1050 QRect srcBounds = srcDev->bounds();
1051 QRect selBounds = selection->bounds();
1052
1053 /* Trying to read outside a KisFixedPaintDevice is inherently wrong and shouldn't be done,
1054 so crash if someone attempts to do this. Don't resize as it would obfuscate the mistake. */
1055 KIS_ASSERT(srcBounds.contains(srcRect));
1056 Q_UNUSED(srcRect); // only used in above assertion
1057 KIS_ASSERT(selBounds.contains(selRect));
1058 Q_UNUSED(selRect); // only used in above assertion
1059
1060 /* Create an intermediate byte array to hold information before it is written
1061 to the current paint device (aka: d->device) */
1062 quint8* dstBytes = 0;
1063 try {
1064 dstBytes = new quint8[srcWidth * srcHeight * d->device->pixelSize()];
1065 } catch (const std::bad_alloc&) {
1066 warnKrita << "KisPainter::bltFixedWithFixedSelection std::bad_alloc for " << srcWidth << " * " << srcHeight << " * " << d->device->pixelSize() << "total bytes";
1067 return;
1068 }
1069 d->device->readBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
1070
1071 const quint8 *srcRowStart = srcDev->data() +
1072 (srcBounds.width() * (srcY - srcBounds.top()) + (srcX - srcBounds.left())) * srcDev->pixelSize();
1073 const quint8 *selRowStart = selection->data() +
1074 (selBounds.width() * (selY - selBounds.top()) + (selX - selBounds.left())) * selection->pixelSize();
1075
1076 if (!d->selection) {
1077 /* As there's nothing selected, blit to dstBytes (intermediary bit array),
1078 ignoring d->selection (the user selection)*/
1079 d->paramInfo.dstRowStart = dstBytes;
1080 d->paramInfo.dstRowStride = srcWidth * d->device->pixelSize();
1081 d->paramInfo.srcRowStart = srcRowStart;
1082 d->paramInfo.srcRowStride = srcBounds.width() * srcDev->pixelSize();
1083 d->paramInfo.maskRowStart = selRowStart;
1084 d->paramInfo.maskRowStride = selBounds.width() * selection->pixelSize();
1085 d->paramInfo.rows = srcHeight;
1086 d->paramInfo.cols = srcWidth;
1087 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
1088 }
1089 else {
1090 /* Read the user selection (d->selection) bytes into an array, ready
1091 to merge in the next block*/
1092 quint32 totalBytes = srcWidth * srcHeight * selection->pixelSize();
1093 quint8 * mergedSelectionBytes = 0;
1094 try {
1095 mergedSelectionBytes = new quint8[ totalBytes ];
1096 } catch (const std::bad_alloc&) {
1097 warnKrita << "KisPainter::bltFixedWithFixedSelection std::bad_alloc for " << totalBytes << "total bytes";
1098 delete[] dstBytes;
1099 return;
1100 }
1101 d->selection->projection()->readBytes(mergedSelectionBytes, dstX, dstY, srcWidth, srcHeight);
1102
1103 KoCompositeOp::ParameterInfo multiplyParamInfo;
1104 multiplyParamInfo.opacity = 1.0f;
1105 multiplyParamInfo.flow = 1.0f;
1106
1107 // Merge selections here by multiplying them - compositeOp(COMPOSITE_MULT)
1108 multiplyParamInfo.dstRowStart = mergedSelectionBytes;
1109 multiplyParamInfo.dstRowStride = srcWidth * selection->pixelSize();
1110 multiplyParamInfo.srcRowStart = selRowStart;
1111 multiplyParamInfo.srcRowStride = selBounds.width() * selection->pixelSize();
1112 multiplyParamInfo.maskRowStart = 0;
1113 multiplyParamInfo.maskRowStride = 0;
1114 multiplyParamInfo.rows = srcHeight;
1115 multiplyParamInfo.cols = srcWidth;
1117
1118 // Blit to dstBytes (intermediary bit array)
1119 d->paramInfo.dstRowStart = dstBytes;
1120 d->paramInfo.dstRowStride = srcWidth * d->device->pixelSize();
1121 d->paramInfo.srcRowStart = srcRowStart;
1122 d->paramInfo.srcRowStride = srcBounds.width() * srcDev->pixelSize();
1123 d->paramInfo.maskRowStart = mergedSelectionBytes;
1124 d->paramInfo.maskRowStride = srcWidth * selection->pixelSize();
1125 d->paramInfo.rows = srcHeight;
1126 d->paramInfo.cols = srcWidth;
1127 d->colorSpace->bitBlt(srcDev->colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
1128
1129 delete[] mergedSelectionBytes;
1130 }
1131
1132 d->device->writeBytes(dstBytes, dstX, dstY, srcWidth, srcHeight);
1133
1134 delete[] dstBytes;
1135
1136 addDirtyRect(QRect(dstX, dstY, srcWidth, srcHeight));
1137}
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References addDirtyRect(), KoColorSpaceRegistry::alpha8(), KisFixedPaintDevice::bounds(), KisFixedPaintDevice::colorSpace(), KoCompositeOp::ParameterInfo::cols, KoCompositeOp::composite(), COMPOSITE_MULT, compositeOp(), KoColorSpace::compositeOp(), d, KisFixedPaintDevice::data(), KoCompositeOp::ParameterInfo::dstRowStart, KoCompositeOp::ParameterInfo::dstRowStride, KoCompositeOp::ParameterInfo::flow, KoColorSpaceRegistry::instance(), KisSharedPtr< T >::isNull(), KIS_ASSERT, KoCompositeOp::ParameterInfo::maskRowStart, KoCompositeOp::ParameterInfo::maskRowStride, KoCompositeOp::ParameterInfo::opacity, KisFixedPaintDevice::pixelSize(), KoCompositeOp::ParameterInfo::rows, selection, KoCompositeOp::ParameterInfo::srcRowStart, KoCompositeOp::ParameterInfo::srcRowStride, and warnKrita.

◆ bltFixedWithFixedSelection() [2/2]

void KisPainter::bltFixedWithFixedSelection ( qint32 dstX,
qint32 dstY,
const KisFixedPaintDeviceSP srcDev,
const KisFixedPaintDeviceSP selection,
quint32 srcWidth,
quint32 srcHeight )

Convenience method that assumes selX, selY, srcX and srcY are equal to 0. Best used when selection and srcDev have exactly the same dimensions and are specially made for each other.

Parameters
dstXthe destination x-coordinate
dstYthe destination y-coordinate
srcDevthe source device
selectionthe custom selection to apply on the source device
srcWidththe width of the region to be manipulated
srcHeightthe height of the region to be manipulated

Definition at line 1139 of file kis_painter.cc.

1143{
1144 bltFixedWithFixedSelection(dstX, dstY, srcDev, selection, selection->bounds().x(), selection->bounds().y(), srcDev->bounds().x(), srcDev->bounds().y(), srcWidth, srcHeight);
1145}
void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 selX, qint32 selY, qint32 srcX, qint32 srcY, quint32 srcWidth, quint32 srcHeight)
qint32 x() const
qint32 y() const

References bltFixedWithFixedSelection(), KisFixedPaintDevice::bounds(), selection, KisSelection::x(), and KisSelection::y().

◆ calculateAllMirroredPoints() [1/2]

const QVector< QPair< QPointF, QPointF > > KisPainter::calculateAllMirroredPoints ( const QPair< QPointF, QPointF > & pair)

Calculate the list of the mirrored point pairs according to the current mirroring configuration.

Definition at line 3150 of file kis_painter.cc.

3151{
3152 return d->calculateMirroredObjects(pair);
3153}

References d.

◆ calculateAllMirroredPoints() [2/2]

const QVector< QPointF > KisPainter::calculateAllMirroredPoints ( const QPointF & pos)

Calculate the list of the mirrored points according to the current mirroring configuration.

Definition at line 3145 of file kis_painter.cc.

3146{
3147 return d->calculateMirroredObjects(pos);
3148}

References d.

◆ calculateAllMirroredRects()

const QVector< QRect > KisPainter::calculateAllMirroredRects ( const QRect & rc)

Calculate the list of the mirrored rects that will be painted on the the canvas when calling renderMirrorMask() at al

Definition at line 3140 of file kis_painter.cc.

3141{
3142 return d->calculateMirroredObjects(rc);
3143}

References d.

◆ calculateMirroredObjects()

template<class T >
QVector< T > KisPainter::calculateMirroredObjects ( const T & object)

◆ channelFlags()

QBitArray KisPainter::channelFlags ( )
Returns
the channel flags

Definition at line 2587 of file kis_painter.cc.

2588{
2589 return d->paramInfo.channelFlags;
2590}

References d.

◆ checkDeviceHasTransparency()

bool KisPainter::checkDeviceHasTransparency ( KisPaintDeviceSP dev)
static

Definition at line 268 of file kis_painter.cc.

269{
270 const QRect deviceBounds = dev->exactBounds();
271 const QRect imageBounds = dev->defaultBounds()->bounds();
272
273 if (deviceBounds.isEmpty() ||
274 (deviceBounds & imageBounds) != imageBounds) {
275
276 return true;
277 }
278
279 const KoColorSpace *cs = dev->colorSpace();
280 KisSequentialConstIterator it(dev, deviceBounds);
281
282 while(it.nextPixel()) {
283 if (cs->opacityU8(it.rawDataConst()) != OPACITY_OPAQUE_U8) {
284 return true;
285 }
286 }
287
288 return false;
289}
const quint8 OPACITY_OPAQUE_U8
virtual QRect bounds() const =0
QRect exactBounds() const
virtual quint8 opacityU8(const quint8 *pixel) const =0

References KisDefaultBoundsBase::bounds(), KisPaintDevice::colorSpace(), KisPaintDevice::defaultBounds(), KisPaintDevice::exactBounds(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), OPACITY_OPAQUE_U8, KoColorSpace::opacityU8(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().

◆ compositeOnePixel()

void KisPainter::compositeOnePixel ( quint8 * dst,
const KoColor & color )
inlineprivate

Definition at line 1636 of file kis_painter.cc.

1637{
1638 d->paramInfo.dstRowStart = dst;
1639 d->paramInfo.dstRowStride = 0;
1640 d->paramInfo.srcRowStart = color.data();
1641 d->paramInfo.srcRowStride = 0;
1642 d->paramInfo.maskRowStart = 0;
1643 d->paramInfo.maskRowStride = 0;
1644 d->paramInfo.rows = 1;
1645 d->paramInfo.cols = 1;
1646
1647 d->colorSpace->bitBlt(color.colorSpace(), d->paramInfo, d->compositeOp(color.colorSpace()),
1648 d->renderingIntent,
1649 d->conversionFlags);
1650}
quint8 * data()
Definition KoColor.h:144
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82

References KoColor::colorSpace(), d, and KoColor::data().

◆ compositeOp()

const KoCompositeOp * KisPainter::compositeOp ( const KoColorSpace * srcCS)

◆ compositeOpId()

QString KisPainter::compositeOpId ( )

Returns the current composite op Id.

◆ convertToAlphaAsAlpha()

KisPaintDeviceSP KisPainter::convertToAlphaAsAlpha ( KisPaintDeviceSP src)
static

Definition at line 202 of file kis_painter.cc.

203{
204 const KoColorSpace *srcCS = src->colorSpace();
205 const QRect processRect = src->extent();
207
208 if (processRect.isEmpty()) return dst;
209
210 KisSequentialConstIterator srcIt(src, processRect);
211 KisSequentialIterator dstIt(dst, processRect);
212
213 while (srcIt.nextPixel() && dstIt.nextPixel()) {
214 const quint8 *srcPtr = srcIt.rawDataConst();
215 quint8 *alpha8Ptr = dstIt.rawData();
216
217 const quint8 white = srcCS->intensity8(srcPtr);
218 const quint8 alpha = srcCS->opacityU8(srcPtr);
219
221 }
222
223 return dst;
224}
static _Tdst multiply(_T a, _Tdst b)
virtual quint8 intensity8(const quint8 *src) const =0

References KoColorSpaceRegistry::instance(), KoColorSpace::intensity8(), KoColorSpaceMaths< _T, _Tdst >::multiply(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KoColorSpace::opacityU8(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().

◆ convertToAlphaAsGray()

KisPaintDeviceSP KisPainter::convertToAlphaAsGray ( KisPaintDeviceSP src)
static

Definition at line 226 of file kis_painter.cc.

227{
228 const KoColorSpace *srcCS = src->colorSpace();
229 const QRect processRect = src->extent();
231
232 if (processRect.isEmpty()) return dst;
233
234 KisSequentialConstIterator srcIt(src, processRect);
235 KisSequentialIterator dstIt(dst, processRect);
236
237 while (srcIt.nextPixel() && dstIt.nextPixel()) {
238 const quint8 *srcPtr = srcIt.rawDataConst();
239 quint8 *alpha8Ptr = dstIt.rawData();
240
241 *alpha8Ptr = srcCS->intensity8(srcPtr);
242 }
243
244 return dst;
245}

References KoColorSpaceRegistry::instance(), KoColorSpace::intensity8(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().

◆ convertToAlphaAsPureAlpha()

KisPaintDeviceSP KisPainter::convertToAlphaAsPureAlpha ( KisPaintDeviceSP src)
static

creates a paint device with only alpha values from src

Definition at line 247 of file kis_painter.cc.

248{
249 const KoColorSpace *srcCS = src->colorSpace();
250 const QRect processRect = src->extent();
252
253 if (processRect.isEmpty()) return dst;
254
255 KisSequentialConstIterator srcIt(src, processRect);
256 KisSequentialIterator dstIt(dst, processRect);
257
258 while (srcIt.nextPixel() && dstIt.nextPixel()) {
259 const quint8 *srcPtr = srcIt.rawDataConst();
260 quint8 *alpha8Ptr = dstIt.rawData();
261
262 *alpha8Ptr = srcCS->opacityU8(srcPtr);
263 }
264
265 return dst;
266}

References KoColorSpaceRegistry::instance(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KoColorSpace::opacityU8(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst().

◆ copyAreaOptimized() [1/2]

void KisPainter::copyAreaOptimized ( const QPoint & dstPt,
KisPaintDeviceSP src,
KisPaintDeviceSP dst,
const QRect & originalSrcRect )
static

Definition at line 153 of file kis_painter.cc.

157{
158 copyAreaOptimizedImpl<false>(dstPt, src, dst, srcRect);
159}

◆ copyAreaOptimized() [2/2]

void KisPainter::copyAreaOptimized ( const QPoint & dstPt,
KisPaintDeviceSP src,
KisPaintDeviceSP dst,
const QRect & originalSrcRect,
KisSelectionSP selection )
static

Definition at line 169 of file kis_painter.cc.

174{
175 if (!selection) {
176 copyAreaOptimized(dstPt, src, dst, originalSrcRect);
177 return;
178 }
179
180 const QRect selectionRect = selection->selectedRect();
181 const QRect srcRect = originalSrcRect & selectionRect;
182 const QPoint dstOffset = srcRect.topLeft() - originalSrcRect.topLeft();
183 const QRect dstRect = QRect(dstPt + dstOffset, srcRect.size());
184
185 const bool srcEmpty = (src->extent() & srcRect).isEmpty();
186 const bool dstEmpty = (dst->extent() & dstRect).isEmpty();
187
188 if (!srcEmpty || !dstEmpty) {
189 //if (srcEmpty) {
190 // doesn't support dstRect
191 // dst->clearSelection(selection);
192 // } else */
193 {
194 KisPainter gc(dst);
195 gc.setSelection(selection);
196 gc.setCompositeOpId(COMPOSITE_COPY);
197 gc.bitBlt(dstRect.topLeft(), src, srcRect);
198 }
199 }
200}
QRect extent() const
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
QRect selectedRect() const

References bitBlt(), COMPOSITE_COPY, copyAreaOptimized(), KisPaintDevice::extent(), KisSelection::selectedRect(), selection, setCompositeOpId(), and setSelection().

◆ copyAreaOptimizedOldData()

void KisPainter::copyAreaOptimizedOldData ( const QPoint & dstPt,
KisPaintDeviceSP src,
KisPaintDeviceSP dst,
const QRect & originalSrcRect )
static

Definition at line 161 of file kis_painter.cc.

165{
166 copyAreaOptimizedImpl<true>(dstPt, src, dst, srcRect);
167}

◆ copyMirrorInformationFrom()

void KisPainter::copyMirrorInformationFrom ( const KisPainter * other)

Definition at line 2809 of file kis_painter.cc.

2810{
2811 d->axesCenter = other->d->axesCenter;
2812 d->mirrorHorizontally = other->d->mirrorHorizontally;
2813 d->mirrorVertically = other->d->mirrorVertically;
2814}

References d.

◆ deleteTransaction()

void KisPainter::deleteTransaction ( )

Finish the transaction and delete it's undo information. NOTE: Be careful, because all the previous transactions will become non-undoable after execution of this method.

Definition at line 372 of file kis_painter.cc.

373{
374 if (!d->transaction) return;
375
376 delete d->transaction;
377 d->transaction = 0;
378}

References d.

◆ device() [1/2]

KisPaintDeviceSP KisPainter::device ( )

◆ device() [2/2]

const KisPaintDeviceSP KisPainter::device ( ) const

Returns the current paint device.

◆ drawDDALine()

void KisPainter::drawDDALine ( const QPointF & start,
const QPointF & end )

paints an unstroked, aliased one-pixel line using the DDA algorithm from specified start position to the specified end position.

Definition at line 1740 of file kis_painter.cc.

1741{
1742 int x = qFloor(start.x());
1743 int y = qFloor(start.y());
1744
1745 int x2 = qFloor(end.x());
1746 int y2 = qFloor(end.y());
1747 // Width and height of the line
1748 int xd = x2 - x;
1749 int yd = y2 - y;
1750
1751 float m = 0;
1752 bool lockAxis = true;
1753
1754 if (xd == 0) {
1755 m = 2.0;
1756 } else if ( yd != 0) {
1757 lockAxis = false;
1758 m = (float)yd / (float)xd;
1759 }
1760
1761 float fx = x;
1762 float fy = y;
1763 int inc;
1764
1765 KisRandomAccessorSP accessor = d->device->createRandomAccessorNG();
1766 KisRandomConstAccessorSP selectionAccessor;
1767 if (d->selection) {
1768 selectionAccessor = d->selection->projection()->createRandomConstAccessorNG();
1769 }
1770
1771
1772 accessor->moveTo(x, y);
1773 if (selectionAccessor) selectionAccessor->moveTo(x,y);
1774
1775 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1776 compositeOnePixel(accessor->rawData(), d->paintColor);
1777 }
1778
1779 if (fabs(m) > 1.0f) {
1780 inc = (yd > 0) ? 1 : -1;
1781 m = (lockAxis)? 0 : 1.0f / m;
1782 m *= inc;
1783 while (y != y2) {
1784 y = y + inc;
1785 fx = fx + m;
1786 x = qRound(fx);
1787
1788 accessor->moveTo(x, y);
1789 if (selectionAccessor) selectionAccessor->moveTo(x, y);
1790
1791 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1792 compositeOnePixel(accessor->rawData(), d->paintColor);
1793 }
1794 }
1795 } else {
1796 inc = (xd > 0) ? 1 : -1;
1797 m *= inc;
1798 while (x != x2) {
1799 x = x + inc;
1800 fy = fy + m;
1801 y = qRound(fy);
1802
1803 accessor->moveTo(x, y);
1804 if (selectionAccessor) selectionAccessor->moveTo(x, y);
1805
1806 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1807 compositeOnePixel(accessor->rawData(), d->paintColor);
1808 }
1809 }
1810 }
1811}
void compositeOnePixel(quint8 *dst, const KoColor &color)
const quint8 SELECTION_THRESHOLD
Definition kis_global.h:34

References compositeOnePixel(), d, KisRandomConstAccessorNG::moveTo(), KisBaseConstAccessor::oldRawData(), KisBaseAccessor::rawData(), and SELECTION_THRESHOLD.

◆ drawLine() [1/2]

void KisPainter::drawLine ( const QPointF & start,
const QPointF & end )

paint an unstroked one-pixel wide line from specified start position to the specified end position.

Definition at line 1735 of file kis_painter.cc.

1736{
1737 drawThickLine(start, end, 1, 1);
1738}
void drawThickLine(const QPointF &start, const QPointF &end, int startWidth, int endWidth)

References drawThickLine().

◆ drawLine() [2/2]

void KisPainter::drawLine ( const QPointF & start,
const QPointF & end,
qreal width,
bool antialias )

paint an unstroked line with thickness from specified start position to the specified end position. Scanline algorithm is used.

Definition at line 1653 of file kis_painter.cc.

1653 {
1654 int x1 = qFloor(start.x());
1655 int y1 = qFloor(start.y());
1656 int x2 = qFloor(end.x());
1657 int y2 = qFloor(end.y());
1658
1659 if ((x2 == x1 ) && (y2 == y1)) return;
1660
1661 int dstX = x2-x1;
1662 int dstY = y2-y1;
1663
1664 qreal uniC = dstX*y1 - dstY*x1;
1665 qreal projectionDenominator = 1.0 / (pow((double)dstX, 2) + pow((double)dstY, 2));
1666
1667 qreal subPixel;
1668 if (qAbs(dstX) > qAbs(dstY)){
1669 subPixel = start.x() - x1;
1670 }else{
1671 subPixel = start.y() - y1;
1672 }
1673
1674 qreal halfWidth = width * 0.5 + subPixel;
1675 int W_ = qRound(halfWidth) + 1;
1676
1677 // save the state
1678 int X1_ = x1;
1679 int Y1_ = y1;
1680 int X2_ = x2;
1681 int Y2_ = y2;
1682
1683 if (x2<x1) std::swap(x1,x2);
1684 if (y2<y1) std::swap(y1,y2);
1685
1686 qreal denominator = sqrt(pow((double)dstY,2) + pow((double)dstX,2));
1687 if (denominator == 0.0) {
1688 denominator = 1.0;
1689 }
1690 denominator = 1.0/denominator;
1691
1692 qreal projection,scanX,scanY,AA_;
1693 KisRandomAccessorSP accessor = d->device->createRandomAccessorNG();
1694 KisRandomConstAccessorSP selectionAccessor;
1695 if (d->selection) {
1696 selectionAccessor = d->selection->projection()->createRandomConstAccessorNG();
1697 }
1698
1699 for (int y = y1-W_; y < y2+W_ ; y++){
1700 for (int x = x1-W_; x < x2+W_; x++){
1701
1702 projection = ( (x-X1_)* dstX + (y-Y1_)*dstY ) * projectionDenominator;
1703 scanX = X1_ + projection * dstX;
1704 scanY = Y1_ + projection * dstY;
1705
1706 if (((scanX < x1) || (scanX > x2)) || ((scanY < y1) || (scanY > y2))) {
1707 AA_ = qMin( sqrt( pow((double)x - X1_, 2) + pow((double)y - Y1_, 2) ),
1708 sqrt( pow((double)x - X2_, 2) + pow((double)y - Y2_, 2) ));
1709 }else{
1710 AA_ = qAbs(dstY*x - dstX*y + uniC) * denominator;
1711 }
1712
1713 if (AA_>halfWidth) {
1714 continue;
1715 }
1716
1717 accessor->moveTo(x, y);
1718 if (selectionAccessor) selectionAccessor->moveTo(x,y);
1719
1720 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1721 KoColor mycolor = d->paintColor;
1722
1723 if (antialias && AA_ > halfWidth - 1.0) {
1724 mycolor.colorSpace()->multiplyAlpha(mycolor.data(), (1.0 - (AA_ - (halfWidth - 1.0))) * 256, 1);
1725 }
1726
1727 compositeOnePixel(accessor->rawData(), mycolor);
1728 }
1729 }
1730 }
1731}
virtual void multiplyAlpha(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0

References KoColor::colorSpace(), compositeOnePixel(), d, KoColor::data(), KisRandomConstAccessorNG::moveTo(), KoColorSpace::multiplyAlpha(), KisBaseConstAccessor::oldRawData(), KisBaseAccessor::rawData(), and SELECTION_THRESHOLD.

◆ drawPainterPath() [1/2]

void KisPainter::drawPainterPath ( const QPainterPath & path,
const QPen & pen )

Definition at line 1558 of file kis_painter.cc.

1559{
1560 drawPainterPath(path, pen, QRect());
1561}
void drawPainterPath(const QPainterPath &path, const QPen &pen, const QRect &requestedRect)

References drawPainterPath().

◆ drawPainterPath() [2/2]

void KisPainter::drawPainterPath ( const QPainterPath & path,
const QPen & pen,
const QRect & requestedRect )

Draw the path using the Pen

if requestedRect is null, the entire path is painted

Definition at line 1563 of file kis_painter.cc.

1564{
1565 QPen pen(_pen);
1566 pen.setColor(Qt::white);
1567
1568 if (!d->fillPainter) {
1569 d->polygon = d->device->createCompositionSourceDevice();
1570 d->fillPainter = new KisFillPainter(d->polygon);
1571 } else {
1572 d->polygon->clear();
1573 }
1574
1575 Q_CHECK_PTR(d->polygon);
1576
1577 QRectF boundingRect = path.boundingRect();
1578 QRect fillRect = boundingRect.toAlignedRect();
1579
1580 // take width of the pen into account
1581 int penWidth = qRound(pen.widthF());
1582 fillRect.adjust(-penWidth, -penWidth, penWidth, penWidth);
1583
1584 // Expand the rectangle to allow for anti-aliasing.
1585 fillRect.adjust(-1, -1, 1, 1);
1586
1587 if (!requestedRect.isNull()) {
1588 fillRect &= requestedRect;
1589 }
1590
1591 d->fillPainter->fillRect(fillRect, paintColor(), OPACITY_OPAQUE_U8);
1592
1593 if (d->polygonMaskImage.isNull() || (d->maskPainter == 0)) {
1594 d->polygonMaskImage = QImage(d->maskImageWidth, d->maskImageHeight, QImage::Format_ARGB32_Premultiplied);
1595 d->maskPainter = new QPainter(&d->polygonMaskImage);
1596 d->maskPainter->setRenderHint(QPainter::Antialiasing, antiAliasPolygonFill());
1597 }
1598
1599 // Break the mask up into chunks so we don't have to allocate a potentially very large QImage.
1600 const QColor black(Qt::black);
1601 QPen oldPen = d->maskPainter->pen();
1602 d->maskPainter->setPen(pen);
1603
1604 for (qint32 x = fillRect.x(); x < fillRect.x() + fillRect.width(); x += d->maskImageWidth) {
1605 for (qint32 y = fillRect.y(); y < fillRect.y() + fillRect.height(); y += d->maskImageHeight) {
1606
1607 d->polygonMaskImage.fill(black.rgb());
1608 d->maskPainter->translate(-x, -y);
1609 d->maskPainter->drawPath(path);
1610 d->maskPainter->translate(x, y);
1611
1612 qint32 rectWidth = qMin(fillRect.x() + fillRect.width() - x, d->maskImageWidth);
1613 qint32 rectHeight = qMin(fillRect.y() + fillRect.height() - y, d->maskImageHeight);
1614
1615 KisHLineIteratorSP lineIt = d->polygon->createHLineIteratorNG(x, y, rectWidth);
1616
1617 quint8 tmp;
1618 for (int row = y; row < y + rectHeight; row++) {
1619 QRgb* line = reinterpret_cast<QRgb*>(d->polygonMaskImage.scanLine(row - y));
1620 do {
1621 tmp = qRed(line[lineIt->x() - x]);
1622 d->polygon->colorSpace()->applyAlphaU8Mask(lineIt->rawData(), &tmp, 1);
1623 } while (lineIt->nextPixel());
1624 lineIt->nextRow();
1625 }
1626
1627 }
1628 }
1629
1630 d->maskPainter->setPen(oldPen);
1631 QRect r = d->polygon->extent();
1632
1633 bitBlt(r.x(), r.y(), d->polygon, r.x(), r.y(), r.width(), r.height());
1634}
bool antiAliasPolygonFill
KoColor paintColor
unsigned int QRgb

References antiAliasPolygonFill, bitBlt(), d, OPACITY_OPAQUE_U8, and paintColor.

◆ drawThickLine()

void KisPainter::drawThickLine ( const QPointF & start,
const QPointF & end,
int startWidth,
int endWidth )

Paint an unstroked wide line from the specified start to the specified end position with width varying from start at the start to end at the end.

XXX: the width should be set in doubles, not integers.

Definition at line 2168 of file kis_painter.cc.

2169{
2170
2171 KisRandomAccessorSP accessor = d->device->createRandomAccessorNG();
2172 KisRandomConstAccessorSP selectionAccessor;
2173 if (d->selection) {
2174 selectionAccessor = d->selection->projection()->createRandomConstAccessorNG();
2175 }
2176
2177 const KoColorSpace *cs = d->device->colorSpace();
2178
2179 KoColor c1(d->paintColor);
2180 KoColor c2(d->paintColor);
2181 KoColor c3(d->paintColor);
2182 KoColor col1(c1);
2183 KoColor col2(c1);
2184
2185 float grada, gradb, dxa, dxb, dya, dyb, fraca, fracb,
2186 xfa, yfa, xfb, yfb, b1a, b2a, b1b, b2b, dstX, dstY;
2187 int x, y, ix1, ix2, iy1, iy2;
2188
2189 int x0a, y0a, x1a, y1a, x0b, y0b, x1b, y1b;
2190 int tp0, tn0, tp1, tn1;
2191
2192 int horizontal = 0;
2193 float opacity = 1.0;
2194
2195 tp0 = startWidth / 2;
2196 tn0 = startWidth / 2;
2197 if (startWidth % 2 == 0) // even width startWidth
2198 tn0--;
2199
2200 tp1 = endWidth / 2;
2201 tn1 = endWidth / 2;
2202 if (endWidth % 2 == 0) // even width endWidth
2203 tn1--;
2204
2205 int x0 = qRound(start.x());
2206 int y0 = qRound(start.y());
2207 int x1 = qRound(end.x());
2208 int y1 = qRound(end.y());
2209
2210 dstX = x1 - x0; // run of general line
2211 dstY = y1 - y0; // rise of general line
2212
2213 if (dstY < 0) dstY = -dstY;
2214 if (dstX < 0) dstX = -dstX;
2215
2216 if (dstX > dstY) { // horizontalish
2217 horizontal = 1;
2218 x0a = x0; y0a = y0 - tn0;
2219 x0b = x0; y0b = y0 + tp0;
2220 x1a = x1; y1a = y1 - tn1;
2221 x1b = x1; y1b = y1 + tp1;
2222 } else {
2223 x0a = x0 - tn0; y0a = y0;
2224 x0b = x0 + tp0; y0b = y0;
2225 x1a = x1 - tn1; y1a = y1;
2226 x1b = x1 + tp1; y1b = y1;
2227 }
2228
2229 if (horizontal) { // draw endpoints
2230 for (int i = y0a; i <= y0b; i++) {
2231
2232 accessor->moveTo(x0, i);
2233 if (selectionAccessor) selectionAccessor->moveTo(x0, i);
2234
2235 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2236 compositeOnePixel(accessor->rawData(), c1);
2237 }
2238 }
2239 for (int i = y1a; i <= y1b; i++) {
2240
2241 accessor->moveTo(x1, i);
2242 if (selectionAccessor) selectionAccessor->moveTo(x1, i);
2243
2244 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2245 compositeOnePixel(accessor->rawData(), c1);
2246 }
2247 }
2248
2249 } else {
2250 for (int i = x0a; i <= x0b; i++) {
2251
2252 accessor->moveTo(i, y0);
2253 if (selectionAccessor) selectionAccessor->moveTo(i, y0);
2254
2255 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2256 compositeOnePixel(accessor->rawData(), c1);
2257 }
2258 }
2259 for (int i = x1a; i <= x1b; i++) {
2260 accessor->moveTo(i, y1);
2261 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2262 compositeOnePixel(accessor->rawData(), c1);
2263 }
2264 }
2265 }
2266
2267 //antialias endpoints
2268 if (x1 != x0 && y1 != y0) {
2269 if (horizontal) {
2270
2271 accessor->moveTo(x0a, y0a - 1);
2272 if (selectionAccessor) selectionAccessor->moveTo(x0a, y0a - 1);
2273
2274 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2275 qreal alpha = cs->opacityF(accessor->rawData());
2276 opacity = .25 * c1.opacityF() + (1 - .25) * alpha;
2277 col1.setOpacity(opacity);
2278 compositeOnePixel(accessor->rawData(), col1);
2279 }
2280
2281 accessor->moveTo(x1b, y1b + 1);
2282 if (selectionAccessor) selectionAccessor->moveTo(x1b, y1b + 1);
2283
2284 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2285 qreal alpha = cs->opacityF(accessor->rawData());
2286 opacity = .25 * c2.opacityF() + (1 - .25) * alpha;
2287 col1.setOpacity(opacity);
2288 compositeOnePixel(accessor->rawData(), col1);
2289 }
2290
2291 } else {
2292
2293 accessor->moveTo(x0a - 1, y0a);
2294 if (selectionAccessor) selectionAccessor->moveTo(x0a - 1, y0a);
2295
2296 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2297 qreal alpha = cs->opacityF(accessor->rawData());
2298 opacity = .25 * c1.opacityF() + (1 - .25) * alpha;
2299 col1.setOpacity(opacity);
2300 compositeOnePixel(accessor->rawData(), col1);
2301 }
2302
2303 accessor->moveTo(x1b + 1, y1b);
2304 if (selectionAccessor) selectionAccessor->moveTo(x1b + 1, y1b);
2305
2306 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2307 qreal alpha = cs->opacityF(accessor->rawData());
2308 opacity = .25 * c2.opacityF() + (1 - .25) * alpha;
2309 col1.setOpacity(opacity);
2310 compositeOnePixel(accessor->rawData(), col1);
2311 }
2312 }
2313 }
2314
2315 dxa = x1a - x0a; // run of a
2316 dya = y1a - y0a; // rise of a
2317 dxb = x1b - x0b; // run of b
2318 dyb = y1b - y0b; // rise of b
2319
2320 if (horizontal) { // horizontal-ish lines
2321 if (x1 < x0) {
2322 int xt, yt, wt;
2323 KoColor tmp;
2324 xt = x1a; x1a = x0a; x0a = xt;
2325 yt = y1a; y1a = y0a; y0a = yt;
2326 xt = x1b; x1b = x0b; x0b = xt;
2327 yt = y1b; y1b = y0b; y0b = yt;
2328 xt = x1; x1 = x0; x0 = xt;
2329 yt = y1; y1 = y0; y0 = yt;
2330
2331 tmp = c1; c1 = c2; c2 = tmp;
2332 wt = startWidth; startWidth = endWidth; endWidth = wt;
2333 }
2334
2335 grada = dya / dxa;
2336 gradb = dyb / dxb;
2337
2338 ix1 = x0; iy1 = y0;
2339 ix2 = x1; iy2 = y1;
2340
2341 yfa = y0a + grada;
2342 yfb = y0b + gradb;
2343
2344 for (x = ix1 + 1; x <= ix2 - 1; x++) {
2345 fraca = yfa - qFloor(yfa);
2346 b1a = 1 - fraca;
2347 b2a = fraca;
2348
2349 fracb = yfb - qFloor(yfb);
2350 b1b = 1 - fracb;
2351 b2b = fracb;
2352
2353 // color first pixel of bottom line
2354 opacity = ((x - ix1) / dstX) * c2.opacityF() + (1 - (x - ix1) / dstX) * c1.opacityF();
2355 c3.setOpacity(opacity);
2356
2357 accessor->moveTo(x, qFloor(yfa));
2358 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfa));
2359
2360 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2361 qreal alpha = cs->opacityF(accessor->rawData());
2362 opacity = b1a * c3.opacityF() + (1 - b1a) * alpha;
2363 col1.setOpacity(opacity);
2364 compositeOnePixel(accessor->rawData(), col1);
2365 }
2366
2367 // color first pixel of top line
2368 if (!(startWidth == 1 && endWidth == 1)) {
2369 accessor->moveTo(x, qFloor(yfb));
2370 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfb));
2371
2372 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2373 qreal alpha = cs->opacityF(accessor->rawData());
2374 opacity = b1b * c3.opacityF() + (1 - b1b) * alpha;
2375 col1.setOpacity(opacity);
2376 compositeOnePixel(accessor->rawData(), col1);
2377 }
2378 }
2379
2380 // color second pixel of bottom line
2381 if (grada != 0 && grada != 1) { // if not flat or exact diagonal
2382
2383 accessor->moveTo(x, qFloor(yfa) + 1);
2384 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfa) + 1);
2385
2386 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2387 qreal alpha = cs->opacityF(accessor->rawData());
2388 opacity = b2a * c3.opacityF() + (1 - b2a) * alpha;
2389 col2.setOpacity(opacity);
2390 compositeOnePixel(accessor->rawData(), col2);
2391 }
2392
2393 }
2394
2395 // color second pixel of top line
2396 if (gradb != 0 && gradb != 1 && !(startWidth == 1 && endWidth == 1)) {
2397
2398 accessor->moveTo(x, qFloor(yfb) + 1);
2399 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yfb) + 1);
2400
2401 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2402 qreal alpha = cs->opacityF(accessor->rawData());
2403 opacity = b2b * c3.opacityF() + (1 - b2b) * alpha;
2404 col2.setOpacity(opacity);
2405 compositeOnePixel(accessor->rawData(), col2);
2406 }
2407
2408 }
2409
2410 // fill remaining pixels
2411 if (!(startWidth == 1 && endWidth == 1)) {
2412 if (yfa < yfb)
2413 for (int i = qFloor(yfa) + 1; i <= qFloor(yfb); i++) {
2414
2415 accessor->moveTo(x, i);
2416 if (selectionAccessor) selectionAccessor->moveTo(x, i);
2417
2418 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2419 compositeOnePixel(accessor->rawData(), c3);
2420 }
2421 }
2422 else
2423 for (int i = qFloor(yfa) + 1; i >= qFloor(yfb); i--) {
2424
2425 accessor->moveTo(x, i);
2426 if (selectionAccessor) selectionAccessor->moveTo(x, i);
2427
2428 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2429 compositeOnePixel(accessor->rawData(), c3);
2430 }
2431 }
2432
2433 }
2434
2435 yfa += grada;
2436 yfb += gradb;
2437 }
2438 } else { // vertical-ish lines
2439 if (y1 < y0) {
2440 int xt, yt, wt;
2441 xt = x1a; x1a = x0a; x0a = xt;
2442 yt = y1a; y1a = y0a; y0a = yt;
2443 xt = x1b; x1b = x0b; x0b = xt;
2444 yt = y1b; y1b = y0b; y0b = yt;
2445 xt = x1; x1 = x0; x0 = xt;
2446 yt = y1; y1 = y0; y0 = yt;
2447
2448 KoColor tmp;
2449 tmp = c1; c1 = c2; c2 = tmp;
2450 wt = startWidth; startWidth = endWidth; endWidth = wt;
2451 }
2452
2453 grada = dxa / dya;
2454 gradb = dxb / dyb;
2455
2456 ix1 = x0; iy1 = y0;
2457 ix2 = x1; iy2 = y1;
2458
2459 xfa = x0a + grada;
2460 xfb = x0b + gradb;
2461
2462 for (y = iy1 + 1; y <= iy2 - 1; y++) {
2463 fraca = xfa - qFloor(xfa);
2464 b1a = 1 - fraca;
2465 b2a = fraca;
2466
2467 fracb = xfb - qFloor(xfb);
2468 b1b = 1 - fracb;
2469 b2b = fracb;
2470
2471 // color first pixel of left line
2472 opacity = ((y - iy1) / dstY) * c2.opacityF() + (1 - (y - iy1) / dstY) * c1.opacityF();
2473 c3.setOpacity(opacity);
2474
2475 accessor->moveTo(qFloor(xfa), y);
2476 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfa), y);
2477
2478 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2479 qreal alpha = cs->opacityF(accessor->rawData());
2480 opacity = b1a * c3.opacityF() + (1 - b1a) * alpha;
2481 col1.setOpacity(opacity);
2482 compositeOnePixel(accessor->rawData(), col1);
2483 }
2484
2485 // color first pixel of right line
2486 if (!(startWidth == 1 && endWidth == 1)) {
2487
2488 accessor->moveTo(qFloor(xfb), y);
2489 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfb), y);
2490
2491 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2492 qreal alpha = cs->opacityF(accessor->rawData());
2493 opacity = b1b * c3.opacityF() + (1 - b1b) * alpha;
2494 col1.setOpacity(opacity);
2495 compositeOnePixel(accessor->rawData(), col1);
2496 }
2497 }
2498
2499 // color second pixel of left line
2500 if (grada != 0 && grada != 1) { // if not flat or exact diagonal
2501
2502 accessor->moveTo(qFloor(xfa) + 1, y);
2503 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfa) + 1, y);
2504
2505 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2506 qreal alpha = cs->opacityF(accessor->rawData());
2507 opacity = b2a * c3.opacityF() + (1 - b2a) * alpha;
2508 col2.setOpacity(opacity);
2509 compositeOnePixel(accessor->rawData(), col2);
2510 }
2511
2512 }
2513
2514 // color second pixel of right line
2515 if (gradb != 0 && gradb != 1 && !(startWidth == 1 && endWidth == 1)) {
2516
2517 accessor->moveTo(qFloor(xfb) + 1, y);
2518 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xfb) + 1, y);
2519
2520 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2521 qreal alpha = cs->opacityF(accessor->rawData());
2522 opacity = b2b * c3.opacityF() + (1 - b2b) * alpha;
2523 col2.setOpacity(opacity);
2524 compositeOnePixel(accessor->rawData(), col2);
2525 }
2526 }
2527
2528 // fill remaining pixels between current xfa,xfb
2529 if (!(startWidth == 1 && endWidth == 1)) {
2530 if (xfa < xfb)
2531 for (int i = qFloor(xfa) + 1; i <= qFloor(xfb); i++) {
2532
2533 accessor->moveTo(i, y);
2534 if (selectionAccessor) selectionAccessor->moveTo(i, y);
2535
2536 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2537 compositeOnePixel(accessor->rawData(), c3);
2538 }
2539 }
2540 else
2541 for (int i = qFloor(xfb); i <= qFloor(xfa) + 1; i++) {
2542
2543 accessor->moveTo(i, y);
2544 if (selectionAccessor) selectionAccessor->moveTo(i, y);
2545
2546 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2547 compositeOnePixel(accessor->rawData(), c3);
2548 }
2549 }
2550 }
2551
2552 xfa += grada;
2553 xfb += gradb;
2554 }
2555 }
2556
2557}
virtual qreal opacityF(const quint8 *pixel) const =0

References compositeOnePixel(), d, KisRandomConstAccessorNG::moveTo(), KisBaseConstAccessor::oldRawData(), KoColor::opacityF(), KoColorSpace::opacityF(), KisBaseAccessor::rawData(), SELECTION_THRESHOLD, and KoColor::setOpacity().

◆ drawWobblyLine()

void KisPainter::drawWobblyLine ( const QPointF & start,
const QPointF & end )

Paint an unstroked, wobbly one-pixel wide line from the specified start to the specified end position.

Definition at line 1813 of file kis_painter.cc.

1814{
1815 KoColor mycolor(d->paintColor);
1816
1817 int x1 = qFloor(start.x());
1818 int y1 = qFloor(start.y());
1819 int x2 = qFloor(end.x());
1820 int y2 = qFloor(end.y());
1821
1822 KisRandomAccessorSP accessor = d->device->createRandomAccessorNG();
1823 KisRandomConstAccessorSP selectionAccessor;
1824 if (d->selection) {
1825 selectionAccessor = d->selection->projection()->createRandomConstAccessorNG();
1826 }
1827
1828 // Width and height of the line
1829 int xd = (x2 - x1);
1830 int yd = (y2 - y1);
1831
1832 int x;
1833 int y;
1834 float fx = (x = x1);
1835 float fy = (y = y1);
1836 float m = (float)yd / (float)xd;
1837 int inc;
1838
1839 if (fabs(m) > 1) {
1840 inc = (yd > 0) ? 1 : -1;
1841 m = 1.0f / m;
1842 m *= inc;
1843 while (y != y2) {
1844 fx = fx + m;
1845 y = y + inc;
1846 x = qRound(fx);
1847
1848 float br1 = qFloor(fx + 1) - fx;
1849 float br2 = fx - qFloor(fx);
1850
1851 accessor->moveTo(x, y);
1852 if (selectionAccessor) selectionAccessor->moveTo(x, y);
1853
1854 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1855 mycolor.setOpacity((quint8)(255*br1));
1856 compositeOnePixel(accessor->rawData(), mycolor);
1857 }
1858
1859 accessor->moveTo(x + 1, y);
1860 if (selectionAccessor) selectionAccessor->moveTo(x + 1, y);
1861
1862 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1863 mycolor.setOpacity((quint8)(255*br2));
1864 compositeOnePixel(accessor->rawData(), mycolor);
1865 }
1866 }
1867 } else {
1868 inc = (xd > 0) ? 1 : -1;
1869 m *= inc;
1870 while (x != x2) {
1871 fy = fy + m;
1872 x = x + inc;
1873 y = qRound(fy);
1874
1875 float br1 = qFloor(fy + 1) - fy;
1876 float br2 = fy - qFloor(fy);
1877
1878 accessor->moveTo(x, y);
1879 if (selectionAccessor) selectionAccessor->moveTo(x, y);
1880
1881 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1882 mycolor.setOpacity((quint8)(255*br1));
1883 compositeOnePixel(accessor->rawData(), mycolor);
1884 }
1885
1886 accessor->moveTo(x, y + 1);
1887 if (selectionAccessor) selectionAccessor->moveTo(x, y + 1);
1888
1889 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1890 mycolor.setOpacity((quint8)(255*br2));
1891 compositeOnePixel(accessor->rawData(), mycolor);
1892 }
1893 }
1894 }
1895
1896}

References compositeOnePixel(), d, KisRandomConstAccessorNG::moveTo(), KisBaseConstAccessor::oldRawData(), KisBaseAccessor::rawData(), SELECTION_THRESHOLD, and KoColor::setOpacity().

◆ drawWuLine()

void KisPainter::drawWuLine ( const QPointF & start,
const QPointF & end )

Paint an unstroked, anti-aliased one-pixel wide line from the specified start to the specified end position using the Wu algorithm

Definition at line 1898 of file kis_painter.cc.

1899{
1900 KoColor lineColor(d->paintColor);
1901
1902 int x1 = qFloor(start.x());
1903 int y1 = qFloor(start.y());
1904 int x2 = qFloor(end.x());
1905 int y2 = qFloor(end.y());
1906
1907 KisRandomAccessorSP accessor = d->device->createRandomAccessorNG();
1908 KisRandomConstAccessorSP selectionAccessor;
1909 if (d->selection) {
1910 selectionAccessor = d->selection->projection()->createRandomConstAccessorNG();
1911 }
1912
1913 float grad, xd, yd;
1914 float xgap, ygap, xend, yend, yf, xf;
1915 float brightness1, brightness2;
1916
1917 int ix1, ix2, iy1, iy2;
1918 quint8 c1, c2;
1919
1920 // gradient of line
1921 xd = (x2 - x1);
1922 yd = (y2 - y1);
1923
1924 if (yd == 0) {
1925 /* Horizontal line */
1926 int incr = (x1 < x2) ? 1 : -1;
1927 ix1 = x1;
1928 ix2 = x2;
1929 iy1 = y1;
1930 while (ix1 != ix2) {
1931 ix1 = ix1 + incr;
1932
1933 accessor->moveTo(ix1, iy1);
1934 if (selectionAccessor) selectionAccessor->moveTo(ix1, iy1);
1935
1936 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1937 compositeOnePixel(accessor->rawData(), lineColor);
1938 }
1939 }
1940 return;
1941 }
1942
1943 if (xd == 0) {
1944 /* Vertical line */
1945 int incr = (y1 < y2) ? 1 : -1;
1946 iy1 = y1;
1947 iy2 = y2;
1948 ix1 = x1;
1949 while (iy1 != iy2) {
1950 iy1 = iy1 + incr;
1951
1952 accessor->moveTo(ix1, iy1);
1953 if (selectionAccessor) selectionAccessor->moveTo(ix1, iy1);
1954
1955 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1956 compositeOnePixel(accessor->rawData(), lineColor);
1957 }
1958 }
1959 return;
1960 }
1961
1962 if (fabs(xd) > fabs(yd)) {
1963 // horizontal line
1964 // line have to be paint from left to right
1965 if (x1 > x2) {
1966 std::swap(x1, x2);
1967 std::swap(y1, y2);
1968 xd = (x2 - x1);
1969 yd = (y2 - y1);
1970 }
1971 grad = yd / xd;
1972 // nearest X,Y integer coordinates
1973 xend = x1;
1974 yend = y1 + grad * (xend - x1);
1975
1976 xgap = invertFrac(x1 + 0.5f);
1977
1978 ix1 = x1;
1979 iy1 = qFloor(yend);
1980
1981 // calc the intensity of the other end point pixel pair.
1982 brightness1 = invertFrac(yend) * xgap;
1983 brightness2 = frac(yend) * xgap;
1984
1985 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
1986 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
1987
1988 accessor->moveTo(ix1, iy1);
1989 if (selectionAccessor) selectionAccessor->moveTo(ix1, iy1);
1990
1991 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
1992 lineColor.setOpacity(c1);
1993 compositeOnePixel(accessor->rawData(), lineColor);
1994 }
1995
1996 accessor->moveTo(ix1, iy1 + 1);
1997 if (selectionAccessor) selectionAccessor->moveTo(ix1, iy1 + 1);
1998
1999 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2000 lineColor.setOpacity(c2);
2001 compositeOnePixel(accessor->rawData(), lineColor);
2002 }
2003
2004 // calc first Y-intersection for main loop
2005 yf = yend + grad;
2006
2007 xend = x2;
2008 yend = y2 + grad * (xend - x2);
2009
2010 xgap = invertFrac(x2 - 0.5f);
2011
2012 ix2 = x2;
2013 iy2 = qFloor(yend);
2014
2015 brightness1 = invertFrac(yend) * xgap;
2016 brightness2 = frac(yend) * xgap;
2017
2018 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
2019 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
2020
2021 accessor->moveTo(ix2, iy2);
2022 if (selectionAccessor) selectionAccessor->moveTo(ix2, iy2);
2023
2024 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2025 lineColor.setOpacity(c1);
2026 compositeOnePixel(accessor->rawData(), lineColor);
2027 }
2028
2029 accessor->moveTo(ix2, iy2 + 1);
2030 if (selectionAccessor) selectionAccessor->moveTo(ix2, iy2 + 1);
2031
2032 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2033 lineColor.setOpacity(c2);
2034 compositeOnePixel(accessor->rawData(), lineColor);
2035 }
2036
2037 // main loop
2038 for (int x = ix1 + 1; x <= ix2 - 1; x++) {
2039 brightness1 = invertFrac(yf);
2040 brightness2 = frac(yf);
2041 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
2042 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
2043
2044 accessor->moveTo(x, qFloor(yf));
2045 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yf));
2046
2047 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2048 lineColor.setOpacity(c1);
2049 compositeOnePixel(accessor->rawData(), lineColor);
2050 }
2051
2052 accessor->moveTo(x, qFloor(yf) + 1);
2053 if (selectionAccessor) selectionAccessor->moveTo(x, qFloor(yf) + 1);
2054
2055 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2056 lineColor.setOpacity(c2);
2057 compositeOnePixel(accessor->rawData(), lineColor);
2058 }
2059
2060 yf = yf + grad;
2061 }
2062 } else {
2063 //vertical
2064 // line have to be painted from left to right
2065 if (y1 > y2) {
2066 std::swap(x1, x2);
2067 std::swap(y1, y2);
2068 xd = (x2 - x1);
2069 yd = (y2 - y1);
2070 }
2071
2072 grad = xd / yd;
2073
2074 // nearest X,Y integer coordinates
2075 yend = y1;
2076 xend = x1 + grad * (yend - y1);
2077
2078 ygap = y1;
2079
2080 ix1 = qFloor(xend);
2081 iy1 = y1;
2082
2083 // calc the intensity of the other end point pixel pair.
2084 brightness1 = invertFrac(xend) * ygap;
2085 brightness2 = frac(xend) * ygap;
2086
2087 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
2088 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
2089
2090 accessor->moveTo(ix1, iy1);
2091 if (selectionAccessor) selectionAccessor->moveTo(ix1, iy1);
2092
2093 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2094 lineColor.setOpacity(c1);
2095 compositeOnePixel(accessor->rawData(), lineColor);
2096 }
2097
2098 accessor->moveTo(x1 + 1, y1);
2099 if (selectionAccessor) selectionAccessor->moveTo(x1 + 1, y1);
2100
2101 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2102 lineColor.setOpacity(c2);
2103 compositeOnePixel(accessor->rawData(), lineColor);
2104 }
2105
2106 // calc first Y-intersection for main loop
2107 xf = xend + grad;
2108
2109 yend = y2;
2110 xend = x2 + grad * (yend - y2);
2111
2112 ygap = invertFrac(y2 - 0.5f);
2113
2114 ix2 = qFloor(xend);
2115 iy2 = y2;
2116
2117 brightness1 = invertFrac(xend) * ygap;
2118 brightness2 = frac(xend) * ygap;
2119
2120 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
2121 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
2122
2123 accessor->moveTo(ix2, iy2);
2124 if (selectionAccessor) selectionAccessor->moveTo(ix2, iy2);
2125
2126 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2127 lineColor.setOpacity(c1);
2128 compositeOnePixel(accessor->rawData(), lineColor);
2129 }
2130
2131 accessor->moveTo(ix2 + 1, iy2);
2132 if (selectionAccessor) selectionAccessor->moveTo(ix2 + 1, iy2);
2133
2134 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2135 lineColor.setOpacity(c2);
2136 compositeOnePixel(accessor->rawData(), lineColor);
2137 }
2138
2139 // main loop
2140 for (int y = iy1 + 1; y <= iy2 - 1; y++) {
2141 brightness1 = invertFrac(xf);
2142 brightness2 = frac(xf);
2143 c1 = (int)(brightness1 * OPACITY_OPAQUE_U8);
2144 c2 = (int)(brightness2 * OPACITY_OPAQUE_U8);
2145
2146 accessor->moveTo(qFloor(xf), y);
2147 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xf), y);
2148
2149 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2150 lineColor.setOpacity(c1);
2151 compositeOnePixel(accessor->rawData(), lineColor);
2152 }
2153
2154 accessor->moveTo(qFloor(xf) + 1, y);
2155 if (selectionAccessor) selectionAccessor->moveTo(qFloor(xf) + 1, y);
2156
2157 if (!selectionAccessor || *selectionAccessor->oldRawData() > SELECTION_THRESHOLD) {
2158 lineColor.setOpacity(c2);
2159 compositeOnePixel(accessor->rawData(), lineColor);
2160 }
2161
2162 xf = xf + grad;
2163 }
2164 }//end-of-else
2165
2166}
float invertFrac(float value)
float frac(float value)

References compositeOnePixel(), d, frac(), invertFrac(), KisRandomConstAccessorNG::moveTo(), KisBaseConstAccessor::oldRawData(), OPACITY_OPAQUE_U8, KisBaseAccessor::rawData(), SELECTION_THRESHOLD, and KoColor::setOpacity().

◆ end()

void KisPainter::end ( )

Finish painting on the current device

Definition at line 311 of file kis_painter.cc.

312{
313 Q_ASSERT_X(!d->transaction, "KisPainter::end()",
314 "end() was called for the painter having a transaction. "
315 "Please use end/deleteTransaction() instead");
316}

References d.

◆ endAndTakeTransaction()

KUndo2Command * KisPainter::endAndTakeTransaction ( )

Finishes a transaction and returns a pointer to its undo command

Definition at line 360 of file kis_painter.cc.

361{
362 Q_ASSERT_X(d->transaction, "KisPainter::endTransaction()",
363 "No transaction is in progress");
364
365 KUndo2Command *transactionData = d->transaction->endAndTake();
366 delete d->transaction;
367 d->transaction = 0;
368
369 return transactionData;
370}

References d.

◆ endTransaction() [1/2]

void KisPainter::endTransaction ( KisPostExecutionUndoAdapter * undoAdapter)

Finish transaction and load it to a special adapter for strokes

Definition at line 350 of file kis_painter.cc.

351{
352 Q_ASSERT_X(d->transaction, "KisPainter::endTransaction()",
353 "No transaction is in progress");
354
355 d->transaction->commit(undoAdapter);
356 delete d->transaction;
357 d->transaction = 0;
358}

References d.

◆ endTransaction() [2/2]

void KisPainter::endTransaction ( KisUndoAdapter * undoAdapter)

Finish the undoable paint operation.

Definition at line 340 of file kis_painter.cc.

341{
342 Q_ASSERT_X(d->transaction, "KisPainter::endTransaction()",
343 "No transaction is in progress");
344
345 d->transaction->commit(undoAdapter);
346 delete d->transaction;
347 d->transaction = 0;
348}

References d.

◆ fill()

void KisPainter::fill ( qint32 x,
qint32 y,
qint32 width,
qint32 height,
const KoColor & color )

fills a region of width width and height height of the current paint device with the color color. x and y set the x and y positions of the origin top-left corner.

Parameters
xthe destination x-coordinate
ythe destination y-coordinate
widththe width of the region to be manipulated
heightthe height of the region to be manipulated
colorthe color the area is filled with

Definition at line 851 of file kis_painter.cc.

852{
853 /* This check for nonsense ought to be a Q_ASSERT. However, when paintops are just
854 * initializing they perform some dummy passes with those parameters, and it must not crash */
855 if(width == 0 || height == 0 || d->device.isNull())
856 return;
857
858 KoColor srcColor(color, d->device->compositionSourceColorSpace());
859 const KoCompositeOp *compositeOp = d->compositeOp(srcColor.colorSpace());
860
861 qint32 dstY = y;
862 qint32 rowsRemaining = height;
863
864 KisRandomAccessorSP dstIt = d->device->createRandomAccessorNG();
865
866 if(d->selection) {
867 KisPaintDeviceSP selectionProjection(d->selection->projection());
868 KisRandomConstAccessorSP maskIt = selectionProjection->createRandomConstAccessorNG();
869
870 while(rowsRemaining > 0) {
871
872 qint32 dstX = x;
873 qint32 columnsRemaining = width;
874 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY);
875 qint32 numContiguousSelRows = maskIt->numContiguousRows(dstY);
876 qint32 rows = qMin(numContiguousDstRows, numContiguousSelRows);
877 rows = qMin(rows, rowsRemaining);
878
879 while (columnsRemaining > 0) {
880
881 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX);
882 qint32 numContiguousSelColumns = maskIt->numContiguousColumns(dstX);
883
884 qint32 columns = qMin(numContiguousDstColumns, numContiguousSelColumns);
885 columns = qMin(columns, columnsRemaining);
886
887 qint32 dstRowStride = dstIt->rowStride(dstX, dstY);
888 dstIt->moveTo(dstX, dstY);
889 qint32 maskRowStride = maskIt->rowStride(dstX, dstY);
890
891 maskIt->moveTo(dstX, dstY);
892
893 d->paramInfo.dstRowStart = dstIt->rawData();
894 d->paramInfo.dstRowStride = dstRowStride;
895 d->paramInfo.srcRowStart = srcColor.data();
896 d->paramInfo.srcRowStride = 0; // srcRowStride is set to zero to use the compositeOp with only a single color pixel
897 d->paramInfo.maskRowStart = maskIt->oldRawData();
898 d->paramInfo.maskRowStride = maskRowStride;
899 d->paramInfo.rows = rows;
900 d->paramInfo.cols = columns;
901 d->colorSpace->bitBlt(srcColor.colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
902
903 dstX += columns;
904 columnsRemaining -= columns;
905 }
906
907 dstY += rows;
908 rowsRemaining -= rows;
909 }
910 }
911 else {
912
913 while(rowsRemaining > 0) {
914
915 qint32 dstX = x;
916 qint32 columnsRemaining = width;
917 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY);
918 qint32 rows = qMin(numContiguousDstRows, rowsRemaining);
919
920 while(columnsRemaining > 0) {
921
922 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX);
923 qint32 columns = qMin(numContiguousDstColumns, columnsRemaining);
924 qint32 dstRowStride = dstIt->rowStride(dstX, dstY);
925 dstIt->moveTo(dstX, dstY);
926
927 d->paramInfo.dstRowStart = dstIt->rawData();
928 d->paramInfo.dstRowStride = dstRowStride;
929 d->paramInfo.srcRowStart = srcColor.data();
930 d->paramInfo.srcRowStride = 0; // srcRowStride is set to zero to use the compositeOp with only a single color pixel
931 d->paramInfo.maskRowStart = 0;
932 d->paramInfo.maskRowStride = 0;
933 d->paramInfo.rows = rows;
934 d->paramInfo.cols = columns;
935 d->colorSpace->bitBlt(srcColor.colorSpace(), d->paramInfo, compositeOp, d->renderingIntent, d->conversionFlags);
936
937 dstX += columns;
938 columnsRemaining -= columns;
939 }
940
941 dstY += rows;
942 rowsRemaining -= rows;
943 }
944 }
945
946 addDirtyRect(QRect(x, y, width, height));
947}

References addDirtyRect(), KoColor::colorSpace(), compositeOp(), KisPaintDevice::createRandomConstAccessorNG(), d, KoColor::data(), KisRandomConstAccessorNG::moveTo(), KisRandomConstAccessorNG::numContiguousColumns(), KisRandomConstAccessorNG::numContiguousRows(), KisBaseConstAccessor::oldRawData(), KisBaseAccessor::rawData(), and KisRandomConstAccessorNG::rowStride().

◆ fillPainterPath() [1/2]

void KisPainter::fillPainterPath ( const QPainterPath & path)

Fills the area enclosed by the given QPainterPath Convenience method for fillPainterPath(path, rect)

Definition at line 1427 of file kis_painter.cc.

1428{
1429 fillPainterPath(path, QRect());
1430}
void fillPainterPath(const QPainterPath &path)

References fillPainterPath().

◆ fillPainterPath() [2/2]

void KisPainter::fillPainterPath ( const QPainterPath & path,
const QRect & requestedRect )

Fills the portion of an area enclosed by the given QPainterPath

Parameters
paththe portion of the path to fill
requestedRectthe rectangle containing the area

Definition at line 1432 of file kis_painter.cc.

1433{
1434 if (d->mirrorHorizontally || d->mirrorVertically) {
1435 KisLodTransform lod(d->device);
1436 QPointF effectiveAxesCenter = lod.map(d->axesCenter);
1437
1438 QTransform C1 = QTransform::fromTranslate(-effectiveAxesCenter.x(), -effectiveAxesCenter.y());
1439 QTransform C2 = QTransform::fromTranslate(effectiveAxesCenter.x(), effectiveAxesCenter.y());
1440
1441 QTransform t;
1442 QPainterPath newPath;
1443 QRect newRect;
1444
1445 if (d->mirrorHorizontally) {
1446 t = C1 * QTransform::fromScale(-1,1) * C2;
1447 newPath = t.map(path);
1448 newRect = t.mapRect(requestedRect);
1449 d->fillPainterPathImpl(newPath, newRect);
1450 }
1451
1452 if (d->mirrorVertically) {
1453 t = C1 * QTransform::fromScale(1,-1) * C2;
1454 newPath = t.map(path);
1455 newRect = t.mapRect(requestedRect);
1456 d->fillPainterPathImpl(newPath, newRect);
1457 }
1458
1459 if (d->mirrorHorizontally && d->mirrorVertically) {
1460 t = C1 * QTransform::fromScale(-1,-1) * C2;
1461 newPath = t.map(path);
1462 newRect = t.mapRect(requestedRect);
1463 d->fillPainterPathImpl(newPath, newRect);
1464 }
1465 }
1466
1467 d->fillPainterPathImpl(path, requestedRect);
1468}

References d, and KisLodTransform::map().

◆ fillPainterPathImpl()

void KisPainter::fillPainterPathImpl ( const QPainterPath & path,
const QRect & requestedRect )

◆ fillPolygon()

void KisPainter::fillPolygon ( const vQPointF & points,
FillStyle fillStyle )
protected

Fill the polygon defined by points with the fillStyle.

Definition at line 1327 of file kis_painter.cc.

1328{
1329 if (points.count() < 3) {
1330 return;
1331 }
1332
1333 if (fillStyle == FillStyleNone) {
1334 return;
1335 }
1336
1337 QPainterPath polygonPath;
1338
1339 polygonPath.moveTo(points.at(0));
1340
1341 for (int pointIndex = 1; pointIndex < points.count(); pointIndex++) {
1342 polygonPath.lineTo(points.at(pointIndex));
1343 }
1344
1345 polygonPath.closeSubpath();
1346
1347 d->fillStyle = fillStyle;
1348 fillPainterPath(polygonPath);
1349}
FillStyle fillStyle

References d, fillPainterPath(), fillStyle, and FillStyleNone.

◆ fillStyle()

FillStyle KisPainter::fillStyle ( ) const

Returns the current fill style.

◆ flow()

qreal KisPainter::flow ( ) const

Definition at line 2682 of file kis_painter.cc.

2683{
2684 return d->paramInfo.flow;
2685}

References d.

◆ frac()

float KisPainter::frac ( float value)
inlineprivate

Definition at line 874 of file kis_painter.h.

874 {
875 float tmp = 0;
876 return modff(value , &tmp);
877 }
float value(const T *src, size_t ch)

References value().

◆ generator()

const KisFilterConfigurationSP KisPainter::generator ( ) const
Returns
the current generator configuration

◆ getBezierCurvePoints()

void KisPainter::getBezierCurvePoints ( const QPointF & pos1,
const QPointF & control1,
const QPointF & control2,
const QPointF & pos2,
vQPointF & points ) const

Fill the given vector points with the points needed to draw the Bezier curve between pos1 and pos2 using control points control1 and control2, excluding the final pos2.

Definition at line 1226 of file kis_painter.cc.

1231{
1232 ::getBezierCurvePoints(toKisVector2D(pos1), toKisVector2D(control1), toKisVector2D(control2), toKisVector2D(pos2), points);
1233}
void getBezierCurvePoints(const QPointF &pos1, const QPointF &control1, const QPointF &control2, const QPointF &pos2, vQPointF &points) const
KisVector2D toKisVector2D(const QPointF &p)
Definition kis_vec.h:19

References getBezierCurvePoints(), and toKisVector2D().

◆ gradient()

const KoAbstractGradientSP KisPainter::gradient ( ) const

◆ hasDirtyRegion()

bool KisPainter::hasDirtyRegion ( ) const
Returns
true if the painter has some rects marked as dirty
See also
takeDirtyRegion(), addDirtyRect()

Definition at line 3075 of file kis_painter.cc.

3076{
3077 return !d->dirtyRects.isEmpty();
3078}

References d.

◆ hasHorizontalMirroring()

bool KisPainter::hasHorizontalMirroring ( ) const

Indicates if horizontal mirroring mode is activated

Definition at line 2821 of file kis_painter.cc.

2822{
2823 return d->mirrorHorizontally;
2824}

References d.

◆ hasMirroring()

bool KisPainter::hasMirroring ( ) const

Returns whether the mirroring methods will do any work when called

Definition at line 2816 of file kis_painter.cc.

2817{
2818 return d->mirrorHorizontally || d->mirrorVertically;
2819}

References d.

◆ hasVerticalMirroring()

bool KisPainter::hasVerticalMirroring ( ) const

Indicates if vertical mirroring mode is activated

Definition at line 2826 of file kis_painter.cc.

2827{
2828 return d->mirrorVertically;
2829}

References d.

◆ init()

void KisPainter::init ( )
protected

Initialize, set everything to '0' or defaults.

Definition at line 84 of file kis_painter.cc.

85{
86 d->paramInfo = KoCompositeOp::ParameterInfo();
89 d->patternTransform = QTransform();
90}

References d, KoColorConversionTransformation::internalConversionFlags(), and KoColorConversionTransformation::internalRenderingIntent().

◆ invertFrac()

float KisPainter::invertFrac ( float value)
inlineprivate

Definition at line 879 of file kis_painter.h.

879 {
880 float tmp = 0;
881 return 1.0f - modff(value , &tmp);
882 }

References value().

◆ isOpacityUnit()

bool KisPainter::isOpacityUnit ( ) const

◆ mirrorDab()

void KisPainter::mirrorDab ( Qt::Orientation direction,
KisRenderedDab * dab,
bool skipMirrorPixels = false ) const

Mirror dab in the requested direction around the center point defined in the painter. The dab's offset is adjusted automatically.

Definition at line 3088 of file kis_painter.cc.

3089{
3090 KisLodTransform t(d->device);
3091 QPointF effectiveAxesCenter = t.map(d->axesCenter);
3092
3093 KritaUtils::mirrorDab(direction, effectiveAxesCenter, dab, skipMirrorPixels);
3094}
void mirrorDab(Qt::Orientation dir, const QPoint &center, KisRenderedDab *dab, bool skipMirrorPixels)

References d, KisLodTransform::map(), and KritaUtils::mirrorDab().

◆ mirrorRect()

void KisPainter::mirrorRect ( Qt::Orientation direction,
QRect * rc ) const

Mirror rc in the requested direction around the center point defined in the painter.

Definition at line 3080 of file kis_painter.cc.

3081{
3082 KisLodTransform t(d->device);
3083 QPoint effectiveAxesCenter = t.map(d->axesCenter).toPoint();
3084
3085 KritaUtils::mirrorRect(direction, effectiveAxesCenter, rc);
3086}
void mirrorRect(Qt::Orientation dir, const QPoint &center, QRect *rc)

References d, KisLodTransform::map(), and KritaUtils::mirrorRect().

◆ opacityF()

qreal KisPainter::opacityF ( ) const

Returns the opacity that is used in painting.

Definition at line 2719 of file kis_painter.cc.

2720{
2721 return d->paramInfo.opacity;
2722}

References d.

◆ operator=()

KisPainter & KisPainter::operator= ( const KisPainter & )
private

◆ paintAt()

void KisPainter::paintAt ( const KisPaintInformation & pos,
KisDistanceInformation * savedDist )

Draw a spot at pos using the currently set paint op, brush and color

Definition at line 1319 of file kis_painter.cc.

1321{
1322 if (d->paintOp && d->paintOp->canPaint()) {
1323 d->paintOp->paintAt(pi, savedDist);
1324 }
1325}

References d.

◆ paintBezierCurve()

void KisPainter::paintBezierCurve ( const KisPaintInformation & pi1,
const QPointF & control1,
const QPointF & control2,
const KisPaintInformation & pi2,
KisDistanceInformation * currentDistance )

Draw a Bezier curve between pi1 and pi2 using control points control1 and control2. If savedDist is less than zero, the brush is painted at pos1 before being painted along the curve using the spacing setting.

Returns
the drag distance, that is the remains of the distance between pi1 and pi2 not covered because the currently set brush has a spacing greater than that distance.

Definition at line 1235 of file kis_painter.cc.

1240{
1241 if (d->paintOp && d->paintOp->canPaint()) {
1242 d->paintOp->paintBezierCurve(pi1, control1, control2, pi2, currentDistance);
1243 }
1244}

References d.

◆ paintColor()

const KoColor & KisPainter::paintColor ( ) const

Returns the color that will be used to paint with.

◆ paintEllipse() [1/2]

void KisPainter::paintEllipse ( const qreal x,
const qreal y,
const qreal w,
const qreal h )

Paint the ellipse that fills the given rectangle.

Parameters
xx coordinate of the top-left corner
yy coordinate of the top-left corner
wthe rectangle width
hthe rectangle height

Definition at line 1311 of file kis_painter.cc.

1315{
1316 paintEllipse(QRectF(x, y, w, h));
1317}
void paintEllipse(const QRectF &rect)

References paintEllipse().

◆ paintEllipse() [2/2]

void KisPainter::paintEllipse ( const QRectF & rect)

Paint the ellipse that fills the given rectangle.

Parameters
rectthe rectangle containing the ellipse to paint.

Definition at line 1269 of file kis_painter.cc.

1270{
1271 QRectF r = rect.normalized(); // normalize before checking as negative width and height are empty too
1272 if (r.isEmpty()) return;
1273
1274 // See http://www.whizkidtech.redprince.net/bezier/circle/ for explanation.
1275 // kappa = (4/3*(sqrt(2)-1))
1276 const qreal kappa = 0.5522847498;
1277 const qreal lx = (r.width() / 2) * kappa;
1278 const qreal ly = (r.height() / 2) * kappa;
1279
1280 QPointF center = r.center();
1281
1282 QPointF p0(r.left(), center.y());
1283 QPointF p1(r.left(), center.y() - ly);
1284 QPointF p2(center.x() - lx, r.top());
1285 QPointF p3(center.x(), r.top());
1286
1287 vQPointF points;
1288
1289 getBezierCurvePoints(p0, p1, p2, p3, points);
1290
1291 QPointF p4(center.x() + lx, r.top());
1292 QPointF p5(r.right(), center.y() - ly);
1293 QPointF p6(r.right(), center.y());
1294
1295 getBezierCurvePoints(p3, p4, p5, p6, points);
1296
1297 QPointF p7(r.right(), center.y() + ly);
1298 QPointF p8(center.x() + lx, r.bottom());
1299 QPointF p9(center.x(), r.bottom());
1300
1301 getBezierCurvePoints(p6, p7, p8, p9, points);
1302
1303 QPointF p10(center.x() - lx, r.bottom());
1304 QPointF p11(r.left(), center.y() + ly);
1305
1306 getBezierCurvePoints(p9, p10, p11, p0, points);
1307
1308 paintPolygon(points);
1309}
QPointF p0
QPointF p2
QPointF p3
QPointF p1
void paintPolygon(const vQPointF &points)

References getBezierCurvePoints(), p0, p1, p2, p3, and paintPolygon().

◆ paintLine()

void KisPainter::paintLine ( const KisPaintInformation & pi1,
const KisPaintInformation & pi2,
KisDistanceInformation * currentDistance )

Draw a line between pos1 and pos2 using the currently set brush and color. If savedDist is less than zero, the brush is painted at pos1 before being painted along the line using the spacing setting.

Returns
the drag distance, that is the remains of the distance between p1 and p2 not covered because the currently set brush has a spacing greater than that distance.

Definition at line 1151 of file kis_painter.cc.

1154{
1155 if (d->device && d->paintOp && d->paintOp->canPaint()) {
1156 d->paintOp->paintLine(pi1, pi2, currentDistance);
1157 }
1158}

References d.

◆ paintOp()

KisPaintOp * KisPainter::paintOp ( ) const

Return the active paintop (which is created based on the specified preset and will be deleted as soon as the KisPainter instance dies).

◆ paintPainterPath()

void KisPainter::paintPainterPath ( const QPainterPath & path)

Stroke the given QPainterPath.

Definition at line 1380 of file kis_painter.cc.

1381{
1382 if (d->fillStyle != FillStyleNone) {
1383 fillPainterPath(path);
1384 }
1385
1386 if (d->strokeStyle == StrokeStyleNone) return;
1387
1388 QPointF lastPoint, nextPoint;
1389 int elementCount = path.elementCount();
1390 KisDistanceInformation saveDist;
1391
1394
1395 auto point = [rnd, strokeRnd] (const QPointF &pt) {
1396 KisPaintInformation pi(pt);
1397 pi.setRandomSource(rnd);
1398 pi.setPerStrokeRandomSource(strokeRnd);
1399 return pi;
1400 };
1401
1402 for (int i = 0; i < elementCount; i++) {
1403 QPainterPath::Element element = path.elementAt(i);
1404 switch (element.type) {
1405 case QPainterPath::MoveToElement:
1406 lastPoint = QPointF(element.x, element.y);
1407 break;
1408 case QPainterPath::LineToElement:
1409 nextPoint = QPointF(element.x, element.y);
1410 paintLine(point(lastPoint), point(nextPoint), &saveDist);
1411 lastPoint = nextPoint;
1412 break;
1413 case QPainterPath::CurveToElement:
1414 nextPoint = QPointF(path.elementAt(i + 2).x, path.elementAt(i + 2).y);
1415 paintBezierCurve(point(lastPoint),
1416 QPointF(path.elementAt(i).x, path.elementAt(i).y),
1417 QPointF(path.elementAt(i + 1).x, path.elementAt(i + 1).y),
1418 point(nextPoint), &saveDist);
1419 lastPoint = nextPoint;
1420 break;
1421 default:
1422 continue;
1423 }
1424 }
1425}
void paintBezierCurve(const KisPaintInformation &pi1, const QPointF &control1, const QPointF &control2, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)
void paintLine(const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)

References d, fillPainterPath(), FillStyleNone, paintBezierCurve(), paintLine(), KisPaintInformation::setPerStrokeRandomSource(), KisPaintInformation::setRandomSource(), and StrokeStyleNone.

◆ paintPolygon()

void KisPainter::paintPolygon ( const vQPointF & points)

Paint the polygon with the points given in points. It automatically closes the polygon by drawing the line from the last point to the first.

Definition at line 1351 of file kis_painter.cc.

1352{
1353 if (d->fillStyle != FillStyleNone) {
1354 fillPolygon(points, d->fillStyle);
1355 }
1356
1357 if (d->strokeStyle != StrokeStyleNone) {
1358 if (points.count() > 1) {
1360 KisAlgebra2D::directionBetweenPoints(points[0], points[1], 0.0));
1361
1364
1365 auto point = [rnd, strokeRnd] (const QPointF &pt) {
1366 KisPaintInformation pi(pt);
1367 pi.setRandomSource(rnd);
1368 pi.setPerStrokeRandomSource(strokeRnd);
1369 return pi;
1370 };
1371
1372 for (int i = 0; i < points.count() - 1; i++) {
1373 paintLine(point(points[i]), point(points[i + 1]), &distance);
1374 }
1375 paintLine(point(points[points.count() - 1]), point(points[0]), &distance);
1376 }
1377 }
1378}
qreal distance(const QPointF &p1, const QPointF &p2)
void fillPolygon(const vQPointF &points, FillStyle fillStyle)
Fill the polygon defined by points with the fillStyle.
qreal directionBetweenPoints(const QPointF &p1, const QPointF &p2, qreal defaultAngle)

References d, KisAlgebra2D::directionBetweenPoints(), distance(), fillPolygon(), FillStyleNone, paintLine(), KisPaintInformation::setPerStrokeRandomSource(), KisPaintInformation::setRandomSource(), and StrokeStyleNone.

◆ paintPolyline()

void KisPainter::paintPolyline ( const QVector< QPointF > & points,
int index = 0,
int numPoints = -1 )

Paint a line that connects the dots in points

Definition at line 1161 of file kis_painter.cc.

1163{
1164 if (d->fillStyle != FillStyleNone) {
1165 fillPolygon(points, d->fillStyle);
1166 }
1167
1168 if (d->strokeStyle == StrokeStyleNone) return;
1169
1170 if (index >= points.count())
1171 return;
1172
1173 if (numPoints < 0)
1174 numPoints = points.count();
1175
1176 if (index + numPoints > points.count())
1177 numPoints = points.count() - index;
1178
1179 if (numPoints > 1) {
1182
1183 auto point = [rnd, strokeRnd] (const QPointF &pt) {
1184 KisPaintInformation pi(pt);
1185 pi.setRandomSource(rnd);
1186 pi.setPerStrokeRandomSource(strokeRnd);
1187 return pi;
1188 };
1189
1190 KisDistanceInformation saveDist(points[0],
1191 KisAlgebra2D::directionBetweenPoints(points[0], points[1], 0.0));
1192 for (int i = index; i < index + numPoints - 1; i++) {
1193 paintLine(point(points[i]), point(points[i + 1]), &saveDist);
1194 }
1195 }
1196
1197}

References d, KisAlgebra2D::directionBetweenPoints(), fillPolygon(), FillStyleNone, paintLine(), KisPaintInformation::setPerStrokeRandomSource(), KisPaintInformation::setRandomSource(), and StrokeStyleNone.

◆ paintRect() [1/2]

void KisPainter::paintRect ( const qreal x,
const qreal y,
const qreal w,
const qreal h )

Paint a rectangle.

Parameters
xx coordinate of the top-left corner
yy coordinate of the top-left corner
wthe rectangle width
hthe rectangle height

Definition at line 1261 of file kis_painter.cc.

1265{
1266 paintRect(QRectF(x, y, w, h));
1267}
void paintRect(const QRectF &rect)

References paintRect().

◆ paintRect() [2/2]

void KisPainter::paintRect ( const QRectF & rect)

Paint a rectangle.

Parameters
rectthe rectangle to paint.

Definition at line 1247 of file kis_painter.cc.

1248{
1249 QRectF normalizedRect = rect.normalized();
1250
1251 vQPointF points;
1252
1253 points.push_back(normalizedRect.topLeft());
1254 points.push_back(normalizedRect.bottomLeft());
1255 points.push_back(normalizedRect.bottomRight());
1256 points.push_back(normalizedRect.topRight());
1257
1258 paintPolygon(points);
1259}

References paintPolygon().

◆ pattern()

const KoPatternSP KisPainter::pattern ( ) const

Returns the currently set pattern.

◆ patternTransform()

QTransform KisPainter::patternTransform ( )

get the current transform on the pattern.

◆ preset()

KisPaintOpPresetSP KisPainter::preset ( ) const

Return the paintop preset.

Definition at line 2792 of file kis_painter.cc.

2793{
2794 return d->paintOpPreset;
2795}

References d.

◆ Private() [1/2]

KisPainter::Private ( KisPainter * _q)
inline

Definition at line 22 of file kis_painter_p.h.

22: q(_q) {}
KisPainter * q

◆ Private() [2/2]

KisPainter::Private ( KisPainter * _q,
const KoColorSpace * cs )
inline

Definition at line 23 of file kis_painter_p.h.

24 : q(_q), paintColor(cs), backgroundColor(cs) {}
KoColor backgroundColor

◆ progressUpdater()

KoUpdater * KisPainter::progressUpdater ( )
protected

◆ putTransaction()

void KisPainter::putTransaction ( KisTransaction * transaction)

continue a transaction started somewhere else

Definition at line 380 of file kis_painter.cc.

381{
382 Q_ASSERT_X(!d->transaction, "KisPainter::putTransaction()",
383 "You asked for a new transaction while still having "
384 "another one. Please finish the first one with "
385 "end/deleteTransaction() first");
386
387 d->transaction = transaction;
388}
KisTransaction * transaction

References d, and transaction.

◆ renderDabWithMirroringNonIncremental()

void KisPainter::renderDabWithMirroringNonIncremental ( QRect rc,
KisPaintDeviceSP dab )

A complex method that re-renders a dab on an rc area. The rc area and all the dedicated mirroring areas are cleared before the painting, so this method should be used by paintops which do not update the canvas incrementally, but instead regenerate some internal cache dab with the COMPOSITE_COPY op.

See also
KisExperimentPaintOp

If there are no cross-intersections, we can use a fast path and do no cycling recompositing

Definition at line 3019 of file kis_painter.cc.

3020{
3021 QVector<QRect> rects;
3022
3023 int x = rc.topLeft().x();
3024 int y = rc.topLeft().y();
3025
3026 KisLodTransform t(d->device);
3027 QPoint effectiveAxesCenter = t.map(d->axesCenter).toPoint();
3028
3029 int mirrorX = -((x+rc.width()) - effectiveAxesCenter.x()) + effectiveAxesCenter.x();
3030 int mirrorY = -((y+rc.height()) - effectiveAxesCenter.y()) + effectiveAxesCenter.y();
3031
3032 rects << rc;
3033
3034 if (d->mirrorHorizontally && d->mirrorVertically){
3035 rects << QRect(mirrorX, y, rc.width(), rc.height());
3036 rects << QRect(mirrorX, mirrorY, rc.width(), rc.height());
3037 rects << QRect(x, mirrorY, rc.width(), rc.height());
3038 } else if (d->mirrorHorizontally) {
3039 rects << QRect(mirrorX, y, rc.width(), rc.height());
3040 } else if (d->mirrorVertically) {
3041 rects << QRect(x, mirrorY, rc.width(), rc.height());
3042 }
3043
3044 Q_FOREACH (const QRect &rc, rects) {
3045 d->device->clear(rc);
3046 }
3047
3048 QRect resultRect = dab->extent() | rc;
3049 bool intersects = false;
3050
3051 for (int i = 1; i < rects.size(); i++) {
3052 if (rects[i].intersects(resultRect)) {
3053 intersects = true;
3054 break;
3055 }
3056 }
3057
3062 if (!intersects) {
3063 rects.resize(1);
3064 }
3065
3066 Q_FOREACH (const QRect &rc, rects) {
3067 bitBlt(rc.topLeft(), dab, rc);
3068 }
3069
3070 Q_FOREACH (const QRect &rc, rects) {
3071 renderMirrorMask(rc, dab);
3072 }
3073}
void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab)

References bitBlt(), d, KisPaintDevice::extent(), KisLodTransform::map(), and renderMirrorMask().

◆ renderMirrorMask() [1/4]

void KisPainter::renderMirrorMask ( QRect rc,
KisFixedPaintDeviceSP dab )

First you need to setup the painter with setMirrorInformation, then these set of methods provide way to render the devices mirrored according the axesCenter vertically or horizontally or both.

Parameters
rcrectangle area covered by dab
dabthis device will be mirrored in-place, it means that it will be changed

Definition at line 2925 of file kis_painter.cc.

2926{
2927 int x = rc.topLeft().x();
2928 int y = rc.topLeft().y();
2929
2930 KisLodTransform t(d->device);
2931 QPoint effectiveAxesCenter = t.map(d->axesCenter).toPoint();
2932
2933 int mirrorX = -((x+rc.width()) - effectiveAxesCenter.x()) + effectiveAxesCenter.x();
2934 int mirrorY = -((y+rc.height()) - effectiveAxesCenter.y()) + effectiveAxesCenter.y();
2935
2936 if (d->mirrorHorizontally && d->mirrorVertically){
2937 dab->mirror(true, false);
2938 bltFixed(mirrorX, y, dab, 0,0,rc.width(),rc.height());
2939 dab->mirror(false,true);
2940 bltFixed(mirrorX, mirrorY, dab, 0,0,rc.width(),rc.height());
2941 dab->mirror(true, false);
2942 bltFixed(x, mirrorY, dab, 0,0,rc.width(),rc.height());
2943
2944 }
2945 else if (d->mirrorHorizontally){
2946 dab->mirror(true, false);
2947 bltFixed(mirrorX, y, dab, 0,0,rc.width(),rc.height());
2948 }
2949 else if (d->mirrorVertically){
2950 dab->mirror(false, true);
2951 bltFixed(x, mirrorY, dab, 0,0,rc.width(),rc.height());
2952 }
2953
2954}
void mirror(bool horizontal, bool vertical)

References bltFixed(), d, KisLodTransform::map(), and KisFixedPaintDevice::mirror().

◆ renderMirrorMask() [2/4]

void KisPainter::renderMirrorMask ( QRect rc,
KisFixedPaintDeviceSP dab,
KisFixedPaintDeviceSP mask )

Definition at line 2956 of file kis_painter.cc.

2957{
2958 int x = rc.topLeft().x();
2959 int y = rc.topLeft().y();
2960
2961 KisLodTransform t(d->device);
2962 QPoint effectiveAxesCenter = t.map(d->axesCenter).toPoint();
2963
2964 int mirrorX = -((x+rc.width()) - effectiveAxesCenter.x()) + effectiveAxesCenter.x();
2965 int mirrorY = -((y+rc.height()) - effectiveAxesCenter.y()) + effectiveAxesCenter.y();
2966
2967 if (d->mirrorHorizontally && d->mirrorVertically){
2968 dab->mirror(true, false);
2969 mask->mirror(true, false);
2970 bltFixedWithFixedSelection(mirrorX,y, dab, mask, rc.width() ,rc.height() );
2971
2972 dab->mirror(false,true);
2973 mask->mirror(false, true);
2974 bltFixedWithFixedSelection(mirrorX,mirrorY, dab, mask, rc.width() ,rc.height() );
2975
2976 dab->mirror(true, false);
2977 mask->mirror(true, false);
2978 bltFixedWithFixedSelection(x,mirrorY, dab, mask, rc.width() ,rc.height() );
2979
2980 }else if (d->mirrorHorizontally){
2981 dab->mirror(true, false);
2982 mask->mirror(true, false);
2983 bltFixedWithFixedSelection(mirrorX,y, dab, mask, rc.width() ,rc.height() );
2984
2985 }else if (d->mirrorVertically){
2986 dab->mirror(false, true);
2987 mask->mirror(false, true);
2988 bltFixedWithFixedSelection(x,mirrorY, dab, mask, rc.width() ,rc.height() );
2989 }
2990
2991}

References bltFixedWithFixedSelection(), d, KisLodTransform::map(), and KisFixedPaintDevice::mirror().

◆ renderMirrorMask() [3/4]

void KisPainter::renderMirrorMask ( QRect rc,
KisPaintDeviceSP dab )

Definition at line 2994 of file kis_painter.cc.

2994 {
2995 if (d->mirrorHorizontally || d->mirrorVertically){
2997 QRect dabRc( QPoint(0,0), QSize(rc.width(),rc.height()) );
2998 mirrorDab->setRect(dabRc);
2999 mirrorDab->lazyGrowBufferWithoutInitialization();
3000
3001 dab->readBytes(mirrorDab->data(),rc);
3002
3003 renderMirrorMask( QRect(rc.topLeft(),dabRc.size()), mirrorDab);
3004 }
3005}
void mirrorDab(Qt::Orientation direction, KisRenderedDab *dab, bool skipMirrorPixels=false) const

References KisPaintDevice::colorSpace(), d, mirrorDab(), KisPaintDevice::readBytes(), and renderMirrorMask().

◆ renderMirrorMask() [4/4]

void KisPainter::renderMirrorMask ( QRect rc,
KisPaintDeviceSP dab,
int sx,
int sy,
KisFixedPaintDeviceSP mask )

Definition at line 3007 of file kis_painter.cc.

3008{
3009 if (d->mirrorHorizontally || d->mirrorVertically){
3011 QRect dabRc( QPoint(0,0), QSize(rc.width(),rc.height()) );
3012 mirrorDab->setRect(dabRc);
3013 mirrorDab->lazyGrowBufferWithoutInitialization();
3014 dab->readBytes(mirrorDab->data(),QRect(QPoint(sx,sy),rc.size()));
3015 renderMirrorMask(rc, mirrorDab, mask);
3016 }
3017}

References KisPaintDevice::colorSpace(), d, mirrorDab(), KisPaintDevice::readBytes(), and renderMirrorMask().

◆ renderMirrorMaskSafe() [1/3]

void KisPainter::renderMirrorMaskSafe ( QRect rc,
KisFixedPaintDeviceSP dab,
bool preserveDab )

Convenience method for renderMirrorMask(), allows to choose whether we need to preserve out dab or do the transformations in-place.

Parameters
rcrectangle area covered by dab
dabthe device to render
maskmask to use for rendering
preserveDabstates whether a temporary device should be created to do the transformations

Definition at line 2892 of file kis_painter.cc.

2893{
2894 if (!d->mirrorHorizontally && !d->mirrorVertically) return;
2895
2896 KisFixedPaintDeviceSP dabToProcess = dab;
2897 if (preserveDab) {
2898 dabToProcess = new KisFixedPaintDevice(*dab);
2899 }
2900 renderMirrorMask(rc, dabToProcess);
2901}

References d, and renderMirrorMask().

◆ renderMirrorMaskSafe() [2/3]

void KisPainter::renderMirrorMaskSafe ( QRect rc,
KisFixedPaintDeviceSP dab,
KisFixedPaintDeviceSP mask,
bool preserveDab )

Definition at line 2903 of file kis_painter.cc.

2904{
2905 if (!d->mirrorHorizontally && !d->mirrorVertically) return;
2906
2907 KisFixedPaintDeviceSP dabToProcess = dab;
2908 if (preserveDab) {
2909 dabToProcess = new KisFixedPaintDevice(*dab);
2910 }
2911 renderMirrorMask(rc, dabToProcess, mask);
2912}

References d, and renderMirrorMask().

◆ renderMirrorMaskSafe() [3/3]

void KisPainter::renderMirrorMaskSafe ( QRect rc,
KisPaintDeviceSP dab,
int sx,
int sy,
KisFixedPaintDeviceSP mask,
bool preserveMask )

Convenience method for renderMirrorMask(), allows to choose whether we need to preserve our fixed mask or do the transformations in-place.

Parameters
rcrectangular area covered by dab
dabthe device to render
sxx coordinate of the top left corner of the area
syy coordinate of the top left corner of the area
maskmask to use for rendering
preserveMaskstates whether a temporary device should be created to do the transformations

Definition at line 2914 of file kis_painter.cc.

2915{
2916 if (!d->mirrorHorizontally && !d->mirrorVertically) return;
2917
2918 KisFixedPaintDeviceSP maskToProcess = mask;
2919 if (preserveMask) {
2920 maskToProcess = new KisFixedPaintDevice(*mask);
2921 }
2922 renderMirrorMask(rc, dab, sx, sy, maskToProcess);
2923}

References d, and renderMirrorMask().

◆ revertTransaction()

void KisPainter::revertTransaction ( )

Cancel all the changes made by the painter.

Definition at line 330 of file kis_painter.cc.

331{
332 Q_ASSERT_X(d->transaction, "KisPainter::revertTransaction()",
333 "No transaction is in progress");
334
335 d->transaction->revert();
336 delete d->transaction;
337 d->transaction = 0;
338}

References d.

◆ runnableStrokeJobsInterface()

KisRunnableStrokeJobsInterface * KisPainter::runnableStrokeJobsInterface ( ) const

Get the interface for running asynchronous jobs. It is used by paintops mostly.

◆ selection()

KisSelectionSP KisPainter::selection ( )
Returns
the selection set on this painter.

◆ setAntiAliasPolygonFill()

void KisPainter::setAntiAliasPolygonFill ( bool antiAliasPolygonFill)

Set whether a polygon's filled area should be anti-aliased or not. The default is true.

Definition at line 2658 of file kis_painter.cc.

2659{
2660 d->antiAliasPolygonFill = antiAliasPolygonFill;
2661}

References antiAliasPolygonFill, and d.

◆ setAverageOpacity()

void KisPainter::setAverageOpacity ( qreal averageOpacity)

Sets average opacity, that is used to make ALPHA_DARKEN painting look correct

Definition at line 2693 of file kis_painter.cc.

2694{
2695 d->paramInfo.setOpacityAndAverage(d->paramInfo.opacity, averageOpacity);
2696}

References d.

◆ setBackgroundColor()

void KisPainter::setBackgroundColor ( const KoColor & color)

Set the current background color, and convert it to the color space of the current paint device.

Definition at line 2615 of file kis_painter.cc.

2616{
2617 d->backgroundColor = color;
2618 if (d->device) {
2619 d->backgroundColor.convertTo(d->device->compositionSourceColorSpace());
2620 }
2621}

References d.

◆ setChannelFlags()

void KisPainter::setChannelFlags ( QBitArray channelFlags)

Set the channelflags: a bit array where true means that the channel corresponding in position with the bit will be read by the operation, and false means that it will not be affected.

An empty channelFlags parameter means that all channels are affected.

Parameters
channelFlagsthe bit array that masks the source channels; only the channels where the corresponding bit is true it will be composited onto the destination device.

Definition at line 2575 of file kis_painter.cc.

2576{
2577 // Q_ASSERT(channelFlags.isEmpty() || quint32(channelFlags.size()) == d->colorSpace->channelCount());
2578 // Now, if all bits in the channelflags are true, pass an empty channel flags bitarray
2579 // because otherwise the compositeops cannot optimize.
2580 d->paramInfo.channelFlags = channelFlags;
2581
2582 if (!channelFlags.isEmpty() && channelFlags == QBitArray(channelFlags.size(), true)) {
2583 d->paramInfo.channelFlags = QBitArray();
2584 }
2585}
QBitArray channelFlags()

References channelFlags(), and d.

◆ setColorConversionFlags()

void KisPainter::setColorConversionFlags ( KoColorConversionTransformation::ConversionFlags conversionFlags)

set the conversion flags in case pixels need to be converted before painting

Definition at line 2870 of file kis_painter.cc.

2871{
2872 d->conversionFlags = conversionFlags;
2873}
KoColorConversionTransformation::ConversionFlags conversionFlags

References conversionFlags, and d.

◆ setCompositeOpId() [1/2]

void KisPainter::setCompositeOpId ( const KoCompositeOp * op)

Set the composite op ID for this painter Only kept for convenience, it will just call ::setCompositeOpId(QString) with op->Id().

Definition at line 2735 of file kis_painter.cc.

2736{
2737 setCompositeOpId(op->id());
2738}
void setCompositeOpId(const KoCompositeOp *op)

References KoCompositeOp::id, and setCompositeOpId().

◆ setCompositeOpId() [2/2]

void KisPainter::setCompositeOpId ( const QString & op)

Set the composite op for this painter by string.

Definition at line 2745 of file kis_painter.cc.

2746{
2747 if (op != d->compositeOpId) {
2748 d->compositeOpId = op;
2749 d->cachedCompositeOp = nullptr;
2750 }
2751}

References d.

◆ setFillStyle()

void KisPainter::setFillStyle ( FillStyle fillStyle)

Set the current style with which to fill.

Definition at line 2638 of file kis_painter.cc.

2639{
2640 d->fillStyle = fillStyle;
2641}

References d, and fillStyle.

◆ setFlow()

void KisPainter::setFlow ( qreal flow)

Definition at line 2677 of file kis_painter.cc.

2678{
2679 d->paramInfo.flow = flow;
2680}
qreal flow() const

References d, and flow().

◆ setGenerator()

void KisPainter::setGenerator ( KisFilterConfigurationSP generator)

Set the current generator (a generator can be used to fill an area.

Definition at line 2628 of file kis_painter.cc.

2629{
2630 d->generator = generator;
2631}
KisFilterConfigurationSP generator

References d, and generator.

◆ setGradient()

void KisPainter::setGradient ( const KoAbstractGradientSP gradient)

Definition at line 2768 of file kis_painter.cc.

2769{
2770 d->gradient = gradient;
2771}
KoAbstractGradientSP gradient

References d, and gradient.

◆ setMaskImageSize()

void KisPainter::setMaskImageSize ( qint32 width,
qint32 height )

Set the size of the tile in fillPainterPath, useful when optimizing the use of fillPainterPath e.g. Spray paintop uses more small tiles, although selections uses bigger tiles. QImage::fill is quite expensive so with smaller images you can save instructions Default and maximum size is 256x256 image

Definition at line 2831 of file kis_painter.cc.

2832{
2833
2834 d->maskImageWidth = qBound(1, width, 256);
2835 d->maskImageHeight = qBound(1, height, 256);
2836 d->fillPainter = 0;
2837 d->polygonMaskImage = QImage();
2838}

References d.

◆ setMirrorInformation()

void KisPainter::setMirrorInformation ( const QPointF & axesCenter,
bool mirrorHorizontally,
bool mirrorVertically )

Definition at line 2802 of file kis_painter.cc.

2803{
2804 d->axesCenter = axesCenter;
2805 d->mirrorHorizontally = mirrorHorizontally;
2806 d->mirrorVertically = mirrorVertically;
2807}
QPointF axesCenter
bool mirrorHorizontally
bool mirrorVertically

References axesCenter, d, mirrorHorizontally, and mirrorVertically.

◆ setOpacityF()

void KisPainter::setOpacityF ( qreal opacity)

Definition at line 2713 of file kis_painter.cc.

2714{
2715 d->isOpacityUnit = qFuzzyCompare(opacity, OPACITY_OPAQUE_F);
2716 d->paramInfo.opacity = opacity;
2717}
const qreal OPACITY_OPAQUE_F
static bool qFuzzyCompare(half p1, half p2)

References d, OPACITY_OPAQUE_F, and qFuzzyCompare().

◆ setOpacityToUnit()

void KisPainter::setOpacityToUnit ( )

Definition at line 2729 of file kis_painter.cc.

2730{
2731 d->isOpacityUnit = true;
2732 d->paramInfo.opacity = OPACITY_OPAQUE_F;
2733}

References d, and OPACITY_OPAQUE_F.

◆ setOpacityU8()

void KisPainter::setOpacityU8 ( quint8 opacity)

Set the opacity which is used in painting (like filling polygons)

Definition at line 2707 of file kis_painter.cc.

2708{
2709 d->isOpacityUnit = opacity == OPACITY_OPAQUE_U8;
2710 d->paramInfo.opacity = float(opacity) / 255.0f;
2711}

References d, and OPACITY_OPAQUE_U8.

◆ setOpacityUpdateAverage()

void KisPainter::setOpacityUpdateAverage ( qreal opacity)

Sets the opacity of the painting and recalculates the mean opacity of the stroke. This mean value is used to make ALPHA_DARKEN painting look correct

Definition at line 2687 of file kis_painter.cc.

2688{
2689 d->isOpacityUnit = qFuzzyCompare(opacity, OPACITY_OPAQUE_F);
2690 d->paramInfo.updateOpacityAndAverage(opacity);
2691}

References d, OPACITY_OPAQUE_F, and qFuzzyCompare().

◆ setPaintColor()

void KisPainter::setPaintColor ( const KoColor & color)

Set the color that will be used to paint with, and convert it to the color space of the current paint device.

Definition at line 2602 of file kis_painter.cc.

2603{
2604 d->paintColor = color;
2605 if (d->device) {
2606 d->paintColor.convertTo(d->device->compositionSourceColorSpace());
2607 }
2608}

References d.

◆ setPaintOpPreset()

void KisPainter::setPaintOpPreset ( KisPaintOpPresetSP preset,
KisNodeSP node,
KisImageSP image )

Set the paintop preset to use. If image is given, the paintop will be created using this image as parameter. Some paintops really want to know about the image they work for, e.g. the clone paintop.

Definition at line 2778 of file kis_painter.cc.

2779{
2780 d->paintOpPreset = preset;
2781 KisPaintOp *paintop = KisPaintOpRegistry::instance()->paintOp(preset, this, node, image);
2782 Q_ASSERT(paintop);
2783 if (paintop) {
2784 delete d->paintOp;
2785 d->paintOp = paintop;
2786 }
2787 else {
2788 warnKrita << "Could not create paintop for preset " << preset->name();
2789 }
2790}
static KisPaintOpRegistry * instance()
KisPaintOp * paintOp(const KisPaintOpPresetSP preset, KisPainter *painter, KisNodeSP node, KisImageSP image) const
KisPaintOpPresetSP preset() const
Return the paintop preset.

References d, KisPaintOpRegistry::instance(), KisPaintOpRegistry::paintOp(), preset(), and warnKrita.

◆ setPattern()

void KisPainter::setPattern ( const KoPatternSP pattern)

Set the current pattern.

Definition at line 2592 of file kis_painter.cc.

2593{
2594 d->pattern = pattern;
2595}
KoPatternSP pattern

References d, and pattern.

◆ setPatternTransform()

void KisPainter::setPatternTransform ( QTransform transform)

Set the transform on the pattern.

Definition at line 2648 of file kis_painter.cc.

2649{
2650 d->patternTransform = transform;
2651}

References d.

◆ setProgress()

void KisPainter::setProgress ( KoUpdater * progressUpdater)

If set, the painter action is cancelable, if the action supports that.

Definition at line 2561 of file kis_painter.cc.

2562{
2563 d->progressUpdater = progressUpdater;
2564}
KoUpdater * progressUpdater

References d, and progressUpdater.

◆ setRenderingIntent()

void KisPainter::setRenderingIntent ( KoColorConversionTransformation::Intent intent)

set the rendering intent in case pixels need to be converted before painting

Definition at line 2865 of file kis_painter.cc.

2866{
2867 d->renderingIntent = intent;
2868}

References d.

◆ setRunnableStrokeJobsInterface()

void KisPainter::setRunnableStrokeJobsInterface ( KisRunnableStrokeJobsInterface * interface)

Set interface for running asynchronous jobs by paintops.

NOTE: the painter does not own the interface device. It is the responsibility of the caller to ensure that the interface object is alive during the lifetime of the painter.

Definition at line 2875 of file kis_painter.cc.

2876{
2877 d->runnableStrokeJobsInterface = interface;
2878}

References d.

◆ setSelection()

void KisPainter::setSelection ( KisSelectionSP selection)

Reset the selection to the given selection. All painter actions will be masked by the specified selection.

Definition at line 2753 of file kis_painter.cc.

2754{
2755 d->selection = selection;
2756}

References d, and selection.

◆ setStrokeStyle()

void KisPainter::setStrokeStyle ( KisPainter::StrokeStyle strokeStyle)

Set the current brush stroke style.

Definition at line 2668 of file kis_painter.cc.

2669{
2670 d->strokeStyle = strokeStyle;
2671}
StrokeStyle strokeStyle

References d, and strokeStyle.

◆ strokeStyle()

StrokeStyle KisPainter::strokeStyle ( ) const

Returns the current brush stroke style.

◆ takeDirtyRegion()

QVector< QRect > KisPainter::takeDirtyRegion ( )

The methods in this class do not tell the paintdevice to update, but they calculate the dirty area. This method returns this dirty area and resets it.

Definition at line 401 of file kis_painter.cc.

402{
403 QVector<QRect> vrect = d->dirtyRects;
404 d->dirtyRects.clear();
405 return vrect;
406}

References d.

◆ takeTransaction()

KisTransaction * KisPainter::takeTransaction ( )

take transaction out of the reach of KisPainter

Definition at line 390 of file kis_painter.cc.

391{
392 Q_ASSERT_X(d->transaction, "KisPainter::takeTransaction()",
393 "No transaction is in progress");
394 KisTransaction *temp = d->transaction;
395 d->transaction = 0;
396 return temp;
397}

References d.

◆ tryReduceSourceRect()

bool KisPainter::tryReduceSourceRect ( const KisPaintDevice * srcDev,
QRect * srcRect,
qint32 * srcX,
qint32 * srcY,
qint32 * srcWidth,
qint32 * srcHeight,
qint32 * dstX,
qint32 * dstY )

Member Data Documentation

◆ antiAliasPolygonFill

bool KisPainter::antiAliasPolygonFill {true}

Definition at line 42 of file kis_painter_p.h.

42{true};

◆ axesCenter

QPointF KisPainter::axesCenter

Definition at line 59 of file kis_painter_p.h.

◆ backgroundColor

const KoColor & KisPainter::backgroundColor

Definition at line 36 of file kis_painter_p.h.

◆ cachedCompositeOp

const KoCompositeOp* KisPainter::cachedCompositeOp {nullptr}

Definition at line 49 of file kis_painter_p.h.

49{nullptr};

◆ cachedSourceColorSpace

const KoColorSpace* KisPainter::cachedSourceColorSpace {nullptr}

Definition at line 48 of file kis_painter_p.h.

48{nullptr};

◆ colorSpace

const KoColorSpace* KisPainter::colorSpace {nullptr}

Definition at line 46 of file kis_painter_p.h.

46{nullptr};

◆ compositeOpId

QString KisPainter::compositeOpId

Definition at line 50 of file kis_painter_p.h.

◆ conversionFlags

KoColorConversionTransformation::ConversionFlags KisPainter::conversionFlags {KoColorConversionTransformation::Empty}

◆ customColor

KoColor KisPainter::customColor

Definition at line 37 of file kis_painter_p.h.

◆ d

Private* const KisPainter::d
private

Definition at line 899 of file kis_painter.h.

◆ device

KisPaintDeviceSP KisPainter::device

Definition at line 28 of file kis_painter_p.h.

◆ dirtyRects

QVector<QRect> KisPainter::dirtyRects

Definition at line 33 of file kis_painter_p.h.

◆ duplicateOffset

QPointF KisPainter::duplicateOffset

Definition at line 44 of file kis_painter_p.h.

◆ fakeRunnableStrokeJobsInterface

QScopedPointer<KisRunnableStrokeJobsInterface> KisPainter::fakeRunnableStrokeJobsInterface

Definition at line 67 of file kis_painter_p.h.

◆ fillPainter

KisFillPainter* KisPainter::fillPainter {nullptr}

Definition at line 55 of file kis_painter_p.h.

55{nullptr};

◆ fillStyle

KisPainter::FillStyle KisPainter::fillStyle {FillStyleNone}

Definition at line 40 of file kis_painter_p.h.

◆ generator

const KisFilterConfigurationSP KisPainter::generator

Definition at line 38 of file kis_painter_p.h.

◆ gradient

const KoAbstractGradientSP KisPainter::gradient

Definition at line 51 of file kis_painter_p.h.

◆ isOpacityUnit

bool KisPainter::isOpacityUnit {true}

Definition at line 62 of file kis_painter_p.h.

62{true}; // TODO: move into ParameterInfo

◆ maskImageHeight

qint32 KisPainter::maskImageHeight {255}

Definition at line 58 of file kis_painter_p.h.

58{255};

◆ maskImageWidth

qint32 KisPainter::maskImageWidth {255}

Definition at line 57 of file kis_painter_p.h.

57{255};

◆ maskPainter

QPainter* KisPainter::maskPainter {nullptr}

Definition at line 54 of file kis_painter_p.h.

54{nullptr};

◆ mirrorHorizontally

bool KisPainter::mirrorHorizontally {false}

Definition at line 60 of file kis_painter_p.h.

60{false};

◆ mirrorVertically

bool KisPainter::mirrorVertically {false}

Definition at line 61 of file kis_painter_p.h.

61{false};

◆ paintColor

const KoColor & KisPainter::paintColor

Definition at line 35 of file kis_painter_p.h.

◆ paintOp

KisPaintOp * KisPainter::paintOp {nullptr}

Definition at line 34 of file kis_painter_p.h.

34{nullptr};

◆ paintOpPreset

KisPaintOpPresetSP KisPainter::paintOpPreset

Definition at line 52 of file kis_painter_p.h.

◆ paramInfo

KoCompositeOp::ParameterInfo KisPainter::paramInfo

Definition at line 63 of file kis_painter_p.h.

◆ pattern

const KoPatternSP KisPainter::pattern

Definition at line 43 of file kis_painter_p.h.

◆ patternTransform

QTransform KisPainter::patternTransform

Definition at line 68 of file kis_painter_p.h.

◆ pixelSize

quint32 KisPainter::pixelSize {0}

Definition at line 45 of file kis_painter_p.h.

45{0};

◆ polygon

KisPaintDeviceSP KisPainter::polygon

Definition at line 56 of file kis_painter_p.h.

◆ polygonMaskImage

QImage KisPainter::polygonMaskImage

Definition at line 53 of file kis_painter_p.h.

◆ profile

KoColorProfile* KisPainter::profile {nullptr}

Definition at line 47 of file kis_painter_p.h.

47{nullptr};

◆ progressUpdater

KoUpdater * KisPainter::progressUpdater {nullptr}

Definition at line 31 of file kis_painter_p.h.

31{nullptr};

◆ q

KisPainter* KisPainter::q {nullptr}

Definition at line 26 of file kis_painter_p.h.

26{nullptr};

◆ renderingIntent

◆ runnableStrokeJobsInterface

KisRunnableStrokeJobsInterface * KisPainter::runnableStrokeJobsInterface {nullptr}

Definition at line 66 of file kis_painter_p.h.

66{nullptr};

◆ selection

KisSelectionSP KisPainter::selection

Definition at line 29 of file kis_painter_p.h.

◆ sourceLayer

KisPaintLayer* KisPainter::sourceLayer {nullptr}

Definition at line 39 of file kis_painter_p.h.

39{nullptr};

◆ strokeStyle

KisPainter::StrokeStyle KisPainter::strokeStyle {StrokeStyleBrush}

Definition at line 41 of file kis_painter_p.h.

◆ transaction

KisTransaction* KisPainter::transaction {nullptr}

Definition at line 30 of file kis_painter_p.h.

30{nullptr};

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