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>
13#include <kis_selection_filters.h>
14#include <kis_painter.h>
16#include <kis_clipboard.h>
21struct Selection::Private {
23 KisSelectionSP selection;
30 d->selection = selection;
38 d->selection =
new KisSelection();
41Selection::~Selection()
46bool Selection::operator==(
const Selection &other)
const
48 return (d->selection == other.d->selection);
51bool Selection::operator!=(
const Selection &other)
const
53 return !(operator==(other));
58 return new Selection(d->selection ?
new KisSelection(*d->selection)
59 :
new KisSelection());
64 if (!d->selection)
return 0;
65 return d->selection->selectedExactRect().width();
70 if (!d->selection)
return 0;
71 return d->selection->selectedExactRect().height();
76 if (!d->selection)
return 0;
77 int xPos = d->selection->x();
78 if (d->selection->hasNonEmptyPixelSelection()) {
79 xPos = d->selection->selectedExactRect().x();
86 if (!d->selection)
return 0;
87 int yPos = d->selection->y();
88 if (d->selection->hasNonEmptyPixelSelection()) {
89 yPos = d->selection->selectedExactRect().y();
96 if (!d->selection)
return;
97 d->selection->pixelSelection()->moveTo(
QPoint(
x,
y));
103 if (!d->selection)
return;
104 d->selection->clear();
109 if (!d->selection)
return;
110 d->selection->pixelSelection()->select(
QRect(
x(),
y(),
width() - value,
height() - value));
116 if (!d->selection)
return;
117 if (node->node()->exactBounds().isEmpty())
return;
118 if (!node->node()->hasEditablePaintDevice())
return;
120 KisPaintDeviceSP dev = node->node()->paintDevice();
121 KisPaintDeviceSP clip =
new KisPaintDevice(dev->colorSpace());
122 KisPaintDeviceSP selectionProjection = d->selection->projection();
124 const KoColorSpace *cs = clip->colorSpace();
125 const KoColorSpace *selCs = d->selection->projection()->colorSpace();
127 QRect rc = d->selection->selectedExactRect();
129 KisPainter::copyAreaOptimized(
QPoint(), dev, clip, rc);
131 KisHLineIteratorSP layerIt = clip->createHLineIteratorNG(0, 0, rc.
width());
132 KisHLineConstIteratorSP selectionIt = selectionProjection->createHLineIteratorNG(rc.
x(), rc.
y(), rc.
width());
134 for (qint32
y = 0;
y < rc.
height();
y++) {
135 for (qint32
x = 0;
x < rc.
width();
x++) {
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;
142 cs->applyAlphaNormedFloatMask(layerIt->rawData(), &mask, 1);
144 layerIt->nextPixel();
145 selectionIt->nextPixel();
148 selectionIt->nextRow();
151 KisClipboard::instance()->setClip(clip, rc.
topLeft());
157 if (!d->selection)
return;
158 if (node->node()->exactBounds().isEmpty())
return;
159 if (!node->node()->hasEditablePaintDevice())
return;
160 KisPaintDeviceSP dev = node->node()->paintDevice();
162 dev->clearSelection(d->selection);
163 node->node()->setDirty(d->selection->selectedExactRect());
168 if (!destination)
return;
169 if (!d->selection)
return;
170 if (!KisClipboard::instance()->hasClip())
return;
172 KisPaintDeviceSP src = KisClipboard::instance()->clip(
QRect(),
false);
173 KisPaintDeviceSP dst = destination->node()->paintDevice();
174 if (!dst || !src)
return;
175 KisPainter::copyAreaOptimized(
QPoint(
x,
y),
180 destination->node()->setDirty();
185 if (!d->selection)
return;
186 KisErodeSelectionFilter esf;
187 QRect rc = esf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
188 esf.process(d->selection->pixelSelection(), rc);
193 if (!d->selection)
return;
194 KisDilateSelectionFilter dsf;
195 QRect rc = dsf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
196 dsf.process(d->selection->pixelSelection(), rc);
201 if (!d->selection)
return;
202 KisBorderSelectionFilter sf(xRadius, yRadius,
true);
203 QRect rc = sf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
204 sf.process(d->selection->pixelSelection(), rc);
209 if (!d->selection)
return;
210 KisFeatherSelectionFilter fsf(radius);
211 QRect rc = fsf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
212 fsf.process(d->selection->pixelSelection(), rc);
217 if (!d->selection)
return;
218 KisGrowSelectionFilter gsf(xradius, yradius);
219 QRect rc = gsf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
220 gsf.process(d->selection->pixelSelection(), rc);
226 if (!d->selection)
return;
227 KisShrinkSelectionFilter sf(xRadius, yRadius, edgeLock);
228 QRect rc = sf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
229 sf.process(d->selection->pixelSelection(), rc);
234 if (!d->selection)
return;
235 KisSmoothSelectionFilter sf;
236 QRect rc = sf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
237 sf.process(d->selection->pixelSelection(), rc);
243 if (!d->selection)
return;
244 KisInvertSelectionFilter sf;
245 QRect rc = sf.changeRect(d->selection->selectedExactRect(), d->selection->pixelSelection()->defaultBounds());
246 sf.process(d->selection->pixelSelection(), rc);
251 if (!d->selection)
return;
252 d->selection->pixelSelection()->select(
QRect(
x(),
y(), w, h));
257 if (!d->selection)
return;
258 d->selection->pixelSelection()->select(
QRect(
x,
y, w, h), value);
263 if (!d->selection)
return;
264 d->selection->pixelSelection()->select(node->node()->exactBounds(), value);
269 if (!d->selection)
return;
270 d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_REPLACE);
275 if (!d->selection)
return;
276 d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_ADD);
281 if (!d->selection)
return;
282 d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_SUBTRACT);
287 if (!d->selection)
return;
288 d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_INTERSECT);
293 if (!d->selection)
return;
294 d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_SYMMETRICDIFFERENCE);
301 if (!d->selection)
return ba;
302 KisPaintDeviceSP dev = d->selection->projection();
303 quint8 *data =
new quint8[w * h];
304 dev->readBytes(data,
x,
y, w, h);
305 ba =
QByteArray((
const char*)data, (
int)(w * h));
312 if (!d->selection)
return;
313 KisPixelSelectionSP dev = d->selection->pixelSelection();
315 dev->writeBytes((
const quint8*)value.
constData(),
x,
y, w, h);
318KisSelectionSP Selection::selection()
const
Node represents a layer or mask in a Krita image's Node hierarchy.
Selection represents a selection on Krita.
void move(int x, int y)
Move the selection's top-left corner to the given coordinates.
void resize(int w, int h)
Resize the selection to the given width and height.
void cut(Node *node)
cut erases the area defined by the selection from the node and puts a copy on the clipboard.
void intersect(Selection *selection)
Intersect the given selection with this 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)
For internal use only.
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...
void selectAll(Node *node, int value)
Select all pixels in the given node.
void clear()
Make the selection entirely unselected.
void contract(int value)
Make the selection's width and height smaller by the given value.
void shrink(int xRadius, int yRadius, bool edgeLock)
Shrink the selection with the given radius.
Selection * duplicate() const
void smooth()
Smooth the selection.
void subtract(Selection *selection)
Subtract the given selection's selected pixels from the current selection.
void dilate()
Dilate the selection with a radius of 1 pixel.
void erode()
Erode the selection with a radius of 1 pixel.
void feather(int radius)
Feather the selection with the given 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()
Invert the selection.
void border(int xRadius, int yRadius)
Border the selection with the given radius.
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)
Grow the selection with the given radius.
void add(Selection *selection)
Add the given selection's selected pixels to the current selection.
void select(int x, int y, int w, int h, int value)
Select the given area.
void replace(Selection *selection)
Replace the current selection's selection with the one of the given selection.
void symmetricdifference(Selection *selection)
Intersect with the inverse of the given selection with this selection.
const char * constData() const const
QPoint topLeft() const const