summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qregion.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-02-27 12:40:36 +0100
committerMarc Mutz <marc.mutz@kdab.com>2016-02-28 19:06:44 +0000
commit77164e4cc05373de1147128058754d6511145afb (patch)
tree872ea60536608b0f67184d8b35d5aef455907ee1 /src/gui/painting/qregion.cpp
parent12705f70c9a380a5a4e8ba4027a835259aebb78f (diff)
QRegion: make iterable
Virtually all code in Qt that inspects a QRegion does so by calling rects(), which returns a QVector<QRect>. But rects() has a problem: A QRegion that contains just one rectangle internally is not represented by a QVector, and the mere act of calling rects() makes QRegion create one. So, expose the fact that QRegion is a container of QRects to users by providing iterators and begin()/end(), which can be nothrow, since for the one-rectangle case, instead of vectorize()ing the region, we just return pointers to (and one past) the 'extent' rectangle. As a consequence, the iterator type is just const QRect*, but I think that whatever containers QRegion may use under the hood in the future, it will be certainly one that is layout-compatible with a C array. No mutable iterators are provided, since QRegion maintains a running bounding-rect, so a mutable iterator would have to call into QRegion for every change, which doesn't make sense. [ChangeLog][QtGui][QRegion] Is now iterable as a container of QRects: added {c,}{r,}{begin,end}(). Change-Id: I2fa565fac0c1d26e2c0937604b23763cd4e23604 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/gui/painting/qregion.cpp')
-rw-r--r--src/gui/painting/qregion.cpp114
1 files changed, 112 insertions, 2 deletions
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 35c4abb3ac..ddeca291b5 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -81,8 +81,8 @@ QT_BEGIN_NAMESPACE
contains() a QPoint or QRect. The bounding rectangle can be found
with boundingRect().
- The function rects() gives a decomposition of the region into
- rectangles.
+ Iteration over the region (with begin(), end()) gives a decomposition of
+ the region into rectangles. The same sequence of rectangles is returned by rects().
Example of using complex regions:
\snippet code/src_gui_painting_qregion.cpp 0
@@ -928,6 +928,100 @@ QRegion QRegion::intersect(const QRect &r) const
*/
/*!
+ \typedef QRegion::const_iterator
+ \since 5.8
+
+ An iterator over the QRects that make up the region.
+
+ QRegion does not offer mutable iterators.
+
+ \sa begin(), end()
+*/
+
+/*!
+ \typedef QRegion::const_reverse_iterator
+ \since 5.8
+
+ A reverse iterator over the QRects that make up the region.
+
+ QRegion does not offer mutable iterators.
+
+ \sa rbegin(), rend()
+*/
+
+/*!
+ \fn QRegion::begin() const
+ \since 5.8
+
+ Returns a const_iterator pointing to the beginning of the range of
+ rectangles that make up this range, in the order in which rects()
+ returns them.
+
+ \sa rbegin(), cbegin(), end()
+*/
+
+/*!
+ \fn QRegion::cbegin() const
+ \since 5.8
+
+ Same as begin().
+*/
+
+/*!
+ \fn QRegion::end() const
+ \since 5.8
+
+ Returns a const_iterator pointing to one past the end of the range of
+ rectangles that make up this range, in the order in which rects()
+ returns them.
+
+ \sa rend(), cend(), begin()
+*/
+
+/*!
+ \fn QRegion::cend() const
+ \since 5.8
+
+ Same as end().
+*/
+
+/*!
+ \fn QRegion::rbegin() const
+ \since 5.8
+
+ Returns a const_reverse_iterator pointing to the beginning of the range of
+ rectangles that make up this range, in the reverse order in which rects()
+ returns them.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*!
+ \fn QRegion::crbegin() const
+ \since 5.8
+
+ Same as rbegin().
+*/
+
+/*!
+ \fn QRegion::rend() const
+ \since 5.8
+
+ Returns a const_reverse_iterator pointing to one past the end of the range of
+ rectangles that make up this range, in the reverse order in which rects()
+ returns them.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*!
+ \fn QRegion::crend() const
+ \since 5.8
+
+ Same as rend().
+*/
+
+/*!
\fn void QRegion::setRects(const QRect *rects, int number)
Sets the region using the array of rectangles specified by \a rects and
@@ -1171,6 +1265,12 @@ struct QRegionPrivate {
}
}
+ const QRect *begin() const Q_DECL_NOTHROW
+ { return numRects == 1 ? &extents : rects.data(); } // avoid vectorize()
+
+ const QRect *end() const Q_DECL_NOTHROW
+ { return begin() + numRects; }
+
inline void append(const QRect *r);
void append(const QRegionPrivate *r);
void prepend(const QRect *r);
@@ -4248,6 +4348,16 @@ QVector<QRect> QRegion::rects() const
}
}
+QRegion::const_iterator QRegion::begin() const Q_DECL_NOTHROW
+{
+ return d->qt_rgn ? d->qt_rgn->begin() : nullptr;
+}
+
+QRegion::const_iterator QRegion::end() const Q_DECL_NOTHROW
+{
+ return d->qt_rgn ? d->qt_rgn->end() : nullptr;
+}
+
void QRegion::setRects(const QRect *rects, int num)
{
*this = QRegion();