Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_selection_based_layer.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org>
3 * SPDX-FileCopyrightText: 2005 C. Boemann <cbo@boemann.dk>
4 * SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
10
11#include <klocalizedstring.h>
12#include "kis_debug.h"
13
15
16#include "kis_image.h"
17#include "kis_painter.h"
18#include "kis_default_bounds.h"
20
21#include "kis_selection.h"
22#include "kis_pixel_selection.h"
25#include "filter/kis_filter.h"
27
29
30
31struct Q_DECL_HIDDEN KisSelectionBasedLayer::Private
32{
33public:
34 Private() : useSelectionInProjection(true) {}
35 Private(const Private &rhs) : useSelectionInProjection(rhs.useSelectionInProjection) {}
36
41};
42
43
45 const QString &name,
46 KisSelectionSP selection,
47 KisFilterConfigurationSP filterConfig)
48 : KisLayer(image.data(), name, OPACITY_OPAQUE_U8),
49 KisNodeFilterInterface(filterConfig),
50 m_d(new Private())
51{
52 if (!selection) {
54 } else {
56 }
57
58 KisImageSP imageSP = image.toStrongRef();
59 if (!imageSP) {
60 return;
61 }
62 m_d->paintDevice = KisPaintDeviceSP(new KisPaintDevice(this, imageSP->colorSpace(), KisDefaultBoundsSP(new KisDefaultBounds(image))));
63 m_d->imageConnections.addConnection(imageSP.data(), SIGNAL(sigSizeChanged(QPointF,QPointF)), this, SLOT(slotImageSizeChanged()));
64}
65
67 : KisLayer(rhs)
70 , m_d(new Private(*rhs.m_d))
71{
72 setInternalSelection(rhs.m_d->selection);
73
74 m_d->paintDevice = new KisPaintDevice(*rhs.m_d->paintDevice.data());
76
77
82
84{
86 m_d->selection->pixelSelection()->setDefaultPixel(KoColor(Qt::white, m_d->selection->pixelSelection()->colorSpace()));
87 m_d->selection->pixelSelection()->setSupportsWraparoundMode(true);
88 m_d->selection->setParentNode(this);
89 m_d->selection->updateProjection();
90}
91
93{
94 if (m_d->selection) {
99 m_d->selection->pixelSelection()->setDirty();
100 setDirty();
101 }
102}
103
105{
106 m_d->imageConnections.clear();
107 m_d->paintDevice->setDefaultBounds(KisDefaultBoundsSP(new KisDefaultBounds(image)));
108 m_d->selection->setDefaultBounds(KisDefaultBoundsSP(new KisDefaultBounds(image)));
109 m_d->selection->setResolutionProxy(m_d->selection->resolutionProxy()->createOrCloneDetached(image));
111
112 if (image) {
113 m_d->imageConnections.addConnection(image.data(), SIGNAL(sigSizeChanged(QPointF,QPointF)), this, SLOT(slotImageSizeChanged()));
114 }
115}
116
118{
119 return node->inherits("KisMask");
120}
121
122
124{
125 return m_d->paintDevice;
126}
128{
129 return m_d->selection->pixelSelection();
130}
131
132
134{
135 return m_d->selection;
136}
137
139{
140 m_d->useSelectionInProjection = value;
141}
142
144{
145 if (!m_d->selection) return KisSelectionSP();
146 m_d->selection->updateProjection(rect);
147
148 KisSelectionSP tempSelection = m_d->selection;
149
151
152 if (hasTemporaryTarget()) {
160 tempSelection = new KisSelection();
161
162 KisPainter::copyAreaOptimized(rect.topLeft(), m_d->selection->pixelSelection(), tempSelection->pixelSelection(), rect);
163
164 KisPainter gc2(tempSelection->pixelSelection());
166 gc2.bitBlt(rect.topLeft(), temporaryTarget(), rect);
167 }
168
169 return tempSelection;
170}
171
173 KisPaintDeviceSP projection,
174 const QRect& rect) const
175{
176 KisSelectionSP tempSelection;
177
178 if (m_d->useSelectionInProjection) {
179 tempSelection = fetchComposedInternalSelection(rect);
180
186 }
187
188 KisPainter::copyAreaOptimized(rect.topLeft(), original, projection, rect, tempSelection);
189}
190
192{
193 return m_d->selection ?
194 rect & m_d->selection->selectedRect() :
195 rect;
196}
197
199{
200 Q_UNUSED(pos);
201 return rect;
202}
203
205{
206 KisImageSP imageSP = image().toStrongRef();
207 if (!imageSP) {
208 return;
209 }
210
211 if (!colorSpace)
212 colorSpace = imageSP->colorSpace();
213
214 Q_ASSERT(colorSpace);
215
216 if (!m_d->paintDevice) {
218 } else if (m_d->paintDevice->colorSpace() != colorSpace) {
219 m_d->paintDevice->clear();
220 m_d->paintDevice->convertTo(colorSpace);
221 } else {
222 m_d->paintDevice->clear();
223 }
224}
225
227{
228 return m_d->selection;
229}
230
232{
233 if (selection) {
234 m_d->selection = new KisSelection(*selection.data());
235 m_d->selection->setParentNode(this);
236 m_d->selection->setDefaultBounds(new KisDefaultBounds(image()));
237 m_d->selection->setResolutionProxy(toQShared(new KisImageResolutionProxy(image())));
238 m_d->selection->pixelSelection()->setSupportsWraparoundMode(true);
239 m_d->selection->updateProjection();
240
241 KisPixelSelectionSP pixelSelection = m_d->selection->pixelSelection();
242 if (pixelSelection->framesInterface()) {
243 addKeyframeChannel(pixelSelection->keyframeChannel());
245 }
246
247 KisImageSP imageSP = image().toStrongRef();
248 if (imageSP) {
252 if (m_d->selection->pixelSelection()->defaultBounds()->bounds() != imageSP->bounds()) {
253 qWarning() << "WARNING: KisSelectionBasedLayer::setInternalSelection"
254 << "New selection has suspicious default bounds";
255 qWarning() << "WARNING:" << ppVar(m_d->selection->pixelSelection()->defaultBounds()->bounds());
256 qWarning() << "WARNING:" << ppVar(imageSP->bounds());
257 }
258 }
259
260 } else {
261 m_d->selection = 0;
262 }
263}
264
266{
267 return m_d->selection ? m_d->selection->x() : 0;
268}
269
271{
272 return m_d->selection ? m_d->selection->y() : 0;
273}
274
276{
277 if (m_d->selection) {
278 m_d->selection->setX(x);
279 }
280}
281
283{
284 if (m_d->selection) {
285 m_d->selection->setY(y);
286 }
287}
288
290{
291 return !m_d->selection || !m_d->selection->hasShapeSelection();
292}
293
295{
296 if (id == KisKeyframeChannel::Raster.id()) {
297 KisRasterKeyframeChannel *contentChannel = m_d->selection->pixelSelection()->createKeyframeChannel(KisKeyframeChannel::Raster);
298 contentChannel->setFilenameSuffix(".pixelselection");
299 return contentChannel;
300 }
301
303}
304
306{
307 if (id == KisKeyframeChannel::Raster.id()) {
308 return true;
309 }
310
312}
313
315{
316 Q_ASSERT(image());
317 KisImageSP imageSP = image().toStrongRef();
318 if (!imageSP) {
319 return;
320 }
321 setDirty(imageSP->bounds());
322}
323
325{
326 QRect resultRect;
327
328 if (m_d->selection) {
329 resultRect = m_d->selection->selectedRect();
330
331 // copy for thread safety!
333
334 if (temporaryTarget) {
335 resultRect |= temporaryTarget->extent();
336 }
337
338 } else {
339 KisImageSP image = this->image().toStrongRef();
341 resultRect = image->bounds();
342 }
343
344 return resultRect;
345}
346
348{
349 QRect resultRect;
350
351 if (m_d->selection) {
352 resultRect = m_d->selection->selectedExactRect();
353
354 // copy for thread safety!
356
357 if (temporaryTarget) {
358 resultRect |= temporaryTarget->exactBounds();
359 }
360
361 } else {
362 KisImageSP image = this->image().toStrongRef();
364 resultRect = image->bounds();
365 }
366
367 return resultRect;
368}
369
370QImage KisSelectionBasedLayer::createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode)
371{
372 KisSelectionSP originalSelection = internalSelection();
373 KisPaintDeviceSP originalDevice = original();
374
375 return originalDevice && originalSelection ?
376 originalDevice->createThumbnail(w, h, aspectRatioMode, 1,
379 QImage();
380}
381
383{
384 KisSelectionSP originalSelection = internalSelection();
385 KisPaintDeviceSP originalDevice = original();
386
387 return originalDevice && originalSelection ? originalDevice->sequenceNumber() : -1;
388}
389
float value(const T *src, size_t ch)
const quint8 OPACITY_OPAQUE_U8
const KoColorSpace * colorSpace() const
QRect bounds() const override
KisKeyframeChannel stores and manages KisKeyframes. Maps units of time to virtual keyframe values....
static const KoID Raster
KisRasterKeyframeChannel * keyframeChannel() const
virtual void clear()
int sequenceNumber() const
QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, qreal oversample=1, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags())
KisPaintDeviceFramesInterface * framesInterface()
QRect exactBounds() const
QRect extent() const
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
void setFilenameSuffix(const QString &suffix)
KisSharedPtr< T > toStrongRef() const
toStrongRef returns a KisSharedPtr which may be dereferenced.
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define ppVar(var)
Definition kis_debug.h:155
KisSharedPtr< KisDefaultBounds > KisDefaultBoundsSP
QSharedPointer< T > toQShared(T *ptr)
KisSharedPtr< KisPaintDevice > KisPaintDeviceSP
Definition kis_types.h:73
KisWeakSharedPtr< KisNode > KisNodeWSP
Definition kis_types.h:87
KisSharedPtr< KisSelection > KisSelectionSP
Definition kis_types.h:149
virtual KisKeyframeChannel * requestKeyframeChannel(const QString &id)
KisImageWSP image
void enableAnimation()
virtual bool supportsKeyframeChannel(const QString &id)
void setupTemporaryPainter(KisPainter *painter) const
KisPaintDeviceSP projection() const override
Definition kis_layer.cc:820
void setImage(KisImageWSP image) override
Definition kis_layer.cc:378
const KoColorSpace * colorSpace() const override
returns the image's colorSpace or null, if there is no image
Definition kis_layer.cc:225
PositionToFilthy
Definition kis_node.h:58
void addKeyframeChannel(KisKeyframeChannel *channel) override
Definition kis_node.cpp:351
Describes base behaviour for selection base classes like KisAdjustmentLayer and KisGeneratorLayer....
void setUseSelectionInProjection(bool value) const
QRect needRect(const QRect &rect, PositionToFilthy pos=N_FILTHY) const override
KisSelectionSP fetchComposedInternalSelection(const QRect &rect) const
void setImage(KisImageWSP image) override
void copyOriginalToProjection(const KisPaintDeviceSP original, KisPaintDeviceSP projection, const QRect &rect) const override
bool allowAsChild(KisNodeSP node) const override
virtual void resetCache(const KoColorSpace *colorSpace)
KisSelectionBasedLayer(KisImageWSP image, const QString &name, KisSelectionSP selection, KisFilterConfigurationSP filterConfig)
void setInternalSelection(KisSelectionSP selection)
QRect cropChangeRectBySelection(const QRect &rect) const
KisKeyframeChannel * requestKeyframeChannel(const QString &id) override
bool supportsLodPainting() const override
bool supportsKeyframeChannel(const QString &id) override
KisSignalAutoConnectionsStore imageConnections
KisSelectionSP internalSelection() const
QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode=Qt::IgnoreAspectRatio) override
KisPaintDeviceSP original() const override
KisPixelSelectionSP pixelSelection