diff options
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpointarray.cpp')
-rw-r--r-- | tqtinterface/qt4/src/kernel/tqpointarray.cpp | 1311 |
1 files changed, 0 insertions, 1311 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqpointarray.cpp b/tqtinterface/qt4/src/kernel/tqpointarray.cpp deleted file mode 100644 index c634210..0000000 --- a/tqtinterface/qt4/src/kernel/tqpointarray.cpp +++ /dev/null @@ -1,1311 +0,0 @@ -#include "tqtglobaldefines.h" - -#ifdef USE_QT4 - -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt3Support module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tqpointarray.h" -#include "private/qt4_qbezier_p.h" - -// Normally declared in private/qpainterpath_p.h -void Q_GUI_EXPORT qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF* startPoint, QPointF *endPoint); - -#include <Qt/qpainterpath.h> - -QT_BEGIN_NAMESPACE - -/*! - \class TQPointArray - The TQPointArray class provides an array of points. - - \compat - - TQPointArray is a QPolygon subclass that provides functions - to make it more source compatible with the \c QPointArray class - in Qt 3. - - In Qt 4, we recommend that you use QPainterPath for representing - arcs, ellipses, and Bezier curves, rather than QPolygon. -*/ - -/*! - Sets the points of the array to those describing an arc of an - ellipse with size, width \a w by height \a h, and position (\a x, - \a y), starting from angle \a a1 and spanning by angle \a a2. The - resulting array has sufficient resolution for pixel accuracy (see - the overloaded function which takes an additional QMatrix - parameter). - - Angles are specified in 16ths of a degree, i.e. a full circle - equals 5760 (16*360). Positive values mean counter-clockwise, - whereas negative values mean the clockwise direction. Zero degrees - is at the 3 o'clock position. -*/ -#ifndef QT_NO_WMATRIX -void TQPointArray::makeArc(int x, int y, int w, int h, int a1, int a2) -{ - QRectF r(x, y, w, h); - QPointF startPoint; - qt_find_ellipse_coords(r, a1 / 16.0, a2 / 16.0, &startPoint, 0); - - QPainterPath path(startPoint); - path.arcTo(r, a1 / 16.0, a2 / 16.0); - - if (path.isEmpty()) - *this = TQPointArray(); - else - *this = path.toSubpathPolygons().at(0).toPolygon(); -} -#endif - -#ifndef QT_NO_TRANSFORMATIONS -/*! - \overload - - Sets the points of the array to those describing an arc of an - ellipse with width \a w and height \a h and position (\a x, \a y), - starting from angle \a a1, and spanning angle by \a a2, and - 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, - whereas negative values mean the clockwise direction. Zero - degrees is at the 3 o'clock position. -*/ -void TQPointArray::makeArc(int x, int y, int w, int h, int a1, int a2, const QMatrix &xf) -{ - QRectF r(x, y, w, h); - QPointF startPoint; - qt_find_ellipse_coords(r, a1 / 16.0, a2 / 16.0, &startPoint, 0); - - QPainterPath path(startPoint); - path.arcTo(r, a1 / 16.0, a2 / 16.0); - path = path * xf; - if (path.isEmpty()) - *this = TQPointArray(); - else - *this = path.toSubpathPolygons().at(0).toPolygon(); -} - -#endif // QT_NO_TRANSFORMATIONS - -/*! - \fn TQPointArray::TQPointArray() - - Constructs an empty TQPointArray. -*/ - -/*! - \fn TQPointArray::TQPointArray(const QRect &r, bool closed) - - Constructs a point array from the rectangle \a r. - - If \a closed is false, then the point array just contains the - following four points of the rectangle ordered clockwise. The - bottom-right point is located at (r.x() + r.width(), r.y() + - r.height()). -*/ - -/*! - \fn TQPointArray::TQPointArray(const QPolygon& other) - - Constructs a copy of \a other. -*/ - -/*! - \fn TQPointArray TQPointArray::copy() const - - Returns a copy of this TQPointArray. -*/ - -/*! - \fn bool TQPointArray::isNull() - - Returns isEmpty(). Use isEmpty() instead. -*/ - -/*! - Sets the points of the array to those describing an ellipse with - size, width \a w by height \a h, and position (\a x, \a y). - - The returned array has sufficient resolution for use as pixels. -*/ -void TQPointArray::makeEllipse(int x, int y, int w, int h) -{ - QPainterPath path; - path.addEllipse(x, y, w, h); - *this = path.toSubpathPolygons().at(0).toPolygon(); -} - -#ifndef QT_NO_BEZIER - -/*! - Returns the Bezier points for the four control points in this - array. -*/ -TQPointArray TQPointArray::cubicBezier() const -{ - if (size() != 4) { - qWarning( "TQPointArray::bezier: The array must have 4 control points" ); - return QPolygon(); - } - QPolygonF polygon = QBezier::fromPoints(at(0), at(1), at(2), at(3)).toPolygon(); - return polygon.toPolygon(); -} -#endif //QT_NO_BEZIER - -QT_END_NAMESPACE - -#else // USE_QT4 - -/**************************************************************************** -** -** Implementation of TQPointArray class -** -** Created : 940213 -** -** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. -** -** 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 requirements 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 sales@trolltech.com. -** -** 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 "tqpointarray.h" -#include "tqrect.h" -#include "tqdatastream.h" -#include "tqwmatrix.h" -#include <stdarg.h> - -const double TQ_PI = 3.14159265358979323846; // pi // one more useful comment - - -/*! - \class TQPointArray tqpointarray.h - \brief The TQPointArray class provides an array of points. - - \ingroup images - \ingroup graphics - \ingroup shared - - A TQPointArray is an array of TQPoint objects. In addition to the - functions provided by TQMemArray, TQPointArray provides some - point-specific functions. - - For convenient reading and writing of the point data use - setPoints(), putPoints(), point(), and setPoint(). - - For tqgeometry operations use boundingRect() and translate(). There - is also the TQWMatrix::map() function for more general - transformations of TQPointArrays. You can also create arcs and - ellipses with makeArc() and makeEllipse(). - - Among others, TQPointArray is used by TQPainter::drawLineSegments(), - TQPainter::drawPolyline(), TQPainter::drawPolygon() and - TQPainter::drawCubicBezier(). - - Note that because this class is a TQMemArray, copying an array and - modifying the copy modifies the original as well, i.e. a shallow - copy. If you need a deep copy use copy() or detach(), for example: - - \code - void drawGiraffe( const TQPointArray & r, TQPainter * p ) - { - TQPointArray tmp = r; - tmp.detach(); - // some code that modifies tmp - p->drawPoints( tmp ); - } - \endcode - - If you forget the tmp.detach(), the const array will be modified. - - \sa TQPainter TQWMatrix TQMemArray -*/ - - -/***************************************************************************** - TQPointArray member functions - *****************************************************************************/ - -/*! - \fn TQPointArray::TQPointArray() - - Constructs a null point array. - - \sa isNull() -*/ - -/*! - \fn TQPointArray::TQPointArray( int size ) - - Constructs a point array with room for \a size points. Makes a - null array if \a size == 0. - - \sa resize(), isNull() -*/ - -/*! - \fn TQPointArray::TQPointArray( const TQPointArray &a ) - - Constructs a shallow copy of the point array \a a. - - \sa copy() detach() -*/ - -/*! - 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(). -*/ - -TQPointArray::TQPointArray( const TQRect &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() ); - } -} - -/*! - \internal - Constructs a point array with \a nPoints points, taken from the - \a points array. - - Equivalent to setPoints(nPoints, points). -*/ - -TQPointArray::TQPointArray( int nPoints, const TQCOORD *points ) -{ - setPoints( nPoints, points ); -} - - -/*! - \fn TQPointArray::~TQPointArray() - - Destroys the point array. -*/ - - -/*! - \fn TQPointArray &TQPointArray::operator=( const TQPointArray &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() detach() -*/ - -/*! - \fn TQPointArray TQPointArray::copy() const - - Creates a deep copy of the array. - - \sa detach() -*/ - - - -/*! - Translates all points in the array by \a (dx, dy). -*/ - -void TQPointArray::translate( int dx, int dy ) -{ - register TQPoint *p = data(); - register int i = size(); - TQPoint pt( dx, dy ); - while ( i-- ) { - *p += pt; - p++; - } -} - - -/*! - Reads the coordinates of the point at position \a index within the - array and writes them into \a *x and \a *y. -*/ - -void TQPointArray::point( uint index, int *x, int *y ) const -{ - TQPoint p = TQMemArray<TQPoint>::at( index ); - if ( x ) - *x = (int)p.x(); - if ( y ) - *y = (int)p.y(); -} - -/*! - \overload - - Returns the point at position \a index within the array. -*/ - -TQPoint TQPointArray::point( uint index ) const -{ // #### index out of bounds - return TQMemArray<TQPoint>::at( index ); -} - -/*! - \fn void TQPointArray::setPoint( uint i, const TQPoint &p ) - - \overload - - Sets the point at array index \a i to \a p. -*/ - -/*! - Sets the point at position \a index in the array to \a (x, y). -*/ - -void TQPointArray::setPoint( uint index, int x, int y ) -{ // #### index out of bounds - TQMemArray<TQPoint>::at( index ) = TQPoint( x, y ); -} - -/*! - \internal - 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 TQCOORD points[] = { 1,2, 3,4 }; - TQPointArray a; - a.setPoints( 2, points ); - \endcode - - \sa resize(), putPoints() -*/ - -bool TQPointArray::setPoints( int nPoints, const TQCOORD *points ) -{ - if ( !resize(nPoints) ) - return FALSE; - int i = 0; - while ( nPoints-- ) { // make array of points - setPoint( i++, *points, *(points+1) ); - points++; - points++; - } - return TRUE; -} - -/*! - \overload - - 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 - TQPointArray a; - a.setPoints( 2, 1,2, 3,4 ); - \endcode - - The points are given as a sequence of integers, starting with \a - firstx then \a firsty, and so on. - - \sa resize(), putPoints() -*/ - -bool TQPointArray::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; -} - -/*! \overload - \internal - Copies \a nPoints points from the \a points coord array into - this point array, and resizes the point array if - \c{index+nPoints} 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). - -*/ - -bool TQPointArray::putPoints( int index, int nPoints, const TQCOORD *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 from position \a index, and resizes the point array if - \c{index+nPoints} 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 three points (4,5), (6,7) - and (8,9), by expanding the array from 1 to 3 points: - - \code - TQPointArray a( 1 ); - a[0] = TQPoint( 4, 5 ); - a.putPoints( 1, 2, 6,7, 8,9 ); // index == 1, points == 2 - \endcode - - This has the same result, but here putPoints overwrites rather - than extends: - \code - TQPointArray a( 3 ); - a.putPoints( 0, 3, 4,5, 0,0, 8,9 ); - a.putPoints( 1, 1, 6,7 ); - \endcode - - The points are given as a sequence of integers, starting with \a - firstx then \a firsty, and so on. - - \sa resize() -*/ - -bool TQPointArray::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; -} - - -/*! - \overload - - This version of the function copies \a nPoints from \a from into - this array, starting at \a index in this array and \a fromIndex in - \a from. \a fromIndex is 0 by default. - - \code - TQPointArray a; - a.putPoints( 0, 3, 1,2, 0,0, 5,6 ); - // a is now the three-point array ( 1,2, 0,0, 5,6 ); - TQPointArray b; - b.putPoints( 0, 3, 4,4, 5,5, 6,6 ); - // b is now ( 4,4, 5,5, 6,6 ); - a.putPoints( 2, 3, b ); - // a is now ( 1,2, 0,0, 4,4, 5,5, 6,6 ); - \endcode -*/ - -bool TQPointArray::putPoints( int index, int nPoints, - const TQPointArray & from, int fromIndex ) -{ - if ( index + nPoints > (int)size() ) { // extend array - if ( !resize(index + nPoints) ) - return FALSE; - } - if ( nPoints <= 0 ) - return TRUE; - int n = 0; - while( n < nPoints ) { - setPoint( index+n, from[fromIndex+n] ); - n++; - } - return TRUE; -} - - -/*! - Returns the bounding rectangle of the points in the array, or - TQRect(0,0,0,0) if the array is empty. -*/ - -TQRect TQPointArray::boundingRect() const -{ - if ( isEmpty() ) - return TQRect( 0, 0, 0, 0 ); // null rectangle - register TQPoint *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 TQRect( TQPoint(minx,miny), TQPoint(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, width \a w by height \a h, and position (\a x, - \a y), starting from angle \a a1 and spanning by angle \a a2. The - resulting array has sufficient resolution for pixel accuracy (see - the overloaded function which takes an additional TQWMatrix - parameter). - - Angles are specified in 16ths of a degree, i.e. a full circle - equals 5760 (16*360). Positive values mean counter-clockwise, - whereas negative values mean the clockwise direction. Zero degrees - is at the 3 o'clock position. - - See the \link qcanvasellipse.html#anglediagram angle diagram\endlink. -*/ - -void TQPointArray::makeArc( int x, int y, int w, int h, int a1, int a2 ) -{ -#if !defined(TQT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) - TQWMatrix 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 - TQPointArray 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.TQMemArray<TQPoint>::at( j++ ) = TQMemArray<TQPoint>::at( i++ ); - } - } else { - while ( npts-- ) { - if ( i < 0 ) // wrap index - i = (int)size()-1; - a.TQMemArray<TQPoint>::at( j++ ) = TQMemArray<TQPoint>::at( i-- ); - } - } - *this = a; - return; -#endif -} - -#ifndef TQT_NO_TRANSFORMATIONS -// Based upon: -// parelarc.c from Graphics Gems III -// VanAken / Simar, "A Parametric Elliptical Arc Algorithm" -// -static void -qtr_elips(TQPointArray& 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] = TQPoint((xJ + vx) >> 16, (yJ + vy) >> 16); - ux -= vx >> m; - vx += ux >> m; - uy -= vy >> m; - vy += uy >> m; - } - -#undef PIV2 -#undef TWOPI -#undef HALF -} - - -/*! - \overload - - Sets the points of the array to those describing an arc of an - ellipse with width \a w and height \a h and position (\a x, \a y), - starting from angle \a a1, and spanning angle by \a a2, and - 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, - whereas negative values mean the clockwise direction. Zero degrees - is at the 3 o'clock position. - - See the \link qcanvasellipse.html#anglediagram angle diagram\endlink. -*/ -void TQPointArray::makeArc( int x, int y, int w, int h, - int a1, int a2, - const TQWMatrix& xf ) -{ -#define PIV2 102944 /* fixed point PI/2 */ - if ( --w < 0 || --h < 0 || !a2 ) { - resize( 0 ); - return; - } - - bool rev = a2 < 0; - if ( rev ) { - a1 += a2; - a2 = -a2; - } - a1 = fix_angle( a1 ); - if ( a1 < 0 ) - a1 += 16*360; - a2 = fix_angle( a2 ); - - bool arc = a1 != 0 || a2 != 360*16 || rev; - - double xP, yP, xQ, yQ, xK, yK; - - xf.map(x+w, y+h/2.0, &xP, &yP); - xf.map(x+w/2.0, y, &xQ, &yQ); - xf.map(x+w, y, &xK, &yK); - - int m = 3; - int max; - int q = int(TQMAX(TQABS(xP-xQ),TQABS(yP-yQ))); - if ( arc ) - q *= 2; - do { - m++; - max = 4*(1 + (PIV2 >> (16 - m)) ); - } while (max < q && m < 16); // 16 limits memory usage on HUGE arcs - - double inc = 1.0/(1<<m); - - const int qn = (PIV2 >> (16 - m)); - resize(qn*4); - - qtr_elips(*this, 0, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x, y+h/2.0, &xQ, &yQ); - xf.map(x, y, &xK, &yK); - qtr_elips(*this, qn, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x+w/2.0, y+h, &xQ, &yQ); - xf.map(x, y+h, &xK, &yK); - qtr_elips(*this, qn*2, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x+w, y+h/2.0, &xQ, &yQ); - xf.map(x+w, y+h, &xK, &yK); - qtr_elips(*this, qn*3, xP, yP, xQ, yQ, xK, yK, m); - - int n = size(); - - if ( arc ) { - double da1 = double(a1)*TQ_PI / (360*8); - double da3 = double(a2+a1)*TQ_PI / (360*8); - int i = int(da1/inc+0.5); - int l = int(da3/inc+0.5); - int k = (l-i)+1; - TQPointArray r(k); - int j = 0; - - if ( rev ) { - while ( k-- ) - r[j++] = at((i+k)%n); - } else { - while ( j < k ) { - r[j] = at((i+j)%n); - j++; - } - } - *this = r; - } -#undef PIV2 -} - -#endif // TQT_NO_TRANSFORMATIONS - -/*! - Sets the points of the array to those describing an ellipse with - size, width \a w by height \a h, and position (\a x, \a y). - - The returned array has sufficient resolution for use as pixels. -*/ -void TQPointArray::makeEllipse( int x, int y, int w, int h ) -{ // midpoint, 1/4 ellipse -#if !defined(TQT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) - TQWMatrix unit; - makeArc(x,y,w,h,0,360*16,unit); - return; -#else - if ( w <= 0 || h <= 0 ) { - if ( w == 0 || h == 0 ) { - resize( 0 ); - return; - } - if ( w < 0 ) { // negative width - w = -w; - x -= w; - } - if ( h < 0 ) { // negative height - h = -h; - y -= h; - } - } - int s = (w+h+2)/2; // max size of xx,yy array - int *px = new int[s]; // 1/4th of ellipse - int *py = new int[s]; - int xx, yy, i=0; - double d1, d2; - double a2=(w/2)*(w/2), b2=(h/2)*(h/2); - xx = 0; - yy = int(h/2); - d1 = b2 - a2*(h/2) + 0.25*a2; - px[i] = xx; - py[i] = yy; - i++; - while ( a2*(yy-0.5) > b2*(xx+0.5) ) { // region 1 - if ( d1 < 0 ) { - d1 = d1 + b2*(3.0+2*xx); - xx++; - } else { - d1 = d1 + b2*(3.0+2*xx) + 2.0*a2*(1-yy); - xx++; - yy--; - } - px[i] = xx; - py[i] = yy; - i++; - } - d2 = b2*(xx+0.5)*(xx+0.5) + a2*(yy-1)*(yy-1) - a2*b2; - while ( yy > 0 ) { // region 2 - if ( d2 < 0 ) { - d2 = d2 + 2.0*b2*(xx+1) + a2*(3-2*yy); - xx++; - yy--; - } else { - d2 = d2 + a2*(3-2*yy); - yy--; - } - px[i] = xx; - py[i] = yy; - i++; - } - s = i; - resize( 4*s ); // make full point array - x += w/2; - y += h/2; - for ( i=0; i<s; i++ ) { // mirror - xx = px[i]; - yy = py[i]; - setPoint( s-i-1, x+xx, y-yy ); - setPoint( s+i, x-xx, y-yy ); - setPoint( 3*s-i-1, x-xx, y+yy ); - setPoint( 3*s+i, x+xx, y+yy ); - } - delete[] px; - delete[] py; -#endif -} - -#ifndef TQT_NO_BEZIER -// Work functions for TQPointArray::cubicBezier() -static -void split(const double *p, double *l, double *r) -{ - double tmpx; - double tmpy; - - l[0] = p[0]; - l[1] = p[1]; - r[6] = p[6]; - r[7] = p[7]; - - l[2] = (p[0]+ p[2])/2; - l[3] = (p[1]+ p[3])/2; - tmpx = (p[2]+ p[4])/2; - tmpy = (p[3]+ p[5])/2; - r[4] = (p[4]+ p[6])/2; - r[5] = (p[5]+ p[7])/2; - - l[4] = (l[2]+ tmpx)/2; - l[5] = (l[3]+ tmpy)/2; - r[2] = (tmpx + r[4])/2; - r[3] = (tmpy + r[5])/2; - - l[6] = (l[4]+ r[2])/2; - l[7] = (l[5]+ r[3])/2; - r[0] = l[6]; - r[1] = l[7]; -} - -// Based on: -// -// A Fast 2D Point-On-Line Test -// by Alan Paeth -// from "Graphics Gems", Academic Press, 1990 -static -int pnt_on_line( const int* p, const int* q, const int* t ) -{ -/* - * given a line through P:(px,py) Q:(qx,qy) and T:(tx,ty) - * return 0 if T is not on the line through <--P--Q--> - * 1 if T is on the open ray ending at P: <--P - * 2 if T is on the closed interior along: P--Q - * 3 if T is on the open ray beginning at Q: Q--> - * - * Example: consider the line P = (3,2), Q = (17,7). A plot - * of the test points T(x,y) (with 0 mapped onto '.') yields: - * - * 8| . . . . . . . . . . . . . . . . . 3 3 - * Y 7| . . . . . . . . . . . . . . 2 2 Q 3 3 Q = 2 - * 6| . . . . . . . . . . . 2 2 2 2 2 . . . - * a 5| . . . . . . . . 2 2 2 2 2 2 . . . . . - * x 4| . . . . . 2 2 2 2 2 2 . . . . . . . . - * i 3| . . . 2 2 2 2 2 . . . . . . . . . . . - * s 2| 1 1 P 2 2 . . . . . . . . . . . . . . P = 2 - * 1| 1 1 . . . . . . . . . . . . . . . . . - * +-------------------------------------- - * 1 2 3 4 5 X-axis 10 15 19 - * - * Point-Line distance is normalized with the Infinity Norm - * avoiding square-root code and tightening the test vs the - * Manhattan Norm. All math is done on the field of integers. - * The latter replaces the initial ">= MAX(...)" test with - * "> (ABS(qx-px) + ABS(qy-py))" loosening both inequality - * and norm, yielding a broader target line for selection. - * The tightest test is employed here for best discrimination - * in merging collinear (to grid coordinates) vertex chains - * into a larger, spanning vectors within the Lemming editor. - */ - - // if all points are coincident, return condition 2 (on line) - if(q[0]==p[0] && q[1]==p[1] && q[0]==t[0] && q[1]==t[1]) { - return 2; - } - - if ( TQABS((q[1]-p[1])*(t[0]-p[0])-(t[1]-p[1])*(q[0]-p[0])) >= - (TQMAX(TQABS(q[0]-p[0]), TQABS(q[1]-p[1])))) return 0; - - if (((q[0]<p[0])&&(p[0]<t[0])) || ((q[1]<p[1])&&(p[1]<t[1]))) - return 1 ; - if (((t[0]<p[0])&&(p[0]<q[0])) || ((t[1]<p[1])&&(p[1]<q[1]))) - return 1 ; - if (((p[0]<q[0])&&(q[0]<t[0])) || ((p[1]<q[1])&&(q[1]<t[1]))) - return 3 ; - if (((t[0]<q[0])&&(q[0]<p[0])) || ((t[1]<q[1])&&(q[1]<p[1]))) - return 3 ; - - return 2 ; -} -static -void polygonizeTQBezier( double* acc, int& accsize, const double ctrl[], - int maxsize ) -{ - if ( accsize > maxsize / 2 ) - { - // This never happens in practice. - - if ( accsize >= maxsize-4 ) - return; - // Running out of space - approximate by a line. - acc[accsize++] = ctrl[0]; - acc[accsize++] = ctrl[1]; - acc[accsize++] = ctrl[6]; - acc[accsize++] = ctrl[7]; - return; - } - - //intersects: - double l[8]; - double r[8]; - split( ctrl, l, r); - - // convert to integers for line condition check - int c0[2]; c0[0] = int(ctrl[0]); c0[1] = int(ctrl[1]); - int c1[2]; c1[0] = int(ctrl[2]); c1[1] = int(ctrl[3]); - int c2[2]; c2[0] = int(ctrl[4]); c2[1] = int(ctrl[5]); - int c3[2]; c3[0] = int(ctrl[6]); c3[1] = int(ctrl[7]); - - // #### Duplication needed? - if ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 - && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 - && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) - { - // Approximate by one line. - // Dont need to write last pt as it is the same as first pt - // on the next segment - acc[accsize++] = l[0]; - acc[accsize++] = l[1]; - return; - } - - if ( ( pnt_on_line( c0, c3, c1 ) == 2 && pnt_on_line( c0, c3, c2 ) == 2 ) - || ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 - && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 - && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) ) - { - // Approximate by one line. - // Dont need to write last pt as it is the same as first pt - // on the next segment - acc[accsize++] = l[0]; - acc[accsize++] = l[1]; - return; - } - - // Too big and too curved - recusively subdivide. - polygonizeTQBezier( acc, accsize, l, maxsize ); - polygonizeTQBezier( acc, accsize, r, maxsize ); -} - -/*! - Returns the Bezier points for the four control points in this - array. -*/ - -TQPointArray TQPointArray::cubicBezier() const -{ -#ifdef USE_SIMPLE_TQBEZIER_CODE - if ( size() != 4 ) { -#if defined(TQT_CHECK_RANGE) - qWarning( "TQPointArray::bezier: The array must have 4 control points" ); -#endif - TQPointArray p; - return p; - } - - int v; - float xvec[4]; - float yvec[4]; - for ( v=0; v<4; v++ ) { // store all x,y in xvec,yvec - int x, y; - point( v, &x, &y ); - xvec[v] = (float)x; - yvec[v] = (float)y; - } - - TQRect r = boundingRect(); - int m = TQMAX(r.width(),r.height())/2; - m = TQMIN(m,30); // m = number of result points - if ( m < 2 ) // at least two points - m = 2; - TQPointArray p( m ); // p = Bezier point array - register TQPointData *pd = p.data(); - - float x0 = xvec[0], y0 = yvec[0]; - float dt = 1.0F/m; - float cx = 3.0F * (xvec[1] - x0); - float bx = 3.0F * (xvec[2] - xvec[1]) - cx; - float ax = xvec[3] - (x0 + cx + bx); - float cy = 3.0F * (yvec[1] - y0); - float by = 3.0F * (yvec[2] - yvec[1]) - cy; - float ay = yvec[3] - (y0 + cy + by); - float t = dt; - - pd->rx() = (TQCOORD)xvec[0]; - pd->ry() = (TQCOORD)yvec[0]; - pd++; - m -= 2; - - while ( m-- ) { - pd->rx() = (TQCOORD)tqRound( ((ax * t + bx) * t + cx) * t + x0 ); - pd->ry() = (TQCOORD)tqRound( ((ay * t + by) * t + cy) * t + y0 ); - pd++; - t += dt; - } - - pd->rx() = (TQCOORD)xvec[3]; - pd->ry() = (TQCOORD)yvec[3]; - - return p; -#else - - if ( size() != 4 ) { -#if defined(TQT_CHECK_RANGE) - qWarning( "TQPointArray::bezier: The array must have 4 control points" ); -#endif - TQPointArray pa; - return pa; - } else { - TQRect r = boundingRect(); - int m = 4+2*TQMAX(r.width(),r.height()); - double *p = new double[m]; - double ctrl[8]; - int i; - for (i=0; i<4; i++) { - ctrl[i*2] = at(i).x(); - ctrl[i*2+1] = at(i).y(); - } - int len=0; - polygonizeTQBezier( p, len, ctrl, m ); - TQPointArray pa((len/2)+1); // one extra point for last point on line - int j=0; - for (i=0; j<len; i++) { - int x = tqRound(p[j++]); - int y = tqRound(p[j++]); - pa[i] = TQPoint(x,y); - } - // add last pt on the line, which will be at the last control pt - pa[(int)pa.size()-1] = at(3); - delete[] p; - - return pa; - } - -#endif -} -#endif //TQT_NO_BEZIER - -/***************************************************************************** - TQPointArray stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQPointArray - - Writes the point array, \a a 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 TQPointArray &a ) -{ - register uint i; - uint len = a.size(); - s << len; // write size of array - for ( i=0; i<len; i++ ) // write each point - s << a.point( i ); - return s; -} - -/*! - \relates TQPointArray - - Reads a point array, \a a from 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, TQPointArray &a ) -{ - register uint i; - uint len; - s >> len; // read size of array - if ( !a.resize( len ) ) // no memory - return s; - TQPoint p; - for ( i=0; i<len; i++ ) { // read each point - s >> p; - a.setPoint( i, p ); - } - return s; -} -#endif //TQT_NO_DATASTREAM - - - -struct TQShortPoint { // Binary compatible with XPoint - short x, y; -}; - -uint TQPointArray::splen = 0; -void* TQPointArray::sp = 0; // Really a TQShortPoint* - -/*! - \internal - - Converts the point coords to short (16bit) size, compatible with - X11's XPoint structure. The pointer returned points to a static - array, so its contents will be overwritten the next time this - function is called. -*/ - -void* TQPointArray::shortPoints( int index, int nPoints ) const -{ - - if ( isNull() || !nPoints ) - return 0; - TQPoint* p = data(); - p += index; - uint i = nPoints < 0 ? size() : nPoints; - if ( splen < i ) { - if ( sp ) - delete[] ((TQShortPoint*)sp); - sp = new TQShortPoint[i]; - splen = i; - } - TQShortPoint* ps = (TQShortPoint*)sp; - while ( i-- ) { - ps->x = (short)p->x(); - ps->y = (short)p->y(); - p++; - ps++; - } - return sp; -} - - -/*! - \internal - - Deallocates the internal buffer used by shortPoints(). -*/ - -void TQPointArray::cleanBuffers() -{ - if ( sp ) - delete[] ((TQShortPoint*)sp); - sp = 0; - splen = 0; -} - -#endif // USE_QT4
\ No newline at end of file |