diff options
Diffstat (limited to 'src/kernel/qregion.cpp')
-rw-r--r-- | src/kernel/qregion.cpp | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/src/kernel/qregion.cpp b/src/kernel/qregion.cpp new file mode 100644 index 000000000..5720d1209 --- /dev/null +++ b/src/kernel/qregion.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Implementation of TQRegion class +** +** Created : 950726 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing retquirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at [email protected]. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qregion.h" +#include "qpointarray.h" +#include "qbuffer.h" +#include "qdatastream.h" + +// BEING REVISED: paul +/*! + \class TQRegion qregion.h + \brief The TQRegion class specifies a clip region for a painter. + + \ingroup images + \ingroup graphics + + TQRegion is used with TQPainter::setClipRegion() to limit the paint + area to what needs to be painted. There is also a + TQWidget::repaint() that takes a TQRegion parameter. TQRegion is the + best tool for reducing flicker. + + A region can be created from a rectangle, an ellipse, a polygon or + a bitmap. Complex regions may be created by combining simple + regions using unite(), intersect(), subtract() or eor() (exclusive + or). You can move a region using translate(). + + You can test whether a region isNull(), isEmpty() or if it + contains() a TQPoint or TQRect. The bounding rectangle is given by + boundingRect(). + + The function rects() gives a decomposition of the region into + rectangles. + + Example of using complex regions: + \code + void MyWidget::paintEvent( TQPaintEvent * ) + { + TQPainter p; // our painter + TQRegion r1( TQRect(100,100,200,80), // r1 = elliptic region + TQRegion::Ellipse ); + TQRegion r2( TQRect(100,120,90,30) ); // r2 = rectangular region + TQRegion r3 = r1.intersect( r2 ); // r3 = intersection + p.begin( this ); // start painting widget + p.setClipRegion( r3 ); // set clip region + ... // paint clipped graphics + p.end(); // painting done + } + \endcode + + TQRegion is an \link shclass.html implicitly shared\endlink class. + + \warning Due to window system limitations, the whole coordinate + space for a region is limited to the points between -32767 and + 32767 on Mac OS X and Windows 95/98/ME. + + \sa TQPainter::setClipRegion(), TQPainter::setClipRect() +*/ + + +/*! + \enum TQRegion::RegionType + + Specifies the shape of the region to be created. + + \value Rectangle the region covers the entire rectangle. + \value Ellipse the region is an ellipse inside the rectangle. +*/ + +/*! + \fn Region TQRegion::handle() const + + Returns the region's handle. +*/ + +/***************************************************************************** + TQRegion member functions + *****************************************************************************/ + +/*! + Constructs a rectangular or elliptic region. + + If \a t is \c Rectangle, the region is the filled rectangle (\a x, + \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled + ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size + (\a w ,\a h ). +*/ +TQRegion::TQRegion( int x, int y, int w, int h, RegionType t ) +{ + TQRegion tmp(TQRect(x,y,w,h),t); + tmp.data->ref(); + data = tmp.data; +} + +/*! + Detaches from shared region data to make sure that this region is + the only one referring to the data. + + \sa copy(), \link shclass.html shared classes\endlink +*/ + +void TQRegion::detach() +{ + if ( data->count != 1 ) + *this = copy(); +} + +#ifndef QT_NO_DATASTREAM +/* + Executes region commands in the internal buffer and rebuilds the + original region. + + We do this when we read a region from the data stream. + + If \a ver is non-0, uses the format version \a ver on reading the + byte array. +*/ + +void TQRegion::exec( const TQByteArray &buffer, int ver ) +{ + TQBuffer buf( buffer ); + TQDataStream s( &buf ); + if ( ver ) + s.setVersion( ver ); + buf.open( IO_ReadOnly ); + TQRegion rgn; +#if defined(QT_CHECK_STATE) + int test_cnt = 0; +#endif + while ( !s.eof() ) { + Q_INT32 id; + if ( s.version() == 1 ) { + int id_int; + s >> id_int; + id = id_int; + } else { + s >> id; + } +#if defined(QT_CHECK_STATE) + if ( test_cnt > 0 && id != TQRGN_TRANSLATE ) + qWarning( "TQRegion::exec: Internal error" ); + test_cnt++; +#endif + if ( id == TQRGN_SETRECT || id == TQRGN_SETELLIPSE ) { + TQRect r; + s >> r; + rgn = TQRegion( r, id == TQRGN_SETRECT ? Rectangle : Ellipse ); + } else if ( id == TQRGN_SETPTARRAY_ALT || id == TQRGN_SETPTARRAY_WIND ) { + TQPointArray a; + s >> a; + rgn = TQRegion( a, id == TQRGN_SETPTARRAY_WIND ); + } else if ( id == TQRGN_TRANSLATE ) { + TQPoint p; + s >> p; + rgn.translate( p.x(), p.y() ); + } else if ( id >= TQRGN_OR && id <= TQRGN_XOR ) { + TQByteArray bop1, bop2; + TQRegion r1, r2; + s >> bop1; r1.exec( bop1 ); + s >> bop2; r2.exec( bop2 ); + switch ( id ) { + case TQRGN_OR: + rgn = r1.unite( r2 ); + break; + case TQRGN_AND: + rgn = r1.intersect( r2 ); + break; + case TQRGN_SUB: + rgn = r1.subtract( r2 ); + break; + case TQRGN_XOR: + rgn = r1.eor( r2 ); + break; + } + } else if ( id == TQRGN_RECTS ) { + // (This is the only form used in TQt 2.0) + Q_UINT32 n; + s >> n; + TQRect r; + for ( int i=0; i<(int)n; i++ ) { + s >> r; + rgn = rgn.unite( TQRegion(r) ); + } + } + } + buf.close(); + *this = rgn; +} + + +/***************************************************************************** + TQRegion stream functions + *****************************************************************************/ + +/*! + \relates TQRegion + + Writes the region \a r to the stream \a s and returns a reference + to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQRegion &r ) +{ + TQMemArray<TQRect> a = r.rects(); + if ( a.isEmpty() ) { + s << (Q_UINT32)0; + } else { + if ( s.version() == 1 ) { + int i; + for ( i=(int)a.size()-1; i>0; i-- ) { + s << (Q_UINT32)(12+i*24); + s << (int)TQRGN_OR; + } + for ( i=0; i<(int)a.size(); i++ ) { + s << (Q_UINT32)(4+8) << (int)TQRGN_SETRECT << a[i]; + } + } + else { + s << (Q_UINT32)(4+4+16*a.size()); // 16: storage size of TQRect + s << (Q_INT32)TQRGN_RECTS; + s << (Q_UINT32)a.size(); + for ( int i=0; i<(int)a.size(); i++ ) + s << a[i]; + } + } + return s; +} + +/*! + \relates TQRegion + + Reads a region from the stream \a s into \a r and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQRegion &r ) +{ + TQByteArray b; + s >> b; + r.exec( b, s.version() ); + return s; +} +#endif //QT_NO_DATASTREAM + +// These are not inline - they can be implemented better on some platforms +// (eg. Windows at least provides 3-variable operations). For now, simple. + + +/*! + Applies the unite() function to this region and \a r. \c r1|r2 is + equivalent to \c r1.unite(r2) + + \sa unite(), operator+() +*/ +const TQRegion TQRegion::operator|( const TQRegion &r ) const + { return unite(r); } + +/*! + Applies the unite() function to this region and \a r. \c r1+r2 is + equivalent to \c r1.unite(r2) + + \sa unite(), operator|() +*/ +const TQRegion TQRegion::operator+( const TQRegion &r ) const + { return unite(r); } + +/*! + Applies the intersect() function to this region and \a r. \c r1&r2 + is equivalent to \c r1.intersect(r2) + + \sa intersect() +*/ +const TQRegion TQRegion::operator&( const TQRegion &r ) const + { return intersect(r); } + +/*! + Applies the subtract() function to this region and \a r. \c r1-r2 + is equivalent to \c r1.subtract(r2) + + \sa subtract() +*/ +const TQRegion TQRegion::operator-( const TQRegion &r ) const + { return subtract(r); } + +/*! + Applies the eor() function to this region and \a r. \c r1^r2 is + equivalent to \c r1.eor(r2) + + \sa eor() +*/ +const TQRegion TQRegion::operator^( const TQRegion &r ) const + { return eor(r); } + +/*! + Applies the unite() function to this region and \a r and assigns + the result to this region. \c r1|=r2 is equivalent to \c + r1=r1.unite(r2) + + \sa unite() +*/ +TQRegion& TQRegion::operator|=( const TQRegion &r ) + { return *this = *this | r; } + +/*! + Applies the unite() function to this region and \a r and assigns + the result to this region. \c r1+=r2 is equivalent to \c + r1=r1.unite(r2) + + \sa intersect() +*/ +TQRegion& TQRegion::operator+=( const TQRegion &r ) + { return *this = *this + r; } + +/*! + Applies the intersect() function to this region and \a r and + assigns the result to this region. \c r1&=r2 is equivalent to \c + r1=r1.intersect(r2) + + \sa intersect() +*/ +TQRegion& TQRegion::operator&=( const TQRegion &r ) + { return *this = *this & r; } + +/*! + Applies the subtract() function to this region and \a r and + assigns the result to this region. \c r1-=r2 is equivalent to \c + r1=r1.subtract(r2) + + \sa subtract() +*/ +TQRegion& TQRegion::operator-=( const TQRegion &r ) + { return *this = *this - r; } + +/*! + Applies the eor() function to this region and \a r and + assigns the result to this region. \c r1^=r2 is equivalent to \c + r1=r1.eor(r2) + + \sa eor() +*/ +TQRegion& TQRegion::operator^=( const TQRegion &r ) + { return *this = *this ^ r; } + |