49 thumbnailImageValid =
false;
50 thumbnailImage = QImage();
51 thumbnailImageTransform = QTransform();
59 m_d->outlineCacheValid =
true;
60 m_d->invalidateThumbnailImage();
71 m_d->outlineCache = rhs.
m_d->outlineCache;
72 m_d->outlineCacheValid = rhs.
m_d->outlineCacheValid;
74 m_d->thumbnailImageValid = rhs.
m_d->thumbnailImageValid;
75 m_d->thumbnailImage = rhs.
m_d->thumbnailImage;
76 m_d->thumbnailImageTransform = rhs.
m_d->thumbnailImageTransform;
89 m_d->outlineCacheValid =
false;
90 m_d->invalidateThumbnailImage();
114 m_d->outlineCacheValid =
false;
115 m_d->invalidateThumbnailImage();
121 QRect r = rc.normalized();
122 if (r.isEmpty())
return;
128 if (
m_d->outlineCacheValid) {
133 m_d->outlineCache += path;
135 m_d->outlineCache -= path;
138 m_d->invalidateThumbnailImage();
174 quint8 *alpha8Ptr = dstIt.
rawData();
179 m_d->outlineCacheValid =
false;
180 m_d->outlineCache = QPainterPath();
181 m_d->invalidateThumbnailImage();
187 if (r.isEmpty())
return;
191 for (
int i = 0; i < r.height(); ++i) {
193 if (*src->oldRawData() + *dst->rawData() <
MAX_SELECTED)
194 *dst->rawData() = *src->oldRawData() + *dst->rawData();
198 }
while (src->nextPixel() && dst->nextPixel());
208 if (
m_d->outlineCacheValid) {
212 m_d->invalidateThumbnailImage();
218 if (r.isEmpty())
return;
223 for (
int i = 0; i < r.height(); ++i) {
225 if (*dst->rawData() - *src->oldRawData() >
MIN_SELECTED)
226 *dst->rawData() = *dst->rawData() - *src->oldRawData();
230 }
while (src->nextPixel() && dst->nextPixel());
242 if (
m_d->outlineCacheValid) {
246 m_d->invalidateThumbnailImage();
259 for (
int i = 0; i < r.height(); ++i) {
261 *dst->rawData() = qMin(*dst->rawData(), *src->oldRawData());
262 }
while (src->nextPixel() && dst->nextPixel());
274 if (
m_d->outlineCacheValid) {
278 m_d->invalidateThumbnailImage();
284 if (r.isEmpty())
return;
288 for (
int i = 0; i < r.height(); ++i) {
291 *dst->rawData() = abs(*dst->rawData() - *src->oldRawData());
292 }
while (src->nextPixel() && dst->nextPixel());
303 if (
m_d->outlineCacheValid) {
307 m_d->invalidateThumbnailImage();
320 if (
m_d->outlineCacheValid) {
324 m_d->outlineCache -= path;
327 m_d->invalidateThumbnailImage();
335 m_d->outlineCacheValid =
true;
336 m_d->outlineCache = QPainterPath();
339 m_d->invalidateThumbnailImage();
340 m_d->thumbnailImageValid =
true;
358 if (
m_d->outlineCacheValid) {
362 m_d->outlineCache = path -
m_d->outlineCache;
365 m_d->invalidateThumbnailImage();
371 const QPoint lod0Point = !lod ? pt :
374 const QPoint
offset = lod0Point -
m_d->lod0CachesOffset;
376 if (
m_d->outlineCacheValid) {
380 if (
m_d->thumbnailImageValid) {
381 m_d->thumbnailImageTransform =
383 m_d->thumbnailImageTransform;
386 m_d->lod0CachesOffset = lod0Point;
396 return ! r.intersects(sr);
423 qint32 xOffset = selectionExtent.x();
424 qint32 yOffset = selectionExtent.y();
425 qint32 width = selectionExtent.width();
426 qint32 height = selectionExtent.height();
431 quint8* buffer =
new quint8[width*height];
432 readBytes(buffer, xOffset, yOffset, width, height);
439 catch(
const std::bad_alloc&) {
441 warnKrita <<
"KisPixelSelection::outline ran out of memory allocating" << width <<
"*" << height <<
"bytes.";
444 return generator.
outline(
this, xOffset, yOffset, width, height);
454 QMutexLocker locker(&
m_d->outlineCacheMutex);
455 return m_d->outlineCache;
460 QMutexLocker locker(&
m_d->outlineCacheMutex);
461 m_d->outlineCache = cache;
462 m_d->outlineCacheValid =
true;
463 m_d->thumbnailImageValid =
false;
468 QMutexLocker locker(&
m_d->outlineCacheMutex);
469 return m_d->outlineCacheValid;
474 QMutexLocker locker(&
m_d->outlineCacheMutex);
475 m_d->outlineCacheValid =
false;
476 m_d->thumbnailImageValid =
false;
481 QMutexLocker locker(&
m_d->outlineCacheMutex);
483 m_d->outlineCache = QPainterPath();
485 Q_FOREACH (
const QPolygon &polygon,
outline()) {
486 m_d->outlineCache.addPolygon(polygon);
497 m_d->outlineCache.closeSubpath();
500 m_d->outlineCacheValid =
true;
505 return m_d->thumbnailImageValid;
510 return m_d->thumbnailImage;
515 return m_d->thumbnailImageTransform;
520 const QColor &maskColor)
522 QImage image(rc.size(), QImage::Format_ARGB32);
524 QColor color = maskColor;
525 const qreal alphaScale = maskColor.alphaF();
530 color.setAlpha(
value);
532 QPoint pt(it.
x(), it.
y());
535 image.setPixel(pt.x(), pt.y(), color.rgba());
544 const int maxPreviewSize = 2000;
547 m_d->thumbnailImageTransform = QTransform();
548 m_d->thumbnailImage = QImage();
553 if (rc.width() > maxPreviewSize ||
554 rc.height() > maxPreviewSize) {
558 if (rc.width() > rc.height()) {
559 factor = qreal(maxPreviewSize) / rc.width();
561 factor = qreal(maxPreviewSize) / rc.height();
564 int newWidth = qRound(rc.width() * factor);
565 int newHeight = qRound(rc.height() * factor);
567 m_d->thumbnailImageTransform =
568 QTransform::fromScale(qreal(rc.width()) / newWidth,
569 qreal(rc.height()) / newHeight) *
570 QTransform::fromTranslate(rc.x(), rc.y());
575 QRect thumbRect(0, 0, newWidth, newHeight);
579 m_d->thumbnailImageTransform = QTransform::fromTranslate(rc.x(), rc.y());
583 m_d->thumbnailImageValid =
true;
588 m_d->parentSelection = selection;
593 return m_d->parentSelection;
605 if (updateRect.isValid()) {
float value(const T *src, size_t ch)
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
PythonPluginManager * instance
virtual int currentLevelOfDetail() const =0
virtual QRect bounds() const =0
void fillRect(qint32 x, qint32 y, qint32 w, qint32 h, const KoColor &c, quint8 opacity)
QVector< QPolygon > outline(quint8 *buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height)
void crop(qint32 x, qint32 y, qint32 w, qint32 h)
bool read(QIODevice *stream)
void setDefaultPixel(const KoColor &defPixel)
KisPaintDevice(const KoColorSpace *colorSpace, const QString &name=QString())
KisPaintDeviceSP createThumbnailDevice(qint32 w, qint32 h, QRect rect=QRect(), QRect outputRect=QRect()) const
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const KoColorSpace * colorSpace() const
KoColor defaultPixel() const
KisDefaultBoundsBaseSP defaultBounds() const
void moveTo(qint32 x, qint32 y)
void makeFullCopyFrom(const KisPaintDevice &rhs, KritaUtils::DeviceCopyMode copyMode=KritaUtils::CopySnapshot, KisNode *newParentNode=0)
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
QRect boundingRect() const
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE int y() const
ALWAYS_INLINE const quint8 * rawDataConst() const
virtual quint8 opacityU8(const quint8 *pixel) const =0
static KoColor createTransparent(const KoColorSpace *cs)
const quint8 MAX_SELECTED
const quint8 MIN_SELECTED
QImage deviceToQImage(KisPaintDeviceSP device, const QRect &rc, const QColor &maskColor)
KisSharedPtr< KisPaintDevice > KisPaintDeviceSP
QPainterPath tryCloseTornSubpathsAfterIntersection(QPainterPath path)
bool isEmpty() const override
void intersectSelection(KisPixelSelectionSP selection)
KisSelectionComponent * clone(KisSelection *) override
bool isTotallyUnselected(const QRect &r) const
Tests if the rect is totally outside the selection.
QTransform thumbnailImageTransform
QPainterPath outlineCache
void recalculateOutlineCache() override
KisSelectionWSP parentSelection
void copyAlphaFrom(KisPaintDeviceSP src, const QRect &processRect)
void recalculateThumbnailImage(const QColor &maskColor)
void symmetricdifferenceSelection(KisPixelSelectionSP selection)
void subtractSelection(KisPixelSelectionSP selection)
void setParentSelection(KisSelectionWSP selection)
QRect exactBounds() const
void invalidateOutlineCache()
~KisPixelSelection() override
void renderToProjection(KisPaintDeviceSP projection) override
bool read(QIODevice *stream)
QRect selectedExactRect() const
const KoColorSpace * compositionSourceColorSpace() const override
void moveTo(const QPoint &pt) override
QVector< QPolygon > outline() const
outline returns the outline of the current selection
KisPixelSelection(KisDefaultBoundsBaseSP defaultBounds=KisDefaultBoundsBaseSP(), KisSelectionWSP parentSelection=KisSelectionWSP())
void setOutlineCache(const QPainterPath &cache)
void select(const QRect &r, quint8 selectedness=MAX_SELECTED)
QRect selectedRect() const
void addSelection(KisPixelSelectionSP selection)
void applySelection(KisPixelSelectionSP selection, SelectionAction action)
void invalidateThumbnailImage()
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())