diff options
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqwmatrix.cpp~')
-rw-r--r-- | tqtinterface/qt4/src/kernel/tqwmatrix.cpp~ | 1204 |
1 files changed, 0 insertions, 1204 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~ b/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~ deleted file mode 100644 index f95b660..0000000 --- a/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~ +++ /dev/null @@ -1,1204 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQWMatrix class -** -** Created : 941020 -** -** 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 "tqwmatrix.h" -#include "tqdatastream.h" -#include "tqregion.h" -#if defined(TQ_WS_X11) -double qsincos( double, bool calcCos ); // defined in qpainter_x11.cpp -#else -#include <math.h> -#endif - -#include <limits.h> - -#ifndef TQT_NO_WMATRIX - -#ifdef USE_QT4 - -// some defines to inline some code -#define MAPDOUBLE( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = m11()*fx + m21()*fy + dx(); \ - ny = m12()*fx + m22()*fy + dy(); \ -} - -#define MAPINT( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = tqRound(m11()*fx + m21()*fy + dx()); \ - ny = tqRound(m12()*fx + m22()*fy + dy()); \ -} - -struct TQWMDoublePoint { - double x; - double y; -}; - -bool qt_old_transformations = TRUE; - -// TQWMatrix TQWMatrix::invert(bool *invertible=0) { -// return convertFromQMatrix(inverted(invertible)); -// } - -/*! - Sets the transformation mode that TQWMatrix and painter - transformations use to \a m. - - \sa TQWMatrix::TransformationMode -*/ -void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m ) -{ - printf("[WARNING] TQWMatrix::setTransformationMode has no effect!\n\r"); - - if ( m == TQWMatrix::Points ) - qt_old_transformations = TRUE; - else - qt_old_transformations = FALSE; -} - - -/*! - Returns the current transformation mode. - - \sa TQWMatrix::TransformationMode -*/ -TQWMatrix::TransformationMode TQWMatrix::transformationMode() -{ - return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas ); -} - -/*! - \internal -*/ -TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const -{ - if( qt_old_transformations ) { - TQPointArray result = a.copy(); - int x, y; - for ( int i=0; i<(int)result.size(); i++ ) { - result.point( i, &x, &y ); - MAPINT( x, y, x, y ); - result.setPoint( i, x, y ); - } - return result; - } else { - int size = a.size(); - int i; - TQMemArray<TQWMDoublePoint> p( size ); - TQPoint *da = TQT_TQPOINT_CONST(a.data()); - TQWMDoublePoint *dp = p.data(); - double xmin = INT_MAX; - double ymin = xmin; - double xmax = INT_MIN; - double ymax = xmax; - int xminp = 0; - int yminp = 0; - for( i = 0; i < size; i++ ) { - dp[i].x = da[i].x(); - dp[i].y = da[i].y(); - if ( dp[i].x < xmin ) { - xmin = dp[i].x; - xminp = i; - } - if ( dp[i].y < ymin ) { - ymin = dp[i].y; - yminp = i; - } - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - double w = TQMAX( xmax - xmin, 1 ); - double h = TQMAX( ymax - ymin, 1 ); - for( i = 0; i < size; i++ ) { - dp[i].x += (dp[i].x - xmin)/w; - dp[i].y += (dp[i].y - ymin)/h; - MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y ); - } - - // now apply correction back for transformed values... - xmin = INT_MAX; - ymin = xmin; - xmax = INT_MIN; - ymax = xmax; - for( i = 0; i < size; i++ ) { - xmin = TQMIN( xmin, dp[i].x ); - ymin = TQMIN( ymin, dp[i].y ); - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - w = TQMAX( xmax - xmin, 1 ); - h = TQMAX( ymax - ymin, 1 ); - - TQPointArray result( size ); - TQPoint *dr = TQT_TQPOINT(result.data()); - for( i = 0; i < size; i++ ) { - dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) ); - dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) ); - } - return result; - } -} - -/*! - Returns the result of multiplying this matrix by matrix \a m. -*/ - -TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m ) -{ - double tm11 = m11()*m.m11() + m12()*m.m21(); - double tm12 = m11()*m.m12() + m12()*m.m22(); - double tm21 = m21()*m.m11() + m22()*m.m21(); - double tm22 = m21()*m.m12() + m22()*m.m22(); - - double tdx = dx()*m.m11() + dy()*m.m21() + m.dx(); - double tdy = dx()*m.m12() + dy()*m.m22() + m.dy(); - - *this = TQWMatrix(tm11, tm12, tm21, tm22, tdx, tdy); - - return *this; -} - -/*! - \overload - \relates TQWMatrix - Returns the product of \a m1 * \a m2. - - Note that matrix multiplication is not commutative, i.e. a*b != - b*a. -*/ - -TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 ) -{ - TQWMatrix result = m1; - result *= m2; - return result; -} - -#else // USE_QT4 - -/*! - \class TQWMatrix tqwmatrix.h - \brief The TQWMatrix class specifies 2D transformations of a - coordinate system. - - \ingroup graphics - \ingroup images - - The standard coordinate system of a \link TQPaintDevice paint - tqdevice\endlink has the origin located at the top-left position. X - values increase to the right; Y values increase downward. - - This coordinate system is the default for the TQPainter, which - renders graphics in a paint tqdevice. A user-defined coordinate - system can be specified by setting a TQWMatrix for the painter. - - Example: - \code - MyWidget::paintEvent( TQPaintEvent * ) - { - TQPainter p; // our painter - TQWMatrix m; // our transformation matrix - m.rotate( 22.5 ); // rotated coordinate system - p.begin( this ); // start painting - p.setWorldMatrix( m ); // use rotated coordinate system - p.drawText( 30,20, "detator" ); // draw rotated text at 30,20 - p.end(); // painting done - } - \endcode - - A matrix specifies how to translate, scale, shear or rotate the - graphics; the actual transformation is performed by the drawing - routines in TQPainter and by TQPixmap::xForm(). - - The TQWMatrix class tqcontains a 3x3 matrix of the form: - <table align=center border=1 cellpadding=1 cellspacing=0> - <tr align=center><td>m11</td><td>m12</td><td> 0 </td></tr> - <tr align=center><td>m21</td><td>m22</td><td> 0 </td></tr> - <tr align=center><td>dx</td> <td>dy</td> <td> 1 </td></tr> - </table> - - A matrix transforms a point in the plane to another point: - \code - x' = m11*x + m21*y + dx - y' = m22*y + m12*x + dy - \endcode - - The point \e (x, y) is the original point, and \e (x', y') is the - transformed point. \e (x', y') can be transformed back to \e (x, - y) by performing the same operation on the \link - TQWMatrix::invert() inverted matrix\endlink. - - The elements \e dx and \e dy specify horizontal and vertical - translation. The elements \e m11 and \e m22 specify horizontal and - vertical scaling. The elements \e m12 and \e m21 specify - horizontal and vertical shearing. - - The identity matrix has \e m11 and \e m22 set to 1; all others are - set to 0. This matrix maps a point to itself. - - Translation is the simplest transformation. Setting \e dx and \e - dy will move the coordinate system \e dx units along the X axis - and \e dy units along the Y axis. - - Scaling can be done by setting \e m11 and \e m22. For example, - setting \e m11 to 2 and \e m22 to 1.5 will double the height and - increase the width by 50%. - - Shearing is controlled by \e m12 and \e m21. Setting these - elements to values different from zero will twist the coordinate - system. - - Rotation is achieved by carefully setting both the shearing - factors and the scaling factors. The TQWMatrix also has a function - that sets \link rotate() rotation \endlink directly. - - TQWMatrix lets you combine transformations like this: - \code - TQWMatrix m; // identity matrix - m.translate(10, -20); // first translate (10,-20) - m.rotate(25); // then rotate 25 degrees - m.scale(1.2, 0.7); // finally scale it - \endcode - - Here's the same example using basic matrix operations: - \code - double a = pi/180 * 25; // convert 25 to radians - double sina = sin(a); - double cosa = cos(a); - TQWMatrix m1(1, 0, 0, 1, 10, -20); // translation matrix - TQWMatrix m2( cosa, sina, // rotation matrix - -sina, cosa, 0, 0 ); - TQWMatrix m3(1.2, 0, 0, 0.7, 0, 0); // scaling matrix - TQWMatrix m; - m = m3 * m2 * m1; // combine all transformations - \endcode - - \l TQPainter has functions to translate, scale, shear and rotate the - coordinate system without using a TQWMatrix. Although these - functions are very convenient, it can be more efficient to build a - TQWMatrix and call TQPainter::setWorldMatrix() if you want to perform - more than a single transform operation. - - \sa TQPainter::setWorldMatrix(), TQPixmap::xForm() -*/ - -bool qt_old_transformations = TRUE; - -/*! - \enum TQWMatrix::TransformationMode - - \keyword transformation matrix - - TQWMatrix offers two transformation modes. Calculations can either - be done in terms of points (Points mode, the default), or in - terms of area (Area mode). - - In Points mode the transformation is applied to the points that - mark out the tqshape's bounding line. In Areas mode the - transformation is applied in such a way that the area of the - contained region is correctly transformed under the matrix. - - \value Points transformations are applied to the tqshape's points. - \value Areas transformations are applied (e.g. to the width and - height) so that the area is transformed. - - Example: - - Suppose we have a rectangle, - \c{TQRect( 10, 20, 30, 40 )} and a transformation matrix - \c{TQWMatrix( 2, 0, 0, 2, 0, 0 )} to double the rectangle's size. - - In Points mode, the matrix will transform the top-left (10,20) and - the bottom-right (39,59) points producing a rectangle with its - top-left point at (20,40) and its bottom-right point at (78,118), - i.e. with a width of 59 and a height of 79. - - In Areas mode, the matrix will transform the top-left point in - the same way as in Points mode to (20/40), and double the width - and height, so the bottom-right will become (69,99), i.e. a width - of 60 and a height of 80. - - Because integer arithmetic is used (for speed), rounding - differences mean that the modes will produce slightly different - results given the same tqshape and the same transformation, - especially when scaling up. This also means that some operations - are not commutative. - - Under Points mode, \c{matrix * ( region1 | region2 )} is not equal to - \c{matrix * region1 | matrix * region2}. Under Area mode, \c{matrix * - (pointarray[i])} is not neccesarily equal to - \c{(matrix * pointarry)[i]}. - - \img xform.png Comparison of Points and Areas TransformationModes -*/ - -/*! - Sets the transformation mode that TQWMatrix and painter - transformations use to \a m. - - \sa TQWMatrix::TransformationMode -*/ -void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m ) -{ - if ( m == TQWMatrix::Points ) - qt_old_transformations = TRUE; - else - qt_old_transformations = FALSE; -} - - -/*! - Returns the current transformation mode. - - \sa TQWMatrix::TransformationMode -*/ -TQWMatrix::TransformationMode TQWMatrix::transformationMode() -{ - return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas ); -} - - -// some defines to inline some code -#define MAPDOUBLE( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = _m11*fx + _m21*fy + _dx; \ - ny = _m12*fx + _m22*fy + _dy; \ -} - -#define MAPINT( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = tqRound(_m11*fx + _m21*fy + _dx); \ - ny = tqRound(_m12*fx + _m22*fy + _dy); \ -} - -/***************************************************************************** - TQWMatrix member functions - *****************************************************************************/ - -/*! - Constructs an identity matrix. All elements are set to zero except - \e m11 and \e m22 (scaling), which are set to 1. -*/ - -TQWMatrix::TQWMatrix() -{ - _m11 = _m22 = 1.0; - _m12 = _m21 = _dx = _dy = 0.0; -} - -/*! - Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a - m22, \a dx and \a dy. -*/ - -TQWMatrix::TQWMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ) -{ - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; -} - - -/*! - Sets the matrix elements to the specified values, \a m11, \a m12, - \a m21, \a m22, \a dx and \a dy. -*/ - -void TQWMatrix::setMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ) -{ - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; -} - - -/*! - \fn double TQWMatrix::m11() const - - Returns the X scaling factor. -*/ - -/*! - \fn double TQWMatrix::m12() const - - Returns the vertical shearing factor. -*/ - -/*! - \fn double TQWMatrix::m21() const - - Returns the horizontal shearing factor. -*/ - -/*! - \fn double TQWMatrix::m22() const - - Returns the Y scaling factor. -*/ - -/*! - \fn double TQWMatrix::dx() const - - Returns the horizontal translation. -*/ - -/*! - \fn double TQWMatrix::dy() const - - Returns the vertical translation. -*/ - - -/*! - \overload - - Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the - following formulae: - - \code - *tx = m11*x + m21*y + dx - *ty = m22*y + m12*x + dy - \endcode -*/ - -void TQWMatrix::map( double x, double y, double *tx, double *ty ) const -{ - MAPDOUBLE( x, y, *tx, *ty ); -} - -/*! - Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the formulae: - - \code - *tx = m11*x + m21*y + dx (rounded to the nearest integer) - *ty = m22*y + m12*x + dy (rounded to the nearest integer) - \endcode -*/ - -void TQWMatrix::map( int x, int y, int *tx, int *ty ) const -{ - MAPINT( x, y, *tx, *ty ); -} - -/*! - \fn TQPoint TQWMatrix::map( const TQPoint &p ) const - - \overload - - Transforms \a p to using the formulae: - - \code - retx = m11*px + m21*py + dx (rounded to the nearest integer) - rety = m22*py + m12*px + dy (rounded to the nearest integer) - \endcode -*/ - -/*! - \fn TQRect TQWMatrix::map( const TQRect &r ) const - - \obsolete - - Please use \l TQWMatrix::mapRect() instead. - - Note that this method does return the bounding rectangle of the \a r, when - shearing or rotations are used. -*/ - -/*! - \fn TQPointArray TQWMatrix::map( const TQPointArray &a ) const - - \overload - - Returns the point array \a a transformed by calling map for each point. -*/ - - -/*! - \fn TQRegion TQWMatrix::map( const TQRegion &r ) const - - \overload - - Transforms the region \a r. - - Calling this method can be rather expensive, if rotations or - shearing are used. -*/ - -/*! - \fn TQRegion TQWMatrix::mapToRegion( const TQRect &rect ) const - - Returns the transformed rectangle \a rect. - - A rectangle which has been rotated or sheared may result in a - non-rectangular region being returned. - - Calling this method can be expensive, if rotations or shearing are - used. If you just need to know the bounding rectangle of the - returned region, use mapRect() which is a lot faster than this - function. - - \sa TQWMatrix::mapRect() -*/ - - -/*! - Returns the transformed rectangle \a rect. - - The bounding rectangle is returned if rotation or shearing has - been specified. - - If you need to know the exact region \a rect maps to use \l - operator*(). - - \sa operator*() -*/ - -TQRect TQWMatrix::mapRect( const TQRect &rect ) const -{ - TQRect result; - if( qt_old_transformations ) { - if ( _m12 == 0.0F && _m21 == 0.0F ) { - result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); - } else { - TQPointArray a( rect ); - a = map( a ); - result = a.boundingRect(); - } - } else { - if ( _m12 == 0.0F && _m21 == 0.0F ) { - int x = tqRound( _m11*rect.x() + _dx ); - int y = tqRound( _m22*rect.y() + _dy ); - int w = tqRound( _m11*rect.width() ); - int h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x -= w-1; - } - if ( h < 0 ) { - h = -h; - y -= h-1; - } - result = TQRect( x, y, w, h ); - } else { - - // see mapToPolygon for explanations of the algorithm. - double x0, y0; - double x, y; - MAPDOUBLE( rect.left(), rect.top(), x0, y0 ); - double xmin = x0; - double ymin = y0; - double xmax = x0; - double ymax = y0; - MAPDOUBLE( rect.right() + 1, rect.top(), x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - MAPDOUBLE( rect.right() + 1, rect.bottom() + 1, x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - MAPDOUBLE( rect.left(), rect.bottom() + 1, x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - double w = xmax - xmin; - double h = ymax - ymin; - xmin -= ( xmin - x0 ) / w; - ymin -= ( ymin - y0 ) / h; - xmax -= ( xmax - x0 ) / w; - ymax -= ( ymax - y0 ) / h; - result = TQRect( tqRound(xmin), tqRound(ymin), tqRound(xmax)-tqRound(xmin)+1, tqRound(ymax)-tqRound(ymin)+1 ); - } - } - return result; -} - - -/*! - \internal -*/ -TQPoint TQWMatrix::operator *( const TQPoint &p ) const -{ - double fx = p.x(); - double fy = p.y(); - return TQPoint( tqRound(_m11*fx + _m21*fy + _dx), - tqRound(_m12*fx + _m22*fy + _dy) ); -} - - -struct TQWMDoublePoint { - double x; - double y; -}; - -/*! - \internal -*/ -TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const -{ - if( qt_old_transformations ) { - TQPointArray result = a.copy(); - int x, y; - for ( int i=0; i<(int)result.size(); i++ ) { - result.point( i, &x, &y ); - MAPINT( x, y, x, y ); - result.setPoint( i, x, y ); - } - return result; - } else { - int size = a.size(); - int i; - TQMemArray<TQWMDoublePoint> p( size ); - TQPoint *da = a.data(); - TQWMDoublePoint *dp = p.data(); - double xmin = INT_MAX; - double ymin = xmin; - double xmax = INT_MIN; - double ymax = xmax; - int xminp = 0; - int yminp = 0; - for( i = 0; i < size; i++ ) { - dp[i].x = da[i].x(); - dp[i].y = da[i].y(); - if ( dp[i].x < xmin ) { - xmin = dp[i].x; - xminp = i; - } - if ( dp[i].y < ymin ) { - ymin = dp[i].y; - yminp = i; - } - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - double w = TQMAX( xmax - xmin, 1 ); - double h = TQMAX( ymax - ymin, 1 ); - for( i = 0; i < size; i++ ) { - dp[i].x += (dp[i].x - xmin)/w; - dp[i].y += (dp[i].y - ymin)/h; - MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y ); - } - - // now apply correction back for transformed values... - xmin = INT_MAX; - ymin = xmin; - xmax = INT_MIN; - ymax = xmax; - for( i = 0; i < size; i++ ) { - xmin = TQMIN( xmin, dp[i].x ); - ymin = TQMIN( ymin, dp[i].y ); - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - w = TQMAX( xmax - xmin, 1 ); - h = TQMAX( ymax - ymin, 1 ); - - TQPointArray result( size ); - TQPoint *dr = result.data(); - for( i = 0; i < size; i++ ) { - dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) ); - dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) ); - } - return result; - } -} - -/*! -\internal -*/ -TQRegion TQWMatrix::operator * (const TQRect &rect ) const -{ - TQRegion result; - if ( isIdentity() ) { - result = rect; - } else if ( _m12 == 0.0F && _m21 == 0.0F ) { - if( qt_old_transformations ) { - result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); - } else { - int x = tqRound( _m11*rect.x() + _dx ); - int y = tqRound( _m22*rect.y() + _dy ); - int w = tqRound( _m11*rect.width() ); - int h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x -= w - 1; - } - if ( h < 0 ) { - h = -h; - y -= h - 1; - } - result = TQRect( x, y, w, h ); - } - } else { - result = TQRegion( mapToPolygon( rect ) ); - } - return result; - -} - -/*! - Returns the transformed rectangle \a rect as a polygon. - - Polygons and rectangles behave slightly differently - when transformed (due to integer rounding), so - \c{matrix.map( TQPointArray( rect ) )} is not always the same as - \c{matrix.mapToPolygon( rect )}. -*/ -TQPointArray TQWMatrix::mapToPolygon( const TQRect &rect ) const -{ - TQPointArray a( 4 ); - if ( qt_old_transformations ) { - a = TQPointArray( rect ); - return operator *( a ); - } - double x[4], y[4]; - if ( _m12 == 0.0F && _m21 == 0.0F ) { - x[0] = tqRound( _m11*rect.x() + _dx ); - y[0] = tqRound( _m22*rect.y() + _dy ); - double w = tqRound( _m11*rect.width() ); - double h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x[0] -= w - 1.; - } - if ( h < 0 ) { - h = -h; - y[0] -= h - 1.; - } - x[1] = x[0]+w-1; - x[2] = x[1]; - x[3] = x[0]; - y[1] = y[0]; - y[2] = y[0]+h-1; - y[3] = y[2]; - } else { - MAPINT( rect.left(), rect.top(), x[0], y[0] ); - MAPINT( rect.right() + 1, rect.top(), x[1], y[1] ); - MAPINT( rect.right() + 1, rect.bottom() + 1, x[2], y[2] ); - MAPINT( rect.left(), rect.bottom() + 1, x[3], y[3] ); - - /* - Including rectangles as we have are evil. - - We now have a rectangle that is one pixel to wide and one to - high. the tranformed position of the top-left corner is - correct. All other points need some adjustments. - - Doing this mathematically exact would force us to calculate some square roots, - something we don't want for the sake of speed. - - Instead we use an approximation, that converts to the correct - answer when m12 -> 0 and m21 -> 0, and accept smaller - errors in the general transformation case. - - The solution is to calculate the width and height of the - bounding rect, and scale the points 1/2/3 by (xp-x0)/xw pixel direction - to point 0. - */ - - double xmin = x[0]; - double ymin = y[0]; - double xmax = x[0]; - double ymax = y[0]; - int i; - for( i = 1; i< 4; i++ ) { - xmin = TQMIN( xmin, x[i] ); - ymin = TQMIN( ymin, y[i] ); - xmax = TQMAX( xmax, x[i] ); - ymax = TQMAX( ymax, y[i] ); - } - double w = xmax - xmin; - double h = ymax - ymin; - - for( i = 1; i < 4; i++ ) { - x[i] -= (x[i] - x[0])/w; - y[i] -= (y[i] - y[0])/h; - } - } -#if 0 - int i; - for( i = 0; i< 4; i++ ) - qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], tqRound(x[i]), tqRound(y[i]) ); - qDebug( "width=%f, height=%f", sqrt( (x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]) ), - sqrt( (x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]) ) ); -#endif - // all coordinates are correctly, tranform to a pointarray - // (rounding to the next integer) - a.setPoints( 4, tqRound( x[0] ), tqRound( y[0] ), - tqRound( x[1] ), tqRound( y[1] ), - tqRound( x[2] ), tqRound( y[2] ), - tqRound( x[3] ), tqRound( y[3] ) ); - return a; -} - -/*! -\internal -*/ -TQRegion TQWMatrix::operator * (const TQRegion &r ) const -{ - if ( isIdentity() ) - return r; - TQMemArray<TQRect> rects = r.rects(); - TQRegion result; - register TQRect *rect = rects.data(); - register int i = rects.size(); - if ( _m12 == 0.0F && _m21 == 0.0F && _m11 > 1.0F && _m22 > 1.0F ) { - // simple case, no rotation - while ( i ) { - int x = tqRound( _m11*rect->x() + _dx ); - int y = tqRound( _m22*rect->y() + _dy ); - int w = tqRound( _m11*rect->width() ); - int h = tqRound( _m22*rect->height() ); - if ( w < 0 ) { - w = -w; - x -= w-1; - } - if ( h < 0 ) { - h = -h; - y -= h-1; - } - *rect = TQRect( x, y, w, h ); - rect++; - i--; - } - result.setRects( rects.data(), rects.size() ); - } else { - while ( i ) { - result |= operator *( *rect ); - rect++; - i--; - } - } - return result; -} - -/*! - Resets the matrix to an identity matrix. - - All elements are set to zero, except \e m11 and \e m22 (scaling) - which are set to 1. - - \sa isIdentity() -*/ - -void TQWMatrix::reset() -{ - _m11 = _m22 = 1.0; - _m12 = _m21 = _dx = _dy = 0.0; -} - -/*! - Returns TRUE if the matrix is the identity matrix; otherwise returns FALSE. - - \sa reset() -*/ -bool TQWMatrix::isIdentity() const -{ - return _m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0 - && _dx == 0.0 && _dy == 0.0; -} - -/*! - Moves the coordinate system \a dx along the X-axis and \a dy along - the Y-axis. - - Returns a reference to the matrix. - - \sa scale(), shear(), rotate() -*/ - -TQWMatrix &TQWMatrix::translate( double dx, double dy ) -{ - _dx += dx*_m11 + dy*_m21; - _dy += dy*_m22 + dx*_m12; - return *this; -} - -/*! - Scales the coordinate system unit by \a sx horizontally and \a sy - vertically. - - Returns a reference to the matrix. - - \sa translate(), shear(), rotate() -*/ - -TQWMatrix &TQWMatrix::scale( double sx, double sy ) -{ - _m11 *= sx; - _m12 *= sx; - _m21 *= sy; - _m22 *= sy; - return *this; -} - -/*! - Shears the coordinate system by \a sh horizontally and \a sv - vertically. - - Returns a reference to the matrix. - - \sa translate(), scale(), rotate() -*/ - -TQWMatrix &TQWMatrix::shear( double sh, double sv ) -{ - double tm11 = sv*_m21; - double tm12 = sv*_m22; - double tm21 = sh*_m11; - double tm22 = sh*_m12; - _m11 += tm11; - _m12 += tm12; - _m21 += tm21; - _m22 += tm22; - return *this; -} - -const double deg2rad = 0.017453292519943295769; // pi/180 - -/*! - Rotates the coordinate system \a a degrees counterclockwise. - - Returns a reference to the matrix. - - \sa translate(), scale(), shear() -*/ - -TQWMatrix &TQWMatrix::rotate( double a ) -{ - double b = deg2rad*a; // convert to radians -#if defined(TQ_WS_X11) - double sina = qsincos(b,FALSE); // fast and convenient - double cosa = qsincos(b,TRUE); -#else - double sina = sin(b); - double cosa = cos(b); -#endif - double tm11 = cosa*_m11 + sina*_m21; - double tm12 = cosa*_m12 + sina*_m22; - double tm21 = -sina*_m11 + cosa*_m21; - double tm22 = -sina*_m12 + cosa*_m22; - _m11 = tm11; _m12 = tm12; - _m21 = tm21; _m22 = tm22; - return *this; -} - -/*! - \fn bool TQWMatrix::isInvertible() const - - Returns TRUE if the matrix is invertible; otherwise returns FALSE. - - \sa invert() -*/ - -/*! - \fn double TQWMatrix::det() const - - Returns the matrix's determinant. -*/ - - -/*! - Returns the inverted matrix. - - If the matrix is singular (not invertible), the identity matrix is - returned. - - If \a invertible is not 0: the value of \a *invertible is set - to TRUE if the matrix is invertible; otherwise \a *invertible is - set to FALSE. - - \sa isInvertible() -*/ - -TQWMatrix TQWMatrix::invert( bool *invertible ) const -{ - double determinant = det(); - if ( determinant == 0.0 ) { - if ( invertible ) - *invertible = FALSE; // singular matrix - TQWMatrix defaultMatrix; - return defaultMatrix; - } - else { // invertible matrix - if ( invertible ) - *invertible = TRUE; - double dinv = 1.0/determinant; - TQWMatrix imatrix( (_m22*dinv), (-_m12*dinv), - (-_m21*dinv), ( _m11*dinv), - ((_m21*_dy - _m22*_dx)*dinv), - ((_m12*_dx - _m11*_dy)*dinv) ); - return imatrix; - } -} - - -/*! - Returns TRUE if this matrix is equal to \a m; otherwise returns FALSE. -*/ - -bool TQWMatrix::operator==( const TQWMatrix &m ) const -{ - return _m11 == m._m11 && - _m12 == m._m12 && - _m21 == m._m21 && - _m22 == m._m22 && - _dx == m._dx && - _dy == m._dy; -} - -/*! - Returns TRUE if this matrix is not equal to \a m; otherwise returns FALSE. -*/ - -bool TQWMatrix::operator!=( const TQWMatrix &m ) const -{ - return _m11 != m._m11 || - _m12 != m._m12 || - _m21 != m._m21 || - _m22 != m._m22 || - _dx != m._dx || - _dy != m._dy; -} - -/*! - Returns the result of multiplying this matrix by matrix \a m. -*/ - -TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m ) -{ - double tm11 = _m11*m._m11 + _m12*m._m21; - double tm12 = _m11*m._m12 + _m12*m._m22; - double tm21 = _m21*m._m11 + _m22*m._m21; - double tm22 = _m21*m._m12 + _m22*m._m22; - - double tdx = _dx*m._m11 + _dy*m._m21 + m._dx; - double tdy = _dx*m._m12 + _dy*m._m22 + m._dy; - - _m11 = tm11; _m12 = tm12; - _m21 = tm21; _m22 = tm22; - _dx = tdx; _dy = tdy; - return *this; -} - -/*! - \overload - \relates TQWMatrix - Returns the product of \a m1 * \a m2. - - Note that matrix multiplication is not commutative, i.e. a*b != - b*a. -*/ - -TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 ) -{ - TQWMatrix result = m1; - result *= m2; - return result; -} - -/***************************************************************************** - TQWMatrix stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQWMatrix - - Writes the matrix \a m 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 TQWMatrix &m ) -{ - if ( s.version() == 1 ) - s << (float)m.m11() << (float)m.m12() << (float)m.m21() - << (float)m.m22() << (float)m.dx() << (float)m.dy(); - else - s << m.m11() << m.m12() << m.m21() << m.m22() - << m.dx() << m.dy(); - return s; -} - -/*! - \relates TQWMatrix - - Reads the matrix \a m 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, TQWMatrix &m ) -{ - if ( s.version() == 1 ) { - float m11, m12, m21, m22, dx, dy; - s >> m11; s >> m12; s >> m21; s >> m22; - s >> dx; s >> dy; - m.setMatrix( m11, m12, m21, m22, dx, dy ); - } - else { - double m11, m12, m21, m22, dx, dy; - s >> m11; s >> m12; s >> m21; s >> m22; - s >> dx; s >> dy; - m.setMatrix( m11, m12, m21, m22, dx, dy ); - } - return s; -} -#endif // TQT_NO_DATASTREAM - -#endif // USE_QT4 - -#endif // TQT_NO_WMATRIX - |