Krita Source Code Documentation
Loading...
Searching...
No Matches
KisRegion Class Reference

#include <KisRegion.h>

+ Inheritance diagram for KisRegion:

Public Member Functions

QRect boundingRect () const
 
bool isEmpty () const
 
 KisRegion ()=default
 
 KisRegion (const KisRegion &rhs)=default
 
 KisRegion (const QRect &rect)
 
 KisRegion (const QVector< QRect > &rects)
 creates a region from a set of non-intersecting rectangles
 
 KisRegion (QVector< QRect > &&rects)
 
 KisRegion (std::initializer_list< QRect > rects)
 
KisRegionoperator&= (const QRect &rect)
 
KisRegionoperator= (const KisRegion &rhs)
 
int rectCount () const
 
QVector< QRect > rects () const
 
QRegion toQRegion () const
 
void translate (int dx, int dy)
 
KisRegion translated (int x, int y) const
 

Static Public Member Functions

static void approximateOverlappingRects (QVector< QRect > &rects, int gridSize)
 
static KisRegion fromOverlappingRects (const QVector< QRect > &rects, int gridSize)
 
static KisRegion fromQRegion (const QRegion &region)
 
static void makeGridLikeRectsUnique (QVector< QRect > &rects)
 
static QVector< QRect >::iterator mergeSparseRects (QVector< QRect >::iterator beginIt, QVector< QRect >::iterator endIt)
 merge a set of rectangles into a smaller set of bigger rectangles
 

Private Member Functions

void mergeAllRects ()
 

Private Attributes

QVector< QRect > m_rects
 

Friends

KRITAGLOBAL_EXPORT bool operator== (const KisRegion &lhs, const KisRegion &rhs)
 

Detailed Description

An more efficient (and more limited) replacement for QRegion.

Its main purpose it to be able to merge a huge set of rectangles into a smaller set of bigger rectangles, the same thing that QRegion is supposed to do. The main difference (and limitation) is: all the input rects must be non-intersecting. This requirement is perfectly fine for Krita's tiles, which do never intersect.

Definition at line 25 of file KisRegion.h.

Constructor & Destructor Documentation

◆ KisRegion() [1/6]

KisRegion::KisRegion ( )
default

◆ KisRegion() [2/6]

KisRegion::KisRegion ( const KisRegion & rhs)
default

◆ KisRegion() [3/6]

KisRegion::KisRegion ( const QRect & rect)

Definition at line 285 of file KisRegion.cpp.

286{
287 m_rects << rect;
288}
QVector< QRect > m_rects
Definition KisRegion.h:97

References m_rects.

◆ KisRegion() [4/6]

KisRegion::KisRegion ( std::initializer_list< QRect > rects)

Definition at line 290 of file KisRegion.cpp.

291 : m_rects(rects)
292{
293}
QVector< QRect > rects() const

◆ KisRegion() [5/6]

KisRegion::KisRegion ( const QVector< QRect > & rects)

creates a region from a set of non-intersecting rectangles

Parameters
rectsrectangles that should be merged. Rectangles must not intersect.

Definition at line 295 of file KisRegion.cpp.

296 : m_rects(rects)
297{
299}
void mergeAllRects()

References mergeAllRects().

◆ KisRegion() [6/6]

KisRegion::KisRegion ( QVector< QRect > && rects)

Definition at line 301 of file KisRegion.cpp.

302 : m_rects(rects)
303{
305}

References mergeAllRects().

Member Function Documentation

◆ approximateOverlappingRects()

void KisRegion::approximateOverlappingRects ( QVector< QRect > & rects,
int gridSize )
static

Simplifies rects in a way that they don't overlap anymore. The actual resulting area may be larger than original rects, but not more than gridSize in any dimension.

Definition at line 240 of file KisRegion.cpp.

241{
242 using namespace detail;
243
244 if (rects.isEmpty()) return;
245
246 QVector<QRect> rowsBuf;
247 QVector<QRect> intermediate;
248 QVector<QRect> tempBuf[2];
249
250 splitRects<VerticalSplitPolicy>(rects.begin(), rects.end(),
251 std::back_inserter(rowsBuf),
252 tempBuf, gridSize, VoidNoOp());
253
254 rects.clear();
257
258 auto rowBegin = rowsBuf.begin();
259 while (rowBegin != rowsBuf.end()) {
260 auto rowEnd = std::upper_bound(rowBegin, rowsBuf.end(),
261 QRect(rowBegin->x(),
262 rowBegin->y() + gridSize - 1,
263 1,1),
264 VerticalSplitPolicy::rowIsLess);
265
266 splitRects<HorizontalSplitPolicy>(rowBegin, rowEnd,
267 std::back_inserter(intermediate),
268 tempBuf, gridSize,
269 MergeRectsOp(intermediate, rects));
270 rowBegin = rowEnd;
271
272 KIS_SAFE_ASSERT_RECOVER_NOOP(intermediate.isEmpty());
275 }
276}
bool isEmpty() const
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References isEmpty(), KIS_SAFE_ASSERT_RECOVER_NOOP, and rects().

◆ boundingRect()

QRect KisRegion::boundingRect ( ) const

Definition at line 327 of file KisRegion.cpp.

328{
329 return std::accumulate(m_rects.constBegin(), m_rects.constEnd(), QRect(), std::bit_or<QRect>());
330}

References m_rects.

◆ fromOverlappingRects()

KisRegion KisRegion::fromOverlappingRects ( const QVector< QRect > & rects,
int gridSize )
static

Approximates a KisRegion from rects, which may overlap. The resulting KisRegion may be larger than the original set of rects, but it is guaranteed to cover it completely.

Definition at line 385 of file KisRegion.cpp.

386{
389 return KisRegion(tmp);
390}
KisRegion()=default
static void approximateOverlappingRects(QVector< QRect > &rects, int gridSize)

References approximateOverlappingRects(), KisRegion(), and rects().

◆ fromQRegion()

KisRegion KisRegion::fromQRegion ( const QRegion & region)
static

Definition at line 373 of file KisRegion.cpp.

374{
375 KisRegion result;
376 result.m_rects.clear();
377 QRegion::const_iterator begin = region.begin();
378 while (begin != region.end()) {
379 result.m_rects << *begin;
380 begin++;
381 }
382 return result;
383}

References m_rects.

◆ isEmpty()

bool KisRegion::isEmpty ( ) const

Definition at line 342 of file KisRegion.cpp.

343{
344 return boundingRect().isEmpty();
345}
QRect boundingRect() const

References boundingRect().

◆ makeGridLikeRectsUnique()

void KisRegion::makeGridLikeRectsUnique ( QVector< QRect > & rects)
static

Definition at line 278 of file KisRegion.cpp.

279{
281 auto it = std::unique(rects.begin(), rects.end());
282 rects.erase(it, rects.end());
283}
static bool elementIsLess(const QRect &lhs, const QRect &rhs)
Definition KisRegion.cpp:27

References detail::HorizontalMergePolicy::elementIsLess(), and rects().

◆ mergeAllRects()

void KisRegion::mergeAllRects ( )
private

Definition at line 392 of file KisRegion.cpp.

393{
394 auto endIt = mergeSparseRects(m_rects.begin(), m_rects.end());
395 m_rects.erase(endIt, m_rects.end());
396}
static QVector< QRect >::iterator mergeSparseRects(QVector< QRect >::iterator beginIt, QVector< QRect >::iterator endIt)
merge a set of rectangles into a smaller set of bigger rectangles

References m_rects, and mergeSparseRects().

◆ mergeSparseRects()

QVector< QRect >::iterator KisRegion::mergeSparseRects ( QVector< QRect >::iterator beginIt,
QVector< QRect >::iterator endIt )
static

merge a set of rectangles into a smaller set of bigger rectangles

The algorithm does two passes over the rectangles. First it tries to merge all the rectangles horizontally, then vertically. The merge happens in-place, that is, all the merged elements will be moved to the front of the original range.

The final range is defined by [beginIt, retvalIt)

Parameters
beginItiterator to the beginning of the source range
endItiterator to the end of the source range
Returns
iteration pointing past the last element of the merged range

Definition at line 233 of file KisRegion.cpp.

234{
235 endIt = detail::mergeRects(beginIt, endIt, detail::HorizontalMergePolicy());
236 endIt = detail::mergeRects(beginIt, endIt, detail::VerticalMergePolicy());
237 return endIt;
238}
QVector< QRect >::iterator mergeRects(QVector< QRect >::iterator beginIt, QVector< QRect >::iterator endIt, MergePolicy policy)
Definition KisRegion.cpp:52

References detail::mergeRects().

◆ operator&=()

KisRegion & KisRegion::operator&= ( const QRect & rect)

Definition at line 313 of file KisRegion.cpp.

314{
315 for (auto it = m_rects.begin(); it != m_rects.end(); /* noop */) {
316 *it &= rect;
317 if (it->isEmpty()) {
318 it = m_rects.erase(it);
319 } else {
320 ++it;
321 }
322 }
324 return *this;
325}

References m_rects, and mergeAllRects().

◆ operator=()

KisRegion & KisRegion::operator= ( const KisRegion & rhs)

Definition at line 307 of file KisRegion.cpp.

308{
309 m_rects = rhs.m_rects;
310 return *this;
311}

References m_rects.

◆ rectCount()

int KisRegion::rectCount ( ) const

Definition at line 337 of file KisRegion.cpp.

338{
339 return m_rects.size();
340}

References m_rects.

◆ rects()

QVector< QRect > KisRegion::rects ( ) const

Definition at line 332 of file KisRegion.cpp.

333{
334 return m_rects;
335}

References m_rects.

◆ toQRegion()

QRegion KisRegion::toQRegion ( ) const

Definition at line 347 of file KisRegion.cpp.

348{
349 // TODO: utilize QRegion::setRects to make creation of QRegion much
350 // faster. The only reason why we cannot use it "as is", is that our m_rects
351 // do not satisfy the second setRects()'s precondition: "All rectangles with
352 // a given top coordinate must have the same height". We can implement a
353 // simple algorithm for cropping m_rects, and it will be much faster than
354 // constructing QRegion iteratively.
355
356 return std::accumulate(m_rects.constBegin(), m_rects.constEnd(), QRegion(), std::bit_or<QRegion>());
357}

References m_rects.

◆ translate()

void KisRegion::translate ( int dx,
int dy )

Definition at line 359 of file KisRegion.cpp.

360{
361 std::transform(m_rects.begin(), m_rects.end(),
362 m_rects.begin(),
363 [dx, dy] (const QRect &rc) { return rc.translated(dx, dy); });
364}

References m_rects.

◆ translated()

KisRegion KisRegion::translated ( int x,
int y ) const

Definition at line 366 of file KisRegion.cpp.

367{
368 KisRegion region(*this);
369 region.translate(dx, dy);
370 return region;
371}

References translate().

Friends And Related Symbol Documentation

◆ operator==

KRITAGLOBAL_EXPORT bool operator== ( const KisRegion & lhs,
const KisRegion & rhs )
friend

Definition at line 398 of file KisRegion.cpp.

399{
400 return lhs.m_rects == rhs.m_rects;
401}

Member Data Documentation

◆ m_rects

QVector<QRect> KisRegion::m_rects
private

Definition at line 97 of file KisRegion.h.


The documentation for this class was generated from the following files: