1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the painting module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
32
#include "qdatastream.h"
39
\brief The QRegion class specifies a clip region for a painter.
43
QRegion is used with QPainter::setClipRegion() to limit the paint
44
area to what needs to be painted. There is also a
45
QWidget::repaint() function that takes a QRegion parameter.
46
QRegion is the best tool for reducing flicker.
48
A region can be created from a rectangle, an ellipse, a polygon or
49
a bitmap. Complex regions may be created by combining simple
50
regions using unite(), intersect(), subtract(), or eor() (exclusive
51
or). You can move a region using translate().
53
You can test whether a region isEmpty() or if it
54
contains() a QPoint or QRect. The bounding rectangle can be found
57
The function rects() gives a decomposition of the region into
60
Example of using complex regions:
62
void MyWidget::paintEvent(QPaintEvent *)
64
QPainter p; // our painter
65
QRegion r1(QRect(100,100,200,80), // r1 = elliptic region
67
QRegion r2(QRect(100,120,90,30)); // r2 = rectangular region
68
QRegion r3 = r1.intersect(r2); // r3 = intersection
69
p.begin(this); // start painting widget
70
p.setClipRegion(r3); // set clip region
71
... // paint clipped graphics
72
p.end(); // painting done
76
QRegion is an \link shclass.html implicitly shared\endlink class.
78
\warning Due to window system limitations, the whole coordinate space for a
79
region is limited to the points between -32767 and 32767 on Windows
80
95/98/ME. You can circumvent this limitation by using a QPainterPath.
82
\sa QPainter::setClipRegion(), QPainter::setClipRect()
89
\enum QRegion::RegionType
91
Specifies the shape of the region to be created.
93
\value Rectangle the region covers the entire rectangle.
94
\value Ellipse the region is an ellipse inside the rectangle.
98
\fn void QRegion::translate(const QPoint &point)
102
Translates to the given \a point.
106
\fn Handle QRegion::handle() const
108
Returns a platform-specific region handle. The \c Handle type is
109
\c HRGN on Windows, \c Region on X11, and \c RgnHandle on Mac OS
112
\warning This function is not portable.
115
/*****************************************************************************
116
QRegion member functions
117
*****************************************************************************/
120
Constructs a rectangular or elliptic region.
122
If \a t is \c Rectangle, the region is the filled rectangle (\a x,
123
\a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled
124
ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size
127
QRegion::QRegion(int x, int y, int w, int h, RegionType t)
129
QRegion tmp(QRect(x, y, w, h), t);
136
Use the constructor tha takes a Qt::FillRule as the second
139
QRegion::QRegion(const QPolygon &pa, bool winding)
141
new (this) QRegion(pa, winding ? Qt::WindingFill : Qt::OddEvenFill);
146
Detaches from shared region data to make sure that this region is
147
the only one referring to the data.
149
\sa copy(), \link shclass.html shared classes\endlink
152
void QRegion::detach()
158
// duplicates in qregion_win.cpp and qregion_wce.cpp
159
#define QRGN_SETRECT 1 // region stream commands
160
#define QRGN_SETELLIPSE 2 // (these are internal)
161
#define QRGN_SETPTARRAY_ALT 3
162
#define QRGN_SETPTARRAY_WIND 4
163
#define QRGN_TRANSLATE 5
168
#define QRGN_RECTS 10
171
#ifndef QT_NO_DATASTREAM
173
Executes region commands in the internal buffer and rebuilds the
176
We do this when we read a region from the data stream.
178
If \a ver is non-0, uses the format version \a ver on reading the
182
void QRegion::exec(const QByteArray &buffer, int ver)
184
QByteArray copy = buffer;
185
QDataStream s(©, QIODevice::ReadOnly);
194
if (s.version() == 1) {
202
if (test_cnt > 0 && id != QRGN_TRANSLATE)
203
qWarning("QRegion::exec: Internal error");
206
if (id == QRGN_SETRECT || id == QRGN_SETELLIPSE) {
209
rgn = QRegion(r, id == QRGN_SETRECT ? Rectangle : Ellipse);
210
} else if (id == QRGN_SETPTARRAY_ALT || id == QRGN_SETPTARRAY_WIND) {
213
rgn = QRegion(a, id == QRGN_SETPTARRAY_WIND ? Qt::WindingFill : Qt::OddEvenFill);
214
} else if (id == QRGN_TRANSLATE) {
217
rgn.translate(p.x(), p.y());
218
} else if (id >= QRGN_OR && id <= QRGN_XOR) {
219
QByteArray bop1, bop2;
231
rgn = r1.intersect(r2);
234
rgn = r1.subtract(r2);
240
} else if (id == QRGN_RECTS) {
241
// (This is the only form used in Qt 2.0)
245
for (int i=0; i<(int)n; i++) {
247
rgn = rgn.unite(QRegion(r));
255
/*****************************************************************************
256
QRegion stream functions
257
*****************************************************************************/
262
Writes the region \a r to the stream \a s and returns a reference
265
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
268
QDataStream &operator<<(QDataStream &s, const QRegion &r)
270
QVector<QRect> a = r.rects();
274
if (s.version() == 1) {
276
for (i = a.size() - 1; i > 0; --i) {
277
s << (quint32)(12 + i * 24);
280
for (i = 0; i < a.size(); ++i) {
281
s << (quint32)(4+8) << (int)QRGN_SETRECT << a[i];
284
s << (quint32)(4 + 4 + 16 * a.size()); // 16: storage size of QRect
285
s << (qint32)QRGN_RECTS;
295
Reads a region from the stream \a s into \a r and returns a
296
reference to the stream.
298
\sa \link datastreamformat.html Format of the QDataStream operators \endlink
301
QDataStream &operator>>(QDataStream &s, QRegion &r)
305
r.exec(b, s.version());
308
#endif //QT_NO_DATASTREAM
310
#ifndef QT_NO_DEBUG_STREAM
311
QDebug operator<<(QDebug s, const QRegion &r)
313
QVector<QRect> rects = r.rects();
314
s.nospace() << "QRegion(size=" << rects.size() << "), "
315
<< "bounds = " << r.boundingRect() << "\n";
316
for (int i=0; i<rects.size(); ++i)
317
s << "- " << i << rects.at(i) << "\n";
323
// These are not inline - they can be implemented better on some platforms
324
// (eg. Windows at least provides 3-variable operations). For now, simple.
328
Applies the unite() function to this region and \a r. \c r1|r2 is
329
equivalent to \c r1.unite(r2)
331
\sa unite(), operator+()
333
const QRegion QRegion::operator|(const QRegion &r) const
337
Applies the unite() function to this region and \a r. \c r1+r2 is
338
equivalent to \c r1.unite(r2)
340
\sa unite(), operator|()
342
const QRegion QRegion::operator+(const QRegion &r) const
346
Applies the intersect() function to this region and \a r. \c r1&r2
347
is equivalent to \c r1.intersect(r2)
351
const QRegion QRegion::operator&(const QRegion &r) const
352
{ return intersect(r); }
355
Applies the subtract() function to this region and \a r. \c r1-r2
356
is equivalent to \c r1.subtract(r2)
360
const QRegion QRegion::operator-(const QRegion &r) const
361
{ return subtract(r); }
364
Applies the eor() function to this region and \a r. \c r1^r2 is
365
equivalent to \c r1.eor(r2)
369
const QRegion QRegion::operator^(const QRegion &r) const
373
Applies the unite() function to this region and \a r and assigns
374
the result to this region. \c r1|=r2 is equivalent to \c
379
QRegion& QRegion::operator|=(const QRegion &r)
380
{ return *this = *this | r; }
383
Applies the unite() function to this region and \a r and assigns
384
the result to this region. \c r1+=r2 is equivalent to \c
389
QRegion& QRegion::operator+=(const QRegion &r)
390
{ return *this = *this + r; }
393
Applies the intersect() function to this region and \a r and
394
assigns the result to this region. \c r1&=r2 is equivalent to \c
399
QRegion& QRegion::operator&=(const QRegion &r)
400
{ return *this = *this & r; }
403
Applies the subtract() function to this region and \a r and
404
assigns the result to this region. \c r1-=r2 is equivalent to \c
409
QRegion& QRegion::operator-=(const QRegion &r)
410
{ return *this = *this - r; }
413
Applies the eor() function to this region and \a r and
414
assigns the result to this region. \c r1^=r2 is equivalent to \c
419
QRegion& QRegion::operator^=(const QRegion &r)
420
{ return *this = *this ^ r; }
423
\fn bool QRegion::operator!=(const QRegion &other) const
425
Returns true if this region is different from the \a other region;
426
otherwise returns false.
430
Returns the region as a QVariant
432
QRegion::operator QVariant() const
434
return QVariant(QVariant::Region, this);
438
\fn bool QRegion::isNull() const
440
Use isEmpty() instead.