chalk

kis_selection.cpp
1/*
2 * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * this program is free software; you can redistribute it and/or modify
5 * it under the terms of the gnu general public license as published by
6 * the free software foundation; either version 2 of the license, or
7 * (at your option) any later version.
8 *
9 * this program is distributed in the hope that it will be useful,
10 * but without any warranty; without even the implied warranty of
11 * merchantability or fitness for a particular purpose. see the
12 * gnu general public license for more details.
13 *
14 * you should have received a copy of the gnu general public license
15 * along with this program; if not, write to the free software
16 * foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
17 */
18
19#include <tqimage.h>
20
21#include <kdebug.h>
22#include <tdelocale.h>
23#include <tqcolor.h>
24
25#include "kis_layer.h"
26#include "kis_debug_areas.h"
27#include "kis_types.h"
28#include "kis_colorspace_factory_registry.h"
29#include "kis_fill_painter.h"
30#include "kis_iterators_pixel.h"
31#include "kis_integer_maths.h"
32#include "kis_image.h"
33#include "kis_datamanager.h"
34#include "kis_fill_painter.h"
35#include "kis_selection.h"
36
37KisSelection::KisSelection(KisPaintDeviceSP dev)
38 : super(dev->parentLayer()
39 , KisMetaRegistry::instance()->csRegistry()->getAlpha8()
40 , (TQString("selection for ") + dev->name()).latin1())
41 , m_parentPaintDevice(dev)
42 , m_doCacheExactRect(false)
43 , m_dirty(false)
44{
45 Q_ASSERT(dev);
46}
47
49 : super(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "anonymous selection")
50 , m_parentPaintDevice(0), m_dirty(false)
51{
52}
53
55 : super(rhs), m_parentPaintDevice(rhs.m_parentPaintDevice), m_doCacheExactRect(rhs.m_doCacheExactRect),
56 m_cachedExactRect(rhs.m_cachedExactRect), m_dirty(rhs.m_dirty)
57{
58}
59
60KisSelection::~KisSelection()
61{
62}
63
64TQ_UINT8 KisSelection::selected(TQ_INT32 x, TQ_INT32 y)
65{
66 KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, false);
67
68 TQ_UINT8 *pix = iter.rawData();
69
70 return *pix;
71}
72
73void KisSelection::setSelected(TQ_INT32 x, TQ_INT32 y, TQ_UINT8 s)
74{
75 KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, true);
76
77 TQ_UINT8 *pix = iter.rawData();
78
79 *pix = s;
80}
81
82TQImage KisSelection::maskImage()
83{
84 // If part of a KisAdjustmentLayer, there may be no parent device.
85 TQImage img;
86 TQRect bounds;
87 if (m_parentPaintDevice) {
88
89 bounds = m_parentPaintDevice->exactBounds();
90 bounds = bounds.intersect( m_parentPaintDevice->image()->bounds() );
91 img = TQImage(bounds.width(), bounds.height(), 32);
92 }
93 else {
94 bounds = TQRect( 0, 0, image()->width(), image()->height());
95 img = TQImage(bounds.width(), bounds.height(), 32);
96 }
97
98 KisHLineIteratorPixel it = createHLineIterator(bounds.x(), bounds.y(), bounds.width(), false);
99 for (int y2 = bounds.y(); y2 < bounds.height() - bounds.y(); ++y2) {
100 int x2 = 0;
101 while (!it.isDone()) {
102 TQ_UINT8 s = MAX_SELECTED - *(it.rawData());
103 TQ_INT32 c = tqRgb(s, s, s);
104 img.setPixel(x2, y2, c);
105 ++x2;
106 ++it;
107 }
108 it.nextRow();
109 }
110 return img;
111}
112void KisSelection::select(TQRect r)
113{
114 KisFillPainter painter(this);
115 KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
116 painter.fillRect(r, KisColor(TQt::white, cs), MAX_SELECTED);
117 TQ_INT32 x, y, w, h;
118 extent(x, y, w, h);
119}
120
121void KisSelection::clear(TQRect r)
122{
123 KisFillPainter painter(this);
124 KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
125 painter.fillRect(r, KisColor(TQt::white, cs), MIN_SELECTED);
126}
127
129{
130 TQ_UINT8 defPixel = MIN_SELECTED;
131 m_datamanager->setDefaultPixel(&defPixel);
132 m_datamanager->clear();
133}
134
135void KisSelection::invert()
136{
137 TQ_INT32 x,y,w,h;
138
139 extent(x, y, w, h);
140 KisRectIterator it = createRectIterator(x, y, w, h, true);
141 while ( ! it.isDone() )
142 {
143 // CBR this is wrong only first byte is inverted
144 // BSAR: But we have always only one byte in this color model :-).
145 *(it.rawData()) = MAX_SELECTED - *(it.rawData());
146 ++it;
147 }
148 TQ_UINT8 defPixel = MAX_SELECTED - *(m_datamanager->defaultPixel());
149 m_datamanager->setDefaultPixel(&defPixel);
150}
151
153{
154 if(*(m_datamanager->defaultPixel()) != MIN_SELECTED)
155 return false;
156 TQRect sr = selectedExactRect();
157 return ! r.intersects(sr);
158}
159
161{
162 if(*(m_datamanager->defaultPixel()) != MIN_SELECTED)
163 return false;
164 TQRect sr = selectedRect();
165 return ! r.intersects(sr);
166}
167
168
170{
171 if(*(m_datamanager->defaultPixel()) == MIN_SELECTED || !m_parentPaintDevice)
172 return extent();
173 else
174 return extent().unite(m_parentPaintDevice->extent());
175}
176
178{
179 if(m_doCacheExactRect)
180 return m_cachedExactRect;
181 else if(*(m_datamanager->defaultPixel()) == MIN_SELECTED || !m_parentPaintDevice)
182 return exactBounds();
183 else
184 return exactBounds().unite(m_parentPaintDevice->exactBounds());
185}
186
187void KisSelection::stopCachingExactRect()
188{
189 kdDebug() << "stop caching the exact rect" << endl;
190 m_doCacheExactRect = false;
191}
192
193
194void KisSelection::startCachingExactRect()
195{
196 kdDebug() << "start caching the exact rect" << endl;
197 if(*(m_datamanager->defaultPixel()) == MIN_SELECTED || !m_parentPaintDevice)
198 m_cachedExactRect = exactBounds();
199 else
200 m_cachedExactRect = exactBounds().unite(m_parentPaintDevice->exactBounds());
201 m_doCacheExactRect = true;
202}
203
204void KisSelection::paintUniformSelectionRegion(TQImage img, const TQRect& imageRect, const TQRegion& uniformRegion)
205{
206 Q_ASSERT(img.size() == imageRect.size());
207 Q_ASSERT(imageRect.contains(uniformRegion.boundingRect()));
208
209 if (img.isNull() || img.size() != imageRect.size() || !imageRect.contains(uniformRegion.boundingRect())) {
210 return;
211 }
212
213 if (*m_datamanager->defaultPixel() == MIN_SELECTED) {
214
215 TQRegion region = uniformRegion & TQRegion(imageRect);
216
217 if (!region.isEmpty()) {
218 TQMemArray<TQRect> rects = region.rects();
219
220 for (unsigned int i = 0; i < rects.count(); i++) {
221 TQRect r = rects[i];
222
223 for (TQ_INT32 y = 0; y < r.height(); ++y) {
224
225 TQRgb *imagePixel = reinterpret_cast<TQRgb *>(img.scanLine(r.y() - imageRect.y() + y));
226 imagePixel += r.x() - imageRect.x();
227
228 TQ_INT32 numPixels = r.width();
229
230 while (numPixels > 0) {
231
232 TQRgb srcPixel = *imagePixel;
233 TQ_UINT8 srcGrey = (tqRed(srcPixel) + tqGreen(srcPixel) + tqBlue(srcPixel)) / 9;
234 TQ_UINT8 srcAlpha = tqAlpha(srcPixel);
235
236 srcGrey = UINT8_MULT(srcGrey, srcAlpha);
237 TQ_UINT8 dstAlpha = TQMAX(srcAlpha, 192);
238
239 TQRgb dstPixel = tqRgba(128 + srcGrey, 128 + srcGrey, 165 + srcGrey, dstAlpha);
240 *imagePixel = dstPixel;
241
242 ++imagePixel;
243 --numPixels;
244 }
245 }
246 }
247 }
248 }
249}
250
251void KisSelection::paintSelection(TQImage img, TQ_INT32 imageRectX, TQ_INT32 imageRectY, TQ_INT32 imageRectWidth, TQ_INT32 imageRectHeight)
252{
253 Q_ASSERT(img.size() == TQSize(imageRectWidth, imageRectHeight));
254
255 if (img.isNull() || img.size() != TQSize(imageRectWidth, imageRectHeight)) {
256 return;
257 }
258
259 TQRect imageRect(imageRectX, imageRectY, imageRectWidth, imageRectHeight);
260 TQRect selectionExtent = extent();
261
262 selectionExtent.setLeft(selectionExtent.left() - 1);
263 selectionExtent.setTop(selectionExtent.top() - 1);
264 selectionExtent.setWidth(selectionExtent.width() + 2);
265 selectionExtent.setHeight(selectionExtent.height() + 2);
266
267 TQRegion uniformRegion = TQRegion(imageRect);
268 uniformRegion -= TQRegion(selectionExtent);
269
270 if (!uniformRegion.isEmpty()) {
271 paintUniformSelectionRegion(img, imageRect, uniformRegion);
272 }
273
274 TQRect nonuniformRect = imageRect & selectionExtent;
275
276 if (!nonuniformRect.isEmpty()) {
277
278 const TQ_INT32 imageRectOffsetX = nonuniformRect.x() - imageRectX;
279 const TQ_INT32 imageRectOffsetY = nonuniformRect.y() - imageRectY;
280
281 imageRectX = nonuniformRect.x();
282 imageRectY = nonuniformRect.y();
283 imageRectWidth = nonuniformRect.width();
284 imageRectHeight = nonuniformRect.height();
285
286 const TQ_INT32 NUM_SELECTION_ROWS = 3;
287
288 TQ_UINT8 *selectionRow[NUM_SELECTION_ROWS];
289
290 TQ_INT32 aboveRowIndex = 0;
291 TQ_INT32 centreRowIndex = 1;
292 TQ_INT32 belowRowIndex = 2;
293
294 selectionRow[aboveRowIndex] = new TQ_UINT8[imageRectWidth + 2];
295 selectionRow[centreRowIndex] = new TQ_UINT8[imageRectWidth + 2];
296 selectionRow[belowRowIndex] = new TQ_UINT8[imageRectWidth + 2];
297
298 readBytes(selectionRow[centreRowIndex], imageRectX - 1, imageRectY - 1, imageRectWidth + 2, 1);
299 readBytes(selectionRow[belowRowIndex], imageRectX - 1, imageRectY, imageRectWidth + 2, 1);
300
301 for (TQ_INT32 y = 0; y < imageRectHeight; ++y) {
302
303 TQ_INT32 oldAboveRowIndex = aboveRowIndex;
304 aboveRowIndex = centreRowIndex;
305 centreRowIndex = belowRowIndex;
306 belowRowIndex = oldAboveRowIndex;
307
308 readBytes(selectionRow[belowRowIndex], imageRectX - 1, imageRectY + y + 1, imageRectWidth + 2, 1);
309
310 const TQ_UINT8 *aboveRow = selectionRow[aboveRowIndex] + 1;
311 const TQ_UINT8 *centreRow = selectionRow[centreRowIndex] + 1;
312 const TQ_UINT8 *belowRow = selectionRow[belowRowIndex] + 1;
313
314 TQRgb *imagePixel = reinterpret_cast<TQRgb *>(img.scanLine(imageRectOffsetY + y));
315 imagePixel += imageRectOffsetX;
316
317 for (TQ_INT32 x = 0; x < imageRectWidth; ++x) {
318
319 TQ_UINT8 centre = *centreRow;
320
321 if (centre != MAX_SELECTED) {
322
323 // this is where we come if the pixels should be blue or bluish
324
325 TQRgb srcPixel = *imagePixel;
326 TQ_UINT8 srcGrey = (tqRed(srcPixel) + tqGreen(srcPixel) + tqBlue(srcPixel)) / 9;
327 TQ_UINT8 srcAlpha = tqAlpha(srcPixel);
328
329 // Colour influence is proportional to alphaPixel.
330 srcGrey = UINT8_MULT(srcGrey, srcAlpha);
331
332 TQRgb dstPixel;
333
334 if (centre == MIN_SELECTED) {
335 //this is where we come if the pixels should be blue (or red outline)
336
337 TQ_UINT8 left = *(centreRow - 1);
338 TQ_UINT8 right = *(centreRow + 1);
339 TQ_UINT8 above = *aboveRow;
340 TQ_UINT8 below = *belowRow;
341
342 // Stop unselected transparent areas from appearing the same
343 // as selected transparent areas.
344 TQ_UINT8 dstAlpha = TQMAX(srcAlpha, 192);
345
346 // now for a simple outline based on 4-connectivity
347 if (left != MIN_SELECTED || right != MIN_SELECTED || above != MIN_SELECTED || below != MIN_SELECTED) {
348 dstPixel = tqRgba(255, 0, 0, dstAlpha);
349 } else {
350 dstPixel = tqRgba(128 + srcGrey, 128 + srcGrey, 165 + srcGrey, dstAlpha);
351 }
352 } else {
353 dstPixel = tqRgba(UINT8_BLEND(tqRed(srcPixel), srcGrey + 128, centre),
354 UINT8_BLEND(tqGreen(srcPixel), srcGrey + 128, centre),
355 UINT8_BLEND(tqBlue(srcPixel), srcGrey + 165, centre),
356 srcAlpha);
357 }
358
359 *imagePixel = dstPixel;
360 }
361
362 aboveRow++;
363 centreRow++;
364 belowRow++;
365 imagePixel++;
366 }
367 }
368
369 delete [] selectionRow[aboveRowIndex];
370 delete [] selectionRow[centreRowIndex];
371 delete [] selectionRow[belowRowIndex];
372 }
373}
374
375void KisSelection::paintSelection(TQImage img, const TQRect& scaledImageRect, const TQSize& scaledImageSize, const TQSize& imageSize)
376{
377 if (img.isNull() || scaledImageRect.isEmpty() || scaledImageSize.isEmpty() || imageSize.isEmpty()) {
378 return;
379 }
380
381 Q_ASSERT(img.size() == scaledImageRect.size());
382
383 if (img.size() != scaledImageRect.size()) {
384 return;
385 }
386
387 TQ_INT32 imageWidth = imageSize.width();
388 TQ_INT32 imageHeight = imageSize.height();
389
390 TQRect selectionExtent = extent();
391
392 selectionExtent.setLeft(selectionExtent.left() - 1);
393 selectionExtent.setTop(selectionExtent.top() - 1);
394 selectionExtent.setWidth(selectionExtent.width() + 2);
395 selectionExtent.setHeight(selectionExtent.height() + 2);
396
397 double xScale = static_cast<double>(scaledImageSize.width()) / imageWidth;
398 double yScale = static_cast<double>(scaledImageSize.height()) / imageHeight;
399
400 TQRect scaledSelectionExtent;
401
402 scaledSelectionExtent.setLeft(static_cast<int>(selectionExtent.left() * xScale));
403 scaledSelectionExtent.setRight(static_cast<int>(ceil((selectionExtent.right() + 1) * xScale)) - 1);
404 scaledSelectionExtent.setTop(static_cast<int>(selectionExtent.top() * yScale));
405 scaledSelectionExtent.setBottom(static_cast<int>(ceil((selectionExtent.bottom() + 1) * yScale)) - 1);
406
407 TQRegion uniformRegion = TQRegion(scaledImageRect);
408 uniformRegion -= TQRegion(scaledSelectionExtent);
409
410 if (!uniformRegion.isEmpty()) {
411 paintUniformSelectionRegion(img, scaledImageRect, uniformRegion);
412 }
413
414 TQRect nonuniformRect = scaledImageRect & scaledSelectionExtent;
415
416 if (!nonuniformRect.isEmpty()) {
417
418 const TQ_INT32 scaledImageRectXOffset = nonuniformRect.x() - scaledImageRect.x();
419 const TQ_INT32 scaledImageRectYOffset = nonuniformRect.y() - scaledImageRect.y();
420
421 const TQ_INT32 scaledImageRectX = nonuniformRect.x();
422 const TQ_INT32 scaledImageRectY = nonuniformRect.y();
423 const TQ_INT32 scaledImageRectWidth = nonuniformRect.width();
424 const TQ_INT32 scaledImageRectHeight = nonuniformRect.height();
425
426 const TQ_INT32 imageRowLeft = static_cast<TQ_INT32>(scaledImageRectX / xScale);
427 const TQ_INT32 imageRowRight = static_cast<TQ_INT32>((ceil((scaledImageRectX + scaledImageRectWidth - 1 + 1) / xScale)) - 1);
428
429 const TQ_INT32 imageRowWidth = imageRowRight - imageRowLeft + 1;
430 const TQ_INT32 imageRowStride = imageRowWidth + 2;
431
432 const TQ_INT32 NUM_SELECTION_ROWS = 3;
433
434 TQ_INT32 aboveRowIndex = 0;
435 TQ_INT32 centreRowIndex = 1;
436 TQ_INT32 belowRowIndex = 2;
437
438 TQ_INT32 aboveRowSrcY = -3;
439 TQ_INT32 centreRowSrcY = -3;
440 TQ_INT32 belowRowSrcY = -3;
441
442 TQ_UINT8 *selectionRows = new TQ_UINT8[imageRowStride * NUM_SELECTION_ROWS];
443 TQ_UINT8 *selectionRow[NUM_SELECTION_ROWS];
444
445 selectionRow[0] = selectionRows + 1;
446 selectionRow[1] = selectionRow[0] + imageRowStride;
447 selectionRow[2] = selectionRow[0] + (2 * imageRowStride);
448
449 for (TQ_INT32 y = 0; y < scaledImageRectHeight; ++y) {
450
451 TQ_INT32 scaledY = scaledImageRectY + y;
452 TQ_INT32 srcY = (scaledY * imageHeight) / scaledImageSize.height();
453
454 TQ_UINT8 *aboveRow;
455 TQ_UINT8 *centreRow;
456 TQ_UINT8 *belowRow;
457
458 if (srcY - 1 == aboveRowSrcY) {
459 aboveRow = selectionRow[aboveRowIndex];
460 centreRow = selectionRow[centreRowIndex];
461 belowRow = selectionRow[belowRowIndex];
462 } else if (srcY - 1 == centreRowSrcY) {
463
464 TQ_INT32 oldAboveRowIndex = aboveRowIndex;
465
466 aboveRowIndex = centreRowIndex;
467 centreRowIndex = belowRowIndex;
468 belowRowIndex = oldAboveRowIndex;
469
470 aboveRow = selectionRow[aboveRowIndex];
471 centreRow = selectionRow[centreRowIndex];
472 belowRow = selectionRow[belowRowIndex];
473
474 readBytes(belowRow - 1, imageRowLeft - 1, srcY + 1, imageRowStride, 1);
475
476 } else if (srcY - 1 == belowRowSrcY) {
477
478 TQ_INT32 oldAboveRowIndex = aboveRowIndex;
479 TQ_INT32 oldCentreRowIndex = centreRowIndex;
480
481 aboveRowIndex = belowRowIndex;
482 centreRowIndex = oldAboveRowIndex;
483 belowRowIndex = oldCentreRowIndex;
484
485 aboveRow = selectionRow[aboveRowIndex];
486 centreRow = selectionRow[centreRowIndex];
487 belowRow = selectionRow[belowRowIndex];
488
489 if (belowRowIndex == centreRowIndex + 1) {
490 readBytes(centreRow - 1, imageRowLeft - 1, srcY, imageRowStride, 2);
491 } else {
492 readBytes(centreRow - 1, imageRowLeft - 1, srcY, imageRowStride, 1);
493 readBytes(belowRow - 1, imageRowLeft - 1, srcY + 1, imageRowStride, 1);
494 }
495
496 } else {
497
498 aboveRowIndex = 0;
499 centreRowIndex = 1;
500 belowRowIndex = 2;
501
502 aboveRow = selectionRow[aboveRowIndex];
503 centreRow = selectionRow[centreRowIndex];
504 belowRow = selectionRow[belowRowIndex];
505
506 readBytes(selectionRows, imageRowLeft - 1, srcY - 1, imageRowStride, NUM_SELECTION_ROWS);
507 }
508
509 aboveRowSrcY = srcY - 1;
510 centreRowSrcY = aboveRowSrcY + 1;
511 belowRowSrcY = centreRowSrcY + 1;
512
513 TQRgb *imagePixel = reinterpret_cast<TQRgb *>(img.scanLine(scaledImageRectYOffset + y));
514 imagePixel += scaledImageRectXOffset;
515
516 for (TQ_INT32 x = 0; x < scaledImageRectWidth; ++x) {
517
518 TQ_INT32 scaledX = scaledImageRectX + x;
519 TQ_INT32 srcX = (scaledX * imageWidth) / scaledImageSize.width();
520
521 TQ_UINT8 centre = *(centreRow + srcX - imageRowLeft);
522
523 if (centre != MAX_SELECTED) {
524
525 // this is where we come if the pixels should be blue or bluish
526
527 TQRgb srcPixel = *imagePixel;
528 TQ_UINT8 srcGrey = (tqRed(srcPixel) + tqGreen(srcPixel) + tqBlue(srcPixel)) / 9;
529 TQ_UINT8 srcAlpha = tqAlpha(srcPixel);
530
531 // Colour influence is proportional to alphaPixel.
532 srcGrey = UINT8_MULT(srcGrey, srcAlpha);
533
534 TQRgb dstPixel;
535
536 if (centre == MIN_SELECTED) {
537 //this is where we come if the pixels should be blue (or red outline)
538
539 TQ_UINT8 left = *(centreRow + (srcX - imageRowLeft) - 1);
540 TQ_UINT8 right = *(centreRow + (srcX - imageRowLeft) + 1);
541 TQ_UINT8 above = *(aboveRow + (srcX - imageRowLeft));
542 TQ_UINT8 below = *(belowRow + (srcX - imageRowLeft));
543
544 // Stop unselected transparent areas from appearing the same
545 // as selected transparent areas.
546 TQ_UINT8 dstAlpha = TQMAX(srcAlpha, 192);
547
548 // now for a simple outline based on 4-connectivity
549 if (left != MIN_SELECTED || right != MIN_SELECTED || above != MIN_SELECTED || below != MIN_SELECTED) {
550 dstPixel = tqRgba(255, 0, 0, dstAlpha);
551 } else {
552 dstPixel = tqRgba(128 + srcGrey, 128 + srcGrey, 165 + srcGrey, dstAlpha);
553 }
554 } else {
555 dstPixel = tqRgba(UINT8_BLEND(tqRed(srcPixel), srcGrey + 128, centre),
556 UINT8_BLEND(tqGreen(srcPixel), srcGrey + 128, centre),
557 UINT8_BLEND(tqBlue(srcPixel), srcGrey + 165, centre),
558 srcAlpha);
559 }
560
561 *imagePixel = dstPixel;
562 }
563
564 imagePixel++;
565 }
566 }
567
568 delete [] selectionRows;
569 }
570}
571
572void KisSelection::setDirty(const TQRect& rc)
573{
574 if (m_dirty)
575 super::setDirty(rc);
576}
577
579{
580 if (m_dirty)
582}
KisColorSpace * getRGB8()
Convenience method to get an RGB colorspace with the default lcms profile.
A single singleton that provides access to several registries.
KisImage * image() const
Return the image that contains this paint device, or 0 if it is not part of an image.
KisRectIteratorPixel createRectIterator(TQ_INT32 left, TQ_INT32 top, TQ_INT32 w, TQ_INT32 h, bool writable)
This function return an iterator which points to the first pixel of an rectangle.
KisLayer * parentLayer() const
Returns the KisLayer that contains this paint device, or 0 if this is not part of a layer.
virtual void readBytes(TQ_UINT8 *data, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h)
Read the bytes representing the rectangle described by x, y, w, h into data.
virtual void setDirty()
Set the parent layer completely dirty, if this paint device has one.
KisHLineIteratorPixel createHLineIterator(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, bool writable)
This function return an iterator which points to the first pixel of a horizontal line.
The KisRectIterator iterators over a rectangular area in the most efficient order.
TQ_UINT8 * rawData() const
returns a pointer to the pixel data. Do NOT interpret the data - leave that to a colorstrategy
bool isDone() const
returns true when iterators has reached the end
TQRect selectedRect() const
Rough, but fastish way of determining the area of the tiles used by the selection.
TQRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
KisSelection()
Create a new KisSelection.
virtual void setDirty()
Set the parent layer completely dirty, if this paint device has one.
bool isTotallyUnselected(TQRect r)
Tests if the the rect is totally outside the selection.
void clear()
Complete erase the current paint device.
KisSelection(KisPaintDeviceSP dev)
Create a new KisSelection.
bool isProbablyTotallyUnselected(TQRect r)
Tests if the the rect is totally outside the selection, but uses selectedRect instead of selectedRect...