Krita Source Code Documentation
Loading...
Searching...
No Matches
Selection.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6#include "Selection.h"
7
8#include <KoColorSpace.h>
9#include "kis_iterator_ng.h"
10#include <kis_selection.h>
11#include <kis_pixel_selection.h>
12#include <kis_paint_device.h>
14#include <kis_painter.h>
15#include <kis_node.h>
16#include <kis_clipboard.h>
17#include <QByteArray>
18
19#include <Node.h>
20
25
26Selection::Selection(KisSelectionSP selection, QObject *parent)
27 : QObject(parent)
28 , d(new Private)
29{
31}
32
33
34Selection::Selection(QObject *parent)
35 : QObject(parent)
36 , d(new Private)
37{
38 d->selection = new KisSelection();
39}
40
42{
43 delete d;
44}
45
46bool Selection::operator==(const Selection &other) const
47{
48 return (d->selection == other.d->selection);
49}
50
51bool Selection::operator!=(const Selection &other) const
52{
53 return !(operator==(other));
54}
55
57{
58 return new Selection(d->selection ? new KisSelection(*d->selection)
59 : new KisSelection());
60}
61
63{
64 if (!d->selection) return 0;
65 return d->selection->selectedExactRect().width();
66}
67
69{
70 if (!d->selection) return 0;
71 return d->selection->selectedExactRect().height();
72}
73
74int Selection::x() const
75{
76 if (!d->selection) return 0;
77 int xPos = d->selection->x();
79 xPos = d->selection->selectedExactRect().x();
80 }
81 return xPos;
82}
83
84int Selection::y() const
85{
86 if (!d->selection) return 0;
87 int yPos = d->selection->y();
89 yPos = d->selection->selectedExactRect().y();
90 }
91 return yPos;
92}
93
94void Selection::move(int x, int y)
95{
96 if (!d->selection) return;
97 d->selection->pixelSelection()->moveTo(QPoint(x, y));
98}
99
100
102{
103 if (!d->selection) return;
104 d->selection->clear();
105}
106
108{
109 if (!d->selection) return;
110 d->selection->pixelSelection()->select(QRect(x(), y(), width() - value, height() - value));
111}
112
114{
115 if (!node) return;
116 if (!d->selection) return;
117 if (node->node()->exactBounds().isEmpty()) return;
118 if (!node->node()->hasEditablePaintDevice()) return;
119
120 KisPaintDeviceSP dev = node->node()->paintDevice();
121 KisPaintDeviceSP clip = new KisPaintDevice(dev->colorSpace());
122 KisPaintDeviceSP selectionProjection = d->selection->projection();
123
124 const KoColorSpace *cs = clip->colorSpace();
125 const KoColorSpace *selCs = d->selection->projection()->colorSpace();
126
127 QRect rc = d->selection->selectedExactRect();
128
129 KisPainter::copyAreaOptimized(QPoint(), dev, clip, rc);
130
131 KisHLineIteratorSP layerIt = clip->createHLineIteratorNG(0, 0, rc.width());
132 KisHLineConstIteratorSP selectionIt = selectionProjection->createHLineIteratorNG(rc.x(), rc.y(), rc.width());
133
134 for (qint32 y = 0; y < rc.height(); y++) {
135 for (qint32 x = 0; x < rc.width(); x++) {
136
137 qreal dstAlpha = cs->opacityF(layerIt->rawData());
138 qreal sel = selCs->opacityF(selectionIt->oldRawData());
139 qreal newAlpha = sel * dstAlpha / (1.0 - dstAlpha + sel * dstAlpha);
140 float mask = newAlpha / dstAlpha;
141
142 cs->applyAlphaNormedFloatMask(layerIt->rawData(), &mask, 1);
143
144 layerIt->nextPixel();
145 selectionIt->nextPixel();
146 }
147 layerIt->nextRow();
148 selectionIt->nextRow();
149 }
150
151 KisClipboard::instance()->setClip(clip, rc.topLeft());
152}
153
155{
156 if (!node) return;
157 if (!d->selection) return;
158 if (node->node()->exactBounds().isEmpty()) return;
159 if (!node->node()->hasEditablePaintDevice()) return;
160 KisPaintDeviceSP dev = node->node()->paintDevice();
161 copy(node);
164}
165
166void Selection::paste(Node *destination, int x, int y)
167{
168 if (!destination) return;
169 if (!d->selection) return;
170 if (!KisClipboard::instance()->hasClip()) return;
171
172 KisPaintDeviceSP src = KisClipboard::instance()->clip(QRect(), false);
173 KisPaintDeviceSP dst = destination->node()->paintDevice();
174 if (!dst || !src) return;
176 src,
177 dst,
178 src->exactBounds(),
179 d->selection);
180 destination->node()->setDirty();
181}
182
184{
185 if (!d->selection) return;
188 esf.process(d->selection->pixelSelection(), rc);
189}
190
192{
193 if (!d->selection) return;
196 dsf.process(d->selection->pixelSelection(), rc);
197}
198
199void Selection::border(int xRadius, int yRadius)
200{
201 if (!d->selection) return;
202 KisBorderSelectionFilter sf(xRadius, yRadius, true);
204 sf.process(d->selection->pixelSelection(), rc);
205}
206
207void Selection::feather(int radius)
208{
209 if (!d->selection) return;
210 KisFeatherSelectionFilter fsf(radius);
212 fsf.process(d->selection->pixelSelection(), rc);
213}
214
215void Selection::grow(int xradius, int yradius)
216{
217 if (!d->selection) return;
218 KisGrowSelectionFilter gsf(xradius, yradius);
220 gsf.process(d->selection->pixelSelection(), rc);
221}
222
223
224void Selection::shrink(int xRadius, int yRadius, bool edgeLock)
225{
226 if (!d->selection) return;
227 KisShrinkSelectionFilter sf(xRadius, yRadius, edgeLock);
229 sf.process(d->selection->pixelSelection(), rc);
230}
231
233{
234 if (!d->selection) return;
237 sf.process(d->selection->pixelSelection(), rc);
238}
239
240
242{
243 if (!d->selection) return;
246 sf.process(d->selection->pixelSelection(), rc);
247}
248
249void Selection::resize(int w, int h)
250{
251 if (!d->selection) return;
252 d->selection->pixelSelection()->select(QRect(x(), y(), w, h));
253}
254
255void Selection::select(int x, int y, int w, int h, int value)
256{
257 if (!d->selection) return;
258 d->selection->pixelSelection()->select(QRect(x, y, w, h), value);
259}
260
262{
263 if (!d->selection) return;
265}
266
268{
269 if (!d->selection) return;
271}
272
273void Selection::add(Selection *selection)
274{
275 if (!d->selection) return;
277}
278
280{
281 if (!d->selection) return;
283}
284
286{
287 if (!d->selection) return;
289}
290
296
297
298QByteArray Selection::pixelData(int x, int y, int w, int h) const
299{
300 QByteArray ba;
301 if (!d->selection) return ba;
303 quint8 *data = new quint8[w * h];
304 dev->readBytes(data, x, y, w, h);
305 ba = QByteArray((const char*)data, (int)(w * h));
306 delete[] data;
307 return ba;
308}
309
310void Selection::setPixelData(QByteArray value, int x, int y, int w, int h)
311{
312 if (!d->selection) return;
314 if (!dev) return;
315 dev->writeBytes((const quint8*)value.constData(), x, y, w, h);
316}
317
319{
320 return d->selection;
321}
322
323
float value(const T *src, size_t ch)
@ SELECTION_REPLACE
@ SELECTION_INTERSECT
@ SELECTION_SYMMETRICDIFFERENCE
@ SELECTION_SUBTRACT
@ SELECTION_ADD
virtual const quint8 * oldRawData() const =0
virtual bool nextPixel()=0
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
static KisClipboard * instance()
void setClip(KisPaintDeviceSP dev, const QPoint &topLeft)
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
virtual void nextRow()=0
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const KoColorSpace * colorSpace() const
void clearSelection(KisSelectionSP selection)
KisDefaultBoundsBaseSP defaultBounds() const
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
void writeBytes(const quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h)
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
QRect changeRect(const QRect &rect, KisDefaultBoundsBaseSP defaultBounds) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
virtual qreal opacityF(const quint8 *pixel) const =0
virtual void applyAlphaNormedFloatMask(quint8 *pixels, const float *alpha, qint32 nPixels) const =0
Definition Node.h:24
KisNodeSP node() const
Definition Node.cpp:827
void move(int x, int y)
Definition Selection.cpp:94
void resize(int w, int h)
void cut(Node *node)
cut erases the area defined by the selection from the node and puts a copy on the clipboard.
int y() const
Definition Selection.cpp:84
void intersect(Selection *selection)
void copy(Node *node)
copy copies the area defined by the selection from the node to the clipboard.
Selection(KisSelectionSP selection, QObject *parent=0)
Definition Selection.cpp:26
void paste(Node *destination, int x, int y)
paste pastes the content of the clipboard to the given node, limited by the area of the current selec...
int width() const
Definition Selection.cpp:62
void selectAll(Node *node, int value)
KisSelectionSP selection() const
bool operator==(const Selection &other) const
Definition Selection.cpp:46
void clear()
void contract(int value)
void shrink(int xRadius, int yRadius, bool edgeLock)
Selection * duplicate() const
Definition Selection.cpp:56
void smooth()
~Selection() override
Definition Selection.cpp:41
void subtract(Selection *selection)
int x() const
Definition Selection.cpp:74
void dilate()
Private *const d
Definition Selection.h:241
void erode()
void feather(int radius)
void setPixelData(QByteArray value, int x, int y, int w, int h)
setPixelData writes the given bytes, of which there must be enough, into the Selection.
void invert()
void border(int xRadius, int yRadius)
QByteArray pixelData(int x, int y, int w, int h) const
pixelData reads the given rectangle from the Selection's mask and returns it as a byte array....
void grow(int xradius, int yradius)
bool operator!=(const Selection &other) const
Definition Selection.cpp:51
void add(Selection *selection)
void select(int x, int y, int w, int h, int value)
int height() const
Definition Selection.cpp:68
void replace(Selection *selection)
void symmetricdifference(Selection *selection)
virtual QRect exactBounds() const
virtual KisPaintDeviceSP paintDevice() const =0
bool hasEditablePaintDevice() const
virtual void setDirty()
Definition kis_node.cpp:577
void moveTo(const QPoint &pt) override
void select(const QRect &r, quint8 selectedness=MAX_SELECTED)
void applySelection(KisPixelSelectionSP selection, SelectionAction action)
KisPixelSelectionSP projection() const
qint32 x() const
bool hasNonEmptyPixelSelection() const
KisPixelSelectionSP pixelSelection
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
qint32 y() const
KisSelectionSP selection
Definition Selection.cpp:23