📄 qpointarray.cpp
字号:
/****************************************************************************** $Id: qt/src/3rdparty/kernel/qpointarray.cpp 2.3.10 edited 2005-01-24 $**** Implementation of QPointArray class**** Created : 940213**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the kernel module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qpointarray.h"#include "qrect.h"#include "qbitarray.h"#include "qdatastream.h"#include "qwmatrix.h"#include <stdarg.h>const double Q_PI = 3.14159265358979323846; // pi // one more useful comment/*! \class QPointArray qpointarray.h \brief The QPointArray class provides an array of points. The QPointArray is an array of QPoint objects. In addition to the functions provided by QArray, QPointArray provides some point-specific functions. For convenient reading and writing of the point data: setPoints(), putPoints(), point(), and setPoint(). For geometry operations: boundingRect() and translate(). There is also a QWMatrix::map() function for more general transformation of QPointArrays. QPointArray is used by QPainter::drawLineSegments(), QPainter::drawPolyline(), QPainter::drawPolygon() and QPainter::drawQuadBezier(), among other things. Note that since this class is a QArray, it is explicitly shared and works with shallow copies by default. \mustquote Transformations used in QPointArray are based on parelarc.c from Graphics Gems III VanAken / Simar, "A Parametric Elliptical Arc Algorithm" \sa QPainter QWMatrix QArray*//***************************************************************************** QPointArray member functions *****************************************************************************//*! \fn QPointArray::QPointArray() Constructs a null point array. \sa isNull()*//*! \fn QPointArray::QPointArray( int size ) Constructs a point array with room for \a size points. Makes a null array if \a size == 0. \sa resize(), isNull()*//*! \fn QPointArray::QPointArray( const QPointArray &a ) Constructs a shallow copy of the point array \a a. \sa copy()*//*! Constructs a point array from the rectangle \a r. If \a closed is FALSE, then the point array just contains the following four points in the listed order: r.topLeft(), r.topRight(), r.bottomRight() and r.bottomLeft(). If \a closed is TRUE, then a fifth point is set to r.topLeft().*/QPointArray::QPointArray( const QRect &r, bool closed ){ setPoints( 4, r.left(), r.top(), r.right(), r.top(), r.right(), r.bottom(), r.left(), r.bottom() ); if ( closed ) { resize( 5 ); setPoint( 4, r.left(), r.top() ); }}/*! Constructs a point array with \a nPoints points, taken from the \a points array. Equivalent to setPoints(nPoints,points).*/QPointArray::QPointArray( int nPoints, const QCOORD *points ){ setPoints( nPoints, points );}/*! \fn QPointArray::~QPointArray() Destructs the point array.*//*! \fn QPointArray &QPointArray::operator=( const QPointArray &a ) Assigns a shallow copy of \a a to this point array and returns a reference to this point array. Equivalent to assign( a ). \sa copy()*//*! \fn QPointArray QPointArray::copy() const Creates a deep copy of the array.*//*! Translates all points in the array \a (dx,dy).*/void QPointArray::translate( int dx, int dy ){ register QPoint *p = data(); register int i = size(); QPoint pt( dx, dy ); while ( i-- ) { *p += pt; p++; }}/*! Returns the point at position \a index in the array in \a *x and \a *y.*/void QPointArray::point( uint index, int *x, int *y ) const{ QPoint p = QArray<QPoint>::at( index ); *x = (int)p.x(); *y = (int)p.y();}/*! Returns the point at position \a index in the array.*/QPoint QPointArray::point( uint index ) const{ return QArray<QPoint>::at( index );}/*! Sets the point at position \a index in the array to \a (x,y).*/void QPointArray::setPoint( uint index, int x, int y ){ QArray<QPoint>::at( index ) = QPoint( x, y );}/*! Resizes the array to \a nPoints and sets the points in the array to the values taken from \a points. Returns TRUE if successful, or FALSE if the array could not be resized (normally due to lack of memory). The example code creates an array with two points (1,2) and (3,4): \code static QCOORD points[] = { 1,2, 3,4 }; QPointArray a; a.setPoints( 2, points ); \endcode \sa resize(), putPoints()*/bool QPointArray::setPoints( int nPoints, const QCOORD *points ){ if ( !resize(nPoints) ) return FALSE; int i = 0; while ( nPoints-- ) { // make array of points setPoint( i++, *points, *(points+1) ); points++; points++; } return TRUE;}/*! \fn void QPointArray::setPoint( uint i, const QPoint &p ) Equivalent to setPoint( i, p.x(), p.y() ).*//*! Resizes the array to \a nPoints and sets the points in the array to the values taken from the variable argument list. Returns TRUE if successful, or FALSE if the array could not be resized (typically due to lack of memory). The example code creates an array with two points (1,2) and (3,4): \code QPointArray a; a.setPoints( 2, 1,2, 3,4 ); \endcode \sa resize(), putPoints()*/bool QPointArray::setPoints( int nPoints, int firstx, int firsty, ... ){ va_list ap; if ( !resize(nPoints) ) return FALSE; setPoint( 0, firstx, firsty ); // set first point int i = 1, x, y; nPoints--; va_start( ap, firsty ); while ( nPoints-- ) { x = va_arg( ap, int ); y = va_arg( ap, int ); setPoint( i++, x, y ); } va_end( ap ); return TRUE;}/*! Copies \a nPoints points from the \a points array into this point array. Will resize this point array if <code>index+nPoints</code> exceeds the size of the array. Returns TRUE if successful, or FALSE if the array could not be resized (typcailly due to lack of memory). The example code creates an array with three points: (1,2), (3,4) and (5,6): \code QPointArray a( 1 ); a[0] = QPoint( 1, 2 ); static QCOORD points[] = { 3,4, 5,6 }; a.putPoints( 1, 2, points ); \endcode This function differs from setPoints() in that it does not resize the array unless the array size is exceeded. \sa resize(), setPoints()*/bool QPointArray::putPoints( int index, int nPoints, const QCOORD *points ){ if ( index + nPoints > (int)size() ) { // extend array if ( !resize( index + nPoints ) ) return FALSE; } int i = index; while ( nPoints-- ) { // make array of points setPoint( i++, *points, *(points+1) ); points++; points++; } return TRUE;}/*! Copies \a nPoints points from the variable argument list into this point array. Will resize this point array if <code>index+nPoints</code> exceeds the size of the array. Returns TRUE if successful, or FALSE if the array could not be resized (typically due to lack of memory). The example code creates an array with two points (1,2), (3,4) and (5,6): \code QPointArray a( 1 ); a[0] = QPoint( 1, 2 ); a.putPoints( 1, 2, 3,4, 5,6 ); \endcode This function differs from setPoints() in that it does not resize the array unless the array size is exceeded. \sa resize(), setPoints()*/bool QPointArray::putPoints( int index, int nPoints, int firstx, int firsty, ... ){ va_list ap; if ( index + nPoints > (int)size() ) { // extend array if ( !resize(index + nPoints) ) return FALSE; } if ( nPoints <= 0 ) return TRUE; setPoint( index, firstx, firsty ); // set first point int i = index + 1, x, y; nPoints--; va_start( ap, firsty ); while ( nPoints-- ) { x = va_arg( ap, int ); y = va_arg( ap, int ); setPoint( i++, x, y ); } va_end( ap ); return TRUE;}/*! Returns the bounding rectangle of the points in the array, or QRect(0,0,0,0) if the array is empty.*/QRect QPointArray::boundingRect() const{ if ( isEmpty() ) return QRect( 0, 0, 0, 0 ); // null rectangle register QPoint *pd = data(); int minx, maxx, miny, maxy; minx = maxx = pd->x(); miny = maxy = pd->y(); pd++; for ( int i=1; i<(int)size(); i++ ) { // find min+max x and y if ( pd->x() < minx ) minx = pd->x(); else if ( pd->x() > maxx ) maxx = pd->x(); if ( pd->y() < miny ) miny = pd->y(); else if ( pd->y() > maxy ) maxy = pd->y(); pd++; } return QRect( QPoint(minx,miny), QPoint(maxx,maxy) );}static inline int fix_angle( int a ){ if ( a > 16*360 ) a %= 16*360; else if ( a < -16*360 ) { a = -( (-a) % (16*360) ); } return a;}/*! Sets the points of the array to those describing an arc of an ellipse with size \a w by \a h and position (\a x, \a y ), starting from angle \a a1, spanning \a a2. The resulting array has sufficient resolution for pixel accuracy (see the overloaded function which takes an additional QWMatrix parameter). Angles are specified in 16ths of a degree, i.e. a full circle equals 5760 (16*360). Positive values mean counter-clockwise while negative values mean clockwise direction. Zero degrees is at the 3 o'clock position.*/void QPointArray::makeArc( int x, int y, int w, int h, int a1, int a2 ){#if !defined(QT_OLD_MAKEELLIPSE) && !defined(QT_NO_TRANSFORMATIONS) QWMatrix unit; makeArc(x,y,w,h,a1,a2,unit);#else a1 = fix_angle( a1 ); if ( a1 < 0 ) a1 += 16*360; a2 = fix_angle( a2 ); int a3 = a2 > 0 ? a2 : -a2; // abs angle makeEllipse( x, y, w, h ); int npts = a3*size()/(16*360); // # points in arc array QPointArray a(npts); int i = a1*size()/(16*360); int j = 0; if ( a2 > 0 ) { while ( npts-- ) { if ( i >= (int)size() ) // wrap index i = 0; a.QArray<QPoint>::at( j++ ) = QArray<QPoint>::at( i++ ); } } else { while ( npts-- ) { if ( i < 0 ) // wrap index i = (int)size()-1; a.QArray<QPoint>::at( j++ ) = QArray<QPoint>::at( i-- ); } } *this = a; return;#endif}#ifndef QT_NO_TRANSFORMATIONS// Based upon:// parelarc.c from Graphics Gems III// VanAken / Simar, "A Parametric Elliptical Arc Algorithm"//static voidqtr_elips(QPointArray& a, int off, double dxP, double dyP, double dxQ, double dyQ, double dxK, double dyK, int m){#define PIV2 102944 /* fixed point PI/2 */#define TWOPI 411775 /* fixed point 2*PI */#define HALF 32768 /* fixed point 1/2 */ int xP, yP, xQ, yQ, xK, yK; xP = int(dxP * 65536.0); yP = int(dyP * 65536.0); xQ = int(dxQ * 65536.0); yQ = int(dyQ * 65536.0); xK = int(dxK * 65536.0); yK = int(dyK * 65536.0); int i; int vx, ux, vy, uy, xJ, yJ; vx = xK - xQ; /* displacements from center */ ux = xK - xP; vy = yK - yQ; uy = yK - yP; xJ = xP - vx + HALF; /* center of ellipse J */ yJ = yP - vy + HALF; int r; ux -= (r = ux >> (2*m + 3)); /* cancel 2nd-order error */ ux -= (r >>= (2*m + 4)); /* cancel 4th-order error */ ux -= r >> (2*m + 3); /* cancel 6th-order error */ ux += vx >> (m + 1); /* cancel 1st-order error */ uy -= (r = uy >> (2*m + 3)); /* cancel 2nd-order error */ uy -= (r >>= (2*m + 4)); /* cancel 4th-order error */ uy -= r >> (2*m + 3); /* cancel 6th-order error */ uy += vy >> (m + 1); /* cancel 1st-order error */ const int qn = a.size()/4; for (i = 0; i < qn; i++) { a[off+i] = QPoint((xJ + vx) >> 16, (yJ + vy) >> 16); ux -= vx >> m; vx += ux >> m; uy -= vy >> m; vy += uy >> m; }#undef PIV2#undef TWOPI#undef HALF}/*! Sets the points of the array to those describing an arc of an ellipse with size \a w by \a h and position (\a x, \a y ), starting from angle \a a1, spanning \a a2, transformed by the matrix \a xf. The resulting array has sufficient resolution for pixel accuracy. Angles are specified in 16ths of a degree, i.e. a full circle equals 5760 (16*360). Positive values mean counter-clockwise while negative values mean clockwise direction. Zero degrees is at the 3 o'clock position.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -