17#include <QFontMetrics>
24#include <klocalizedstring.h>
90 bitBlt(rc.topLeft(), fillDevice, rc);
103 quint8 * data = kc2.
data();
128 if (!offset.isNull()) {
129 patternLayer->
moveTo(offset);
140 if (rc.width() < 1)
return;
141 if (rc.height() < 1)
return;
176 fillRect(rc.x(), rc.y(), rc.width(), rc.height(),
device, deviceRect);
181 const QRect &patternRect = deviceRect;
184 auto toPatternLocal = [](
int value,
int offset,
int width) {
185 const int normalizedValue =
value - offset;
186 return offset + (normalizedValue >= 0 ?
187 normalizedValue % width :
188 width - (-normalizedValue - 1) % width - 1);
193 const int dstRowsRemaining =
fillRect.bottom() - dstY + 1;
195 const int srcY = toPatternLocal(dstY, patternRect.y(), patternRect.height());
196 const int height = qMin(patternRect.height() - srcY + patternRect.y(), dstRowsRemaining);
200 const int dstColumnsRemaining =
fillRect.right() - dstX + 1;
202 const int srcX = toPatternLocal(dstX, patternRect.x(), patternRect.width());
203 const int width = qMin(patternRect.width() - srcX + patternRect.x(), dstColumnsRemaining);
223 QRect tmpRc(x1, y1, w, h);
240 sourceDevice !=
device()) {
242 warnKrita <<
"WARNING: Fast Flood Fill (no compositing mode)"
243 <<
"does not support compositeOps, opacity, "
244 <<
"selection enhancements and separate source "
249 QPoint startPoint(startX, startY);
251 if (!fillBoundsRect.contains(startPoint))
return;
334 bitBlt(rc.topLeft(), filled, rc);
356 m_width = rc.width() - (startX - rc.x());
357 m_height = rc.height() - (startY - rc.y());
365 QPoint startPoint(startX, startY);
367 if (!fillBoundsRect.contains(startPoint)) {
368 return pixelSelection;
415 return pixelSelection;
418template <
typename DifferencePolicy,
typename SelectionPolicy>
423 DifferencePolicy differencePolicy,
424 SelectionPolicy selectionPolicy,
430 const int totalNumberOfPixels =
rect.width() *
rect.height();
431 const int numberOfUpdates = 4;
432 const int numberOfPixelsPerUpdate = totalNumberOfPixels / numberOfUpdates;
433 const int progressIncrement = 100 / numberOfUpdates;
434 int numberOfPixelsProcessed = 0;
438 while (referenceDeviceIterator.
nextPixel() &&
442 *outSelectionIterator.
rawData() =
443 selectionPolicy.opacityFromDifference(
444 differencePolicy.difference(referenceDeviceIterator.
rawDataConst())
448 ++numberOfPixelsProcessed;
449 if (numberOfPixelsProcessed > numberOfPixelsPerUpdate) {
450 numberOfPixelsProcessed = 0;
451 updater->setProgress(updater->progress() + progressIncrement);
456 while (referenceDeviceIterator.
nextPixel() &&
458 *outSelectionIterator.
rawData() =
459 selectionPolicy.opacityFromDifference(
460 differencePolicy.difference(referenceDeviceIterator.
rawDataConst())
463 ++numberOfPixelsProcessed;
464 if (numberOfPixelsProcessed > numberOfPixelsPerUpdate) {
465 numberOfPixelsProcessed = 0;
466 updater->setProgress(updater->progress() + progressIncrement);
472 updater->setProgress(100);
482 if (
rect.isEmpty()) {
486 KoColor srcColor(referenceColor);
542 if (
rect.isEmpty()) {
558 for (
const QRect &patch : fillPatches) {
561 [referenceDevice, outSelection, mask, referenceColor,
562 threshold, softness, patch, progressHelper]()
mutable
564 if (patch.isEmpty()) {
568 KoUpdater *updater = progressHelper ? progressHelper->updater() :
nullptr;
573 KoColor srcColor(*referenceColor);
619 [outSelection, referenceDevice, mask,
622 KoUpdater *updater = progressHelper ? progressHelper->updater() :
nullptr;
float value(const T *src, size_t ch)
const QString COMPOSITE_OVER
AntiAlias filter for selections inspired by FXAA.
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
void fillSelection(const QRect &rc, const KoColor &color)
bool m_stopGrowingAtDarkestPixel
KisPixelSelectionSP createFloodSelection(int startX, int startY, KisPaintDeviceSP sourceDevice, KisPaintDeviceSP existingSelection)
KoColor m_regionFillingBoundaryColor
QVector< KisStrokeJobData * > createSimilarColorsSelectionJobs(KisPixelSelectionSP outSelection, const QSharedPointer< KoColor > referenceColor, KisPaintDeviceSP referenceDevice, const QRect &rect, KisPixelSelectionSP mask, QSharedPointer< KisProcessingVisitor::ProgressHelper > progressHelper=nullptr)
void fillRect(qint32 x, qint32 y, qint32 w, qint32 h, const KoColor &c, quint8 opacity)
int fillThreshold() const
int opacitySpread() const
void fillColor(int startX, int startY, KisPaintDeviceSP sourceDevice)
void fillPattern(int startX, int startY, KisPaintDeviceSP sourceDevice, QTransform patternTransform=QTransform())
void genericFillEnd(KisPaintDeviceSP filled)
void createSimilarColorsSelection(KisPixelSelectionSP outSelection, const KoColor &referenceColor, KisPaintDeviceSP referenceDevice, const QRect &rect, KisPixelSelectionSP mask)
void genericFillStart(int startX, int startY, KisPaintDeviceSP sourceDevice)
bool m_useSelectionAsBoundary
bool stopGrowingAtDarkestPixel() const
@ RegionFillingMode_FloodFill
RegionFillingMode m_regionFillingMode
void fillRectNoCompose(const QRect &rc, const KoPatternSP pattern, const QTransform transform)
fillRect Fill a rectangle with a certain pattern. The pattern is repeated if it does not fit the enti...
KisSelectionSP m_fillSelection
static KisGeneratorRegistry * instance()
virtual void generate(KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const =0
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
Filter that dilates a selection and that can stop dilating adaptively at areas of higher darkness or ...
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
static KisImageResolutionProxySP identity()
quint32 pixelSize() const
bool supportsWraproundMode() const
void setDefaultPixel(const KoColor &defPixel)
void setDefaultBounds(KisDefaultBoundsBaseSP bounds)
KisPaintDeviceSP createCompositionSourceDevice() const
void fill(const QRect &rc, const KoColor &color)
const KoColorSpace * colorSpace() const
void setSupportsWraparoundMode(bool value)
KisDefaultBoundsBaseSP defaultBounds() const
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
void moveTo(qint32 x, qint32 y)
const KoColorSpace * colorSpace
KisFilterConfigurationSP generator
void setSelection(KisSelectionSP selection)
KoUpdater * progressUpdater
QTransform patternTransform
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void addDirtyRect(const QRect &r)
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE const quint8 * rawDataConst() const
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
const T value(const QString &id) const
void setProgress(int percent)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
void createSimilarColorsSelectionImpl(KisPixelSelectionSP outSelection, KisPaintDeviceSP referenceDevice, const QRect &rect, KisPixelSelectionSP mask, DifferencePolicy differencePolicy, SelectionPolicy selectionPolicy, KoUpdater *updater=nullptr)
const quint8 MIN_SELECTED
QVector< QRect > splitRectIntoPatches(const QRect &rc, const QSize &patchSize)
void addJobConcurrent(QVector< Job * > &jobs, Func func)
void addJobSequential(QVector< Job * > &jobs, Func func)
void addJobBarrier(QVector< Job * > &jobs, Func func)
QRect selectedExactRect() const
QRect selectedRect() const
void applySelection(KisPixelSelectionSP selection, SelectionAction action)
void fillSelectionUntilColor(KisPixelSelectionSP pixelSelection, const KoColor &boundaryColor, KisPaintDeviceSP boundarySelection)
void fillUntilColor(const KoColor &fillColor, const KoColor &boundaryColor)
void setCloseGap(int closeGap)
void fill(const KoColor &fillColor)
void fillSelection(KisPixelSelectionSP pixelSelection, KisPaintDeviceSP boundarySelection)
void setThreshold(int threshold)
void setOpacitySpread(int opacitySpread)
KisPixelSelectionSP projection() const
KisPixelSelectionSP pixelSelection
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
The KisWrapAroundBoundsWrapper class wrapper around a KisDefaultBoundsBaseSP to enable wraparound....