source: vendor/trolltech/current/src/kernel/qregion.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1/****************************************************************************
2** $Id: qregion.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QRegion class
5**
6** Created : 950726
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qregion.h"
39#include "qpointarray.h"
40#include "qbuffer.h"
41#include "qdatastream.h"
42
43// BEING REVISED: paul
44/*!
45 \class QRegion qregion.h
46 \brief The QRegion class specifies a clip region for a painter.
47
48 \ingroup images
49 \ingroup graphics
50
51 QRegion is used with QPainter::setClipRegion() to limit the paint
52 area to what needs to be painted. There is also a
53 QWidget::repaint() that takes a QRegion parameter. QRegion is the
54 best tool for reducing flicker.
55
56 A region can be created from a rectangle, an ellipse, a polygon or
57 a bitmap. Complex regions may be created by combining simple
58 regions using unite(), intersect(), subtract() or eor() (exclusive
59 or). You can move a region using translate().
60
61 You can test whether a region isNull(), isEmpty() or if it
62 contains() a QPoint or QRect. The bounding rectangle is given by
63 boundingRect().
64
65 The function rects() gives a decomposition of the region into
66 rectangles.
67
68 Example of using complex regions:
69 \code
70 void MyWidget::paintEvent( QPaintEvent * )
71 {
72 QPainter p; // our painter
73 QRegion r1( QRect(100,100,200,80), // r1 = elliptic region
74 QRegion::Ellipse );
75 QRegion r2( QRect(100,120,90,30) ); // r2 = rectangular region
76 QRegion r3 = r1.intersect( r2 ); // r3 = intersection
77 p.begin( this ); // start painting widget
78 p.setClipRegion( r3 ); // set clip region
79 ... // paint clipped graphics
80 p.end(); // painting done
81 }
82 \endcode
83
84 QRegion is an \link shclass.html implicitly shared\endlink class.
85
86 \warning Due to window system limitations, the whole coordinate
87 space for a region is limited to the points between -32767 and
88 32767 on Windows 95/98/ME.
89
90 \sa QPainter::setClipRegion(), QPainter::setClipRect()
91*/
92
93
94/*!
95 \enum QRegion::RegionType
96
97 Specifies the shape of the region to be created.
98
99 \value Rectangle the region covers the entire rectangle.
100 \value Ellipse the region is an ellipse inside the rectangle.
101*/
102
103/*!
104 \fn Region QRegion::handle() const
105
106 Returns the region's handle.
107*/
108
109/*****************************************************************************
110 QRegion member functions
111 *****************************************************************************/
112
113/*!
114 Constructs a rectangular or elliptic region.
115
116 If \a t is \c Rectangle, the region is the filled rectangle (\a x,
117 \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled
118 ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size
119 (\a w ,\a h ).
120*/
121QRegion::QRegion( int x, int y, int w, int h, RegionType t )
122{
123 QRegion tmp(QRect(x,y,w,h),t);
124 tmp.data->ref();
125 data = tmp.data;
126}
127
128/*!
129 Detaches from shared region data to make sure that this region is
130 the only one referring to the data.
131
132 \sa copy(), \link shclass.html shared classes\endlink
133*/
134
135void QRegion::detach()
136{
137 if ( data->count != 1 )
138 *this = copy();
139}
140
141#ifndef QT_NO_DATASTREAM
142/*
143 Executes region commands in the internal buffer and rebuilds the
144 original region.
145
146 We do this when we read a region from the data stream.
147
148 If \a ver is non-0, uses the format version \a ver on reading the
149 byte array.
150*/
151
152void QRegion::exec( const QByteArray &buffer, int ver )
153{
154 QBuffer buf( buffer );
155 QDataStream s( &buf );
156 if ( ver )
157 s.setVersion( ver );
158 buf.open( IO_ReadOnly );
159 QRegion rgn;
160#if defined(QT_CHECK_STATE)
161 int test_cnt = 0;
162#endif
163 while ( !s.eof() ) {
164 Q_INT32 id;
165 if ( s.version() == 1 ) {
166 int id_int;
167 s >> id_int;
168 id = id_int;
169 } else {
170 s >> id;
171 }
172#if defined(QT_CHECK_STATE)
173 if ( test_cnt > 0 && id != QRGN_TRANSLATE )
174 qWarning( "QRegion::exec: Internal error" );
175 test_cnt++;
176#endif
177 if ( id == QRGN_SETRECT || id == QRGN_SETELLIPSE ) {
178 QRect r;
179 s >> r;
180 rgn = QRegion( r, id == QRGN_SETRECT ? Rectangle : Ellipse );
181 } else if ( id == QRGN_SETPTARRAY_ALT || id == QRGN_SETPTARRAY_WIND ) {
182 QPointArray a;
183 s >> a;
184 rgn = QRegion( a, id == QRGN_SETPTARRAY_WIND );
185 } else if ( id == QRGN_TRANSLATE ) {
186 QPoint p;
187 s >> p;
188 rgn.translate( p.x(), p.y() );
189 } else if ( id >= QRGN_OR && id <= QRGN_XOR ) {
190 QByteArray bop1, bop2;
191 QRegion r1, r2;
192 s >> bop1; r1.exec( bop1 );
193 s >> bop2; r2.exec( bop2 );
194 switch ( id ) {
195 case QRGN_OR:
196 rgn = r1.unite( r2 );
197 break;
198 case QRGN_AND:
199 rgn = r1.intersect( r2 );
200 break;
201 case QRGN_SUB:
202 rgn = r1.subtract( r2 );
203 break;
204 case QRGN_XOR:
205 rgn = r1.eor( r2 );
206 break;
207 }
208 } else if ( id == QRGN_RECTS ) {
209 // (This is the only form used in Qt 2.0)
210 Q_UINT32 n;
211 s >> n;
212 QRect r;
213 for ( int i=0; i<(int)n; i++ ) {
214 s >> r;
215 rgn = rgn.unite( QRegion(r) );
216 }
217 }
218 }
219 buf.close();
220 *this = rgn;
221}
222
223
224/*****************************************************************************
225 QRegion stream functions
226 *****************************************************************************/
227
228/*!
229 \relates QRegion
230
231 Writes the region \a r to the stream \a s and returns a reference
232 to the stream.
233
234 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
235*/
236
237QDataStream &operator<<( QDataStream &s, const QRegion &r )
238{
239 QMemArray<QRect> a = r.rects();
240 if ( a.isEmpty() ) {
241 s << (Q_UINT32)0;
242 } else {
243 if ( s.version() == 1 ) {
244 int i;
245 for ( i=(int)a.size()-1; i>0; i-- ) {
246 s << (Q_UINT32)(12+i*24);
247 s << (int)QRGN_OR;
248 }
249 for ( i=0; i<(int)a.size(); i++ ) {
250 s << (Q_UINT32)(4+8) << (int)QRGN_SETRECT << a[i];
251 }
252 }
253 else {
254 s << (Q_UINT32)(4+4+16*a.size()); // 16: storage size of QRect
255 s << (Q_INT32)QRGN_RECTS;
256 s << (Q_UINT32)a.size();
257 for ( int i=0; i<(int)a.size(); i++ )
258 s << a[i];
259 }
260 }
261 return s;
262}
263
264/*!
265 \relates QRegion
266
267 Reads a region from the stream \a s into \a r and returns a
268 reference to the stream.
269
270 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
271*/
272
273QDataStream &operator>>( QDataStream &s, QRegion &r )
274{
275 QByteArray b;
276 s >> b;
277 r.exec( b, s.version() );
278 return s;
279}
280#endif //QT_NO_DATASTREAM
281
282// These are not inline - they can be implemented better on some platforms
283// (eg. Windows at least provides 3-variable operations). For now, simple.
284
285
286/*!
287 Applies the unite() function to this region and \a r. \c r1|r2 is
288 equivalent to \c r1.unite(r2)
289
290 \sa unite(), operator+()
291*/
292const QRegion QRegion::operator|( const QRegion &r ) const
293 { return unite(r); }
294
295/*!
296 Applies the unite() function to this region and \a r. \c r1+r2 is
297 equivalent to \c r1.unite(r2)
298
299 \sa unite(), operator|()
300*/
301const QRegion QRegion::operator+( const QRegion &r ) const
302 { return unite(r); }
303
304/*!
305 Applies the intersect() function to this region and \a r. \c r1&r2
306 is equivalent to \c r1.intersect(r2)
307
308 \sa intersect()
309*/
310const QRegion QRegion::operator&( const QRegion &r ) const
311 { return intersect(r); }
312
313/*!
314 Applies the subtract() function to this region and \a r. \c r1-r2
315 is equivalent to \c r1.subtract(r2)
316
317 \sa subtract()
318*/
319const QRegion QRegion::operator-( const QRegion &r ) const
320 { return subtract(r); }
321
322/*!
323 Applies the eor() function to this region and \a r. \c r1^r2 is
324 equivalent to \c r1.eor(r2)
325
326 \sa eor()
327*/
328const QRegion QRegion::operator^( const QRegion &r ) const
329 { return eor(r); }
330
331/*!
332 Applies the unite() function to this region and \a r and assigns
333 the result to this region. \c r1|=r2 is equivalent to \c
334 r1=r1.unite(r2)
335
336 \sa unite()
337*/
338QRegion& QRegion::operator|=( const QRegion &r )
339 { return *this = *this | r; }
340
341/*!
342 Applies the unite() function to this region and \a r and assigns
343 the result to this region. \c r1+=r2 is equivalent to \c
344 r1=r1.unite(r2)
345
346 \sa intersect()
347*/
348QRegion& QRegion::operator+=( const QRegion &r )
349 { return *this = *this + r; }
350
351/*!
352 Applies the intersect() function to this region and \a r and
353 assigns the result to this region. \c r1&=r2 is equivalent to \c
354 r1=r1.intersect(r2)
355
356 \sa intersect()
357*/
358QRegion& QRegion::operator&=( const QRegion &r )
359 { return *this = *this & r; }
360
361/*!
362 Applies the subtract() function to this region and \a r and
363 assigns the result to this region. \c r1-=r2 is equivalent to \c
364 r1=r1.subtract(r2)
365
366 \sa subtract()
367*/
368QRegion& QRegion::operator-=( const QRegion &r )
369 { return *this = *this - r; }
370
371/*!
372 Applies the eor() function to this region and \a r and
373 assigns the result to this region. \c r1^=r2 is equivalent to \c
374 r1=r1.eor(r2)
375
376 \sa eor()
377*/
378QRegion& QRegion::operator^=( const QRegion &r )
379 { return *this = *this ^ r; }
380
Note: See TracBrowser for help on using the repository browser.