src/gui/painting/qmatrix.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qdatastream.h"
       
    43 #include "qdebug.h"
       
    44 #include "qmatrix.h"
       
    45 #include "qregion.h"
       
    46 #include "qpainterpath.h"
       
    47 #include "qvariant.h"
       
    48 #include <qmath.h>
       
    49 
       
    50 #include <limits.h>
       
    51 
       
    52 QT_BEGIN_NAMESPACE
       
    53 
       
    54 /*!
       
    55     \class QMatrix
       
    56     \brief The QMatrix class specifies 2D transformations of a
       
    57     coordinate system.
       
    58     \obsolete
       
    59 
       
    60     \ingroup painting
       
    61 
       
    62     A matrix specifies how to translate, scale, shear or rotate the
       
    63     coordinate system, and is typically used when rendering graphics.
       
    64     QMatrix, in contrast to QTransform, does not allow perspective
       
    65     transformations. QTransform is the recommended transformation
       
    66     class in Qt.
       
    67 
       
    68     A QMatrix object can be built using the setMatrix(), scale(),
       
    69     rotate(), translate() and shear() functions.  Alternatively, it
       
    70     can be built by applying \l {QMatrix#Basic Matrix
       
    71     Operations}{basic matrix operations}. The matrix can also be
       
    72     defined when constructed, and it can be reset to the identity
       
    73     matrix (the default) using the reset() function.
       
    74 
       
    75     The QMatrix class supports mapping of graphic primitives: A given
       
    76     point, line, polygon, region, or painter path can be mapped to the
       
    77     coordinate system defined by \e this matrix using the map()
       
    78     function. In case of a rectangle, its coordinates can be
       
    79     transformed using the mapRect() function. A rectangle can also be
       
    80     transformed into a \e polygon (mapped to the coordinate system
       
    81     defined by \e this matrix), using the mapToPolygon() function.
       
    82 
       
    83     QMatrix provides the isIdentity() function which returns true if
       
    84     the matrix is the identity matrix, and the isInvertible() function
       
    85     which returns true if the matrix is non-singular (i.e. AB = BA =
       
    86     I). The inverted() function returns an inverted copy of \e this
       
    87     matrix if it is invertible (otherwise it returns the identity
       
    88     matrix). In addition, QMatrix provides the det() function
       
    89     returning the matrix's determinant.
       
    90 
       
    91     Finally, the QMatrix class supports matrix multiplication, and
       
    92     objects of the class can be streamed as well as compared.
       
    93 
       
    94     \tableofcontents
       
    95 
       
    96     \section1 Rendering Graphics
       
    97 
       
    98     When rendering graphics, the matrix defines the transformations
       
    99     but the actual transformation is performed by the drawing routines
       
   100     in QPainter.
       
   101 
       
   102     By default, QPainter operates on the associated device's own
       
   103     coordinate system.  The standard coordinate system of a
       
   104     QPaintDevice has its origin located at the top-left position. The
       
   105     \e x values increase to the right; \e y values increase
       
   106     downward. For a complete description, see the \l {The Coordinate
       
   107     System}{coordinate system} documentation.
       
   108 
       
   109     QPainter has functions to translate, scale, shear and rotate the
       
   110     coordinate system without using a QMatrix. For example:
       
   111 
       
   112     \table 100%
       
   113     \row
       
   114     \o \inlineimage qmatrix-simpletransformation.png
       
   115     \o
       
   116     \snippet doc/src/snippets/matrix/matrix.cpp 0
       
   117     \endtable
       
   118 
       
   119     Although these functions are very convenient, it can be more
       
   120     efficient to build a QMatrix and call QPainter::setMatrix() if you
       
   121     want to perform more than a single transform operation. For
       
   122     example:
       
   123 
       
   124     \table 100%
       
   125     \row
       
   126     \o \inlineimage qmatrix-combinedtransformation.png
       
   127     \o
       
   128     \snippet doc/src/snippets/matrix/matrix.cpp 1
       
   129     \endtable
       
   130 
       
   131     \section1 Basic Matrix Operations
       
   132 
       
   133     \image qmatrix-representation.png
       
   134 
       
   135     A QMatrix object contains a 3 x 3 matrix.  The \c dx and \c dy
       
   136     elements specify horizontal and vertical translation. The \c m11
       
   137     and \c m22 elements specify horizontal and vertical scaling. And
       
   138     finally, the \c m21 and \c m12 elements specify horizontal and
       
   139     vertical \e shearing.
       
   140 
       
   141     QMatrix transforms a point in the plane to another point using the
       
   142     following formulas:
       
   143 
       
   144     \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 0
       
   145 
       
   146     The point \e (x, y) is the original point, and \e (x', y') is the
       
   147     transformed point. \e (x', y') can be transformed back to \e (x,
       
   148     y) by performing the same operation on the inverted() matrix.
       
   149 
       
   150     The various matrix elements can be set when constructing the
       
   151     matrix, or by using the setMatrix() function later on. They can also
       
   152     be manipulated using the translate(), rotate(), scale() and
       
   153     shear() convenience functions, The currently set values can be
       
   154     retrieved using the m11(), m12(), m21(), m22(), dx() and dy()
       
   155     functions.
       
   156 
       
   157     Translation is the simplest transformation. Setting \c dx and \c
       
   158     dy will move the coordinate system \c dx units along the X axis
       
   159     and \c dy units along the Y axis.  Scaling can be done by setting
       
   160     \c m11 and \c m22. For example, setting \c m11 to 2 and \c m22 to
       
   161     1.5 will double the height and increase the width by 50%.  The
       
   162     identity matrix has \c m11 and \c m22 set to 1 (all others are set
       
   163     to 0) mapping a point to itself. Shearing is controlled by \c m12
       
   164     and \c m21. Setting these elements to values different from zero
       
   165     will twist the coordinate system. Rotation is achieved by
       
   166     carefully setting both the shearing factors and the scaling
       
   167     factors.
       
   168 
       
   169     Here's the combined transformations example using basic matrix
       
   170     operations:
       
   171 
       
   172     \table 100%
       
   173     \row
       
   174     \o \inlineimage qmatrix-combinedtransformation.png
       
   175     \o
       
   176     \snippet doc/src/snippets/matrix/matrix.cpp 2
       
   177     \endtable
       
   178 
       
   179     \sa QPainter, QTransform, {The Coordinate System}, 
       
   180     {demos/affine}{Affine Transformations Demo}, {Transformations Example}
       
   181 */
       
   182 
       
   183 
       
   184 // some defines to inline some code
       
   185 #define MAPDOUBLE(x, y, nx, ny) \
       
   186 { \
       
   187     qreal fx = x; \
       
   188     qreal fy = y; \
       
   189     nx = _m11*fx + _m21*fy + _dx; \
       
   190     ny = _m12*fx + _m22*fy + _dy; \
       
   191 }
       
   192 
       
   193 #define MAPINT(x, y, nx, ny) \
       
   194 { \
       
   195     qreal fx = x; \
       
   196     qreal fy = y; \
       
   197     nx = qRound(_m11*fx + _m21*fy + _dx); \
       
   198     ny = qRound(_m12*fx + _m22*fy + _dy); \
       
   199 }
       
   200 
       
   201 /*****************************************************************************
       
   202   QMatrix member functions
       
   203  *****************************************************************************/
       
   204 /*!
       
   205     \fn QMatrix::QMatrix(Qt::Initialization)
       
   206     \internal
       
   207 */
       
   208 
       
   209 /*!
       
   210     Constructs an identity matrix.
       
   211 
       
   212     All elements are set to zero except \c m11 and \c m22 (specifying
       
   213     the scale), which are set to 1.
       
   214 
       
   215     \sa reset()
       
   216 */
       
   217 
       
   218 QMatrix::QMatrix()
       
   219     : _m11(1.)
       
   220     , _m12(0.)
       
   221     , _m21(0.)
       
   222     , _m22(1.)
       
   223     , _dx(0.)
       
   224     , _dy(0.)
       
   225 {
       
   226 }
       
   227 
       
   228 /*!
       
   229     Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a
       
   230     m22, \a dx and \a dy.
       
   231 
       
   232     \sa setMatrix()
       
   233 */
       
   234 
       
   235 QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
       
   236     : _m11(m11)
       
   237     , _m12(m12)
       
   238     , _m21(m21)
       
   239     , _m22(m22)
       
   240     , _dx(dx)
       
   241     , _dy(dy)
       
   242 {
       
   243 }
       
   244 
       
   245 
       
   246 /*!
       
   247      Constructs a matrix that is a copy of the given \a matrix.
       
   248  */
       
   249 QMatrix::QMatrix(const QMatrix &matrix)
       
   250     : _m11(matrix._m11)
       
   251     , _m12(matrix._m12)
       
   252     , _m21(matrix._m21)
       
   253     , _m22(matrix._m22)
       
   254     , _dx(matrix._dx)
       
   255     , _dy(matrix._dy)
       
   256 {
       
   257 }
       
   258 
       
   259 /*!
       
   260     Sets the matrix elements to the specified values, \a m11, \a m12,
       
   261     \a m21, \a m22, \a dx and \a dy.
       
   262 
       
   263     Note that this function replaces the previous values. QMatrix
       
   264     provide the translate(), rotate(), scale() and shear() convenience
       
   265     functions to manipulate the various matrix elements based on the
       
   266     currently defined coordinate system.
       
   267 
       
   268     \sa QMatrix()
       
   269 */
       
   270 
       
   271 void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
       
   272 {
       
   273     _m11 = m11;
       
   274     _m12 = m12;
       
   275     _m21 = m21;
       
   276     _m22 = m22;
       
   277     _dx  = dx;
       
   278     _dy  = dy;
       
   279 }
       
   280 
       
   281 
       
   282 /*!
       
   283     \fn qreal QMatrix::m11() const
       
   284 
       
   285     Returns the horizontal scaling factor.
       
   286 
       
   287     \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   288     Operations}
       
   289 */
       
   290 
       
   291 /*!
       
   292     \fn qreal QMatrix::m12() const
       
   293 
       
   294     Returns the vertical shearing factor.
       
   295 
       
   296     \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   297     Operations}
       
   298 */
       
   299 
       
   300 /*!
       
   301     \fn qreal QMatrix::m21() const
       
   302 
       
   303     Returns the horizontal shearing factor.
       
   304 
       
   305     \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   306     Operations}
       
   307 */
       
   308 
       
   309 /*!
       
   310     \fn qreal QMatrix::m22() const
       
   311 
       
   312     Returns the vertical scaling factor.
       
   313 
       
   314     \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   315     Operations}
       
   316 */
       
   317 
       
   318 /*!
       
   319     \fn qreal QMatrix::dx() const
       
   320 
       
   321     Returns the horizontal translation factor.
       
   322 
       
   323     \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   324     Operations}
       
   325 */
       
   326 
       
   327 /*!
       
   328     \fn qreal QMatrix::dy() const
       
   329 
       
   330     Returns the vertical translation factor.
       
   331 
       
   332     \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   333     Operations}
       
   334 */
       
   335 
       
   336 
       
   337 /*!
       
   338     Maps the given coordinates \a x and \a y into the coordinate
       
   339     system defined by this matrix. The resulting values are put in *\a
       
   340     tx and *\a ty, respectively.
       
   341 
       
   342     The coordinates are transformed using the following formulas:
       
   343 
       
   344     \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 1
       
   345 
       
   346     The point (x, y) is the original point, and (x', y') is the
       
   347     transformed point.
       
   348 
       
   349     \sa {QMatrix#Basic Matrix Operations}{Basic Matrix Operations}
       
   350 */
       
   351 
       
   352 void QMatrix::map(qreal x, qreal y, qreal *tx, qreal *ty) const
       
   353 {
       
   354     MAPDOUBLE(x, y, *tx, *ty);
       
   355 }
       
   356 
       
   357 
       
   358 
       
   359 /*!
       
   360     \overload
       
   361 
       
   362     Maps the given coordinates \a x and \a y into the coordinate
       
   363     system defined by this matrix. The resulting values are put in *\a
       
   364     tx and *\a ty, respectively. Note that the transformed coordinates
       
   365     are rounded to the nearest integer.
       
   366 */
       
   367 
       
   368 void QMatrix::map(int x, int y, int *tx, int *ty) const
       
   369 {
       
   370     MAPINT(x, y, *tx, *ty);
       
   371 }
       
   372 
       
   373 QRect QMatrix::mapRect(const QRect &rect) const
       
   374 {
       
   375     QRect result;
       
   376     if (_m12 == 0.0F && _m21 == 0.0F) {
       
   377         int x = qRound(_m11*rect.x() + _dx);
       
   378         int y = qRound(_m22*rect.y() + _dy);
       
   379         int w = qRound(_m11*rect.width());
       
   380         int h = qRound(_m22*rect.height());
       
   381         if (w < 0) {
       
   382             w = -w;
       
   383             x -= w;
       
   384         }
       
   385         if (h < 0) {
       
   386             h = -h;
       
   387             y -= h;
       
   388         }
       
   389         result = QRect(x, y, w, h);
       
   390     } else {
       
   391         // see mapToPolygon for explanations of the algorithm.
       
   392         qreal x0, y0;
       
   393         qreal x, y;
       
   394         MAPDOUBLE(rect.left(), rect.top(), x0, y0);
       
   395         qreal xmin = x0;
       
   396         qreal ymin = y0;
       
   397         qreal xmax = x0;
       
   398         qreal ymax = y0;
       
   399         MAPDOUBLE(rect.right() + 1, rect.top(), x, y);
       
   400         xmin = qMin(xmin, x);
       
   401         ymin = qMin(ymin, y);
       
   402         xmax = qMax(xmax, x);
       
   403         ymax = qMax(ymax, y);
       
   404         MAPDOUBLE(rect.right() + 1, rect.bottom() + 1, x, y);
       
   405         xmin = qMin(xmin, x);
       
   406         ymin = qMin(ymin, y);
       
   407         xmax = qMax(xmax, x);
       
   408         ymax = qMax(ymax, y);
       
   409         MAPDOUBLE(rect.left(), rect.bottom() + 1, x, y);
       
   410         xmin = qMin(xmin, x);
       
   411         ymin = qMin(ymin, y);
       
   412         xmax = qMax(xmax, x);
       
   413         ymax = qMax(ymax, y);
       
   414         result = QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
       
   415     }
       
   416     return result;
       
   417 }
       
   418 
       
   419 /*!
       
   420     \fn QRectF QMatrix::mapRect(const QRectF &rectangle) const
       
   421 
       
   422     Creates and returns a QRectF object that is a copy of the given \a
       
   423     rectangle, mapped into the coordinate system defined by this
       
   424     matrix.
       
   425 
       
   426     The rectangle's coordinates are transformed using the following
       
   427     formulas:
       
   428 
       
   429     \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 2
       
   430 
       
   431     If rotation or shearing has been specified, this function returns
       
   432     the \e bounding rectangle. To retrieve the exact region the given
       
   433     \a rectangle maps to, use the mapToPolygon() function instead.
       
   434 
       
   435     \sa mapToPolygon(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   436     Operations}
       
   437 */
       
   438 QRectF QMatrix::mapRect(const QRectF &rect) const
       
   439 {
       
   440     QRectF result;
       
   441     if (_m12 == 0.0F && _m21 == 0.0F) {
       
   442         qreal x = _m11*rect.x() + _dx;
       
   443         qreal y = _m22*rect.y() + _dy;
       
   444         qreal w = _m11*rect.width();
       
   445         qreal h = _m22*rect.height();
       
   446         if (w < 0) {
       
   447             w = -w;
       
   448             x -= w;
       
   449         }
       
   450         if (h < 0) {
       
   451             h = -h;
       
   452             y -= h;
       
   453         }
       
   454         result = QRectF(x, y, w, h);
       
   455     } else {
       
   456         qreal x0, y0;
       
   457         qreal x, y;
       
   458         MAPDOUBLE(rect.x(), rect.y(), x0, y0);
       
   459         qreal xmin = x0;
       
   460         qreal ymin = y0;
       
   461         qreal xmax = x0;
       
   462         qreal ymax = y0;
       
   463         MAPDOUBLE(rect.x() + rect.width(), rect.y(), x, y);
       
   464         xmin = qMin(xmin, x);
       
   465         ymin = qMin(ymin, y);
       
   466         xmax = qMax(xmax, x);
       
   467         ymax = qMax(ymax, y);
       
   468         MAPDOUBLE(rect.x() + rect.width(), rect.y() + rect.height(), x, y);
       
   469         xmin = qMin(xmin, x);
       
   470         ymin = qMin(ymin, y);
       
   471         xmax = qMax(xmax, x);
       
   472         ymax = qMax(ymax, y);
       
   473         MAPDOUBLE(rect.x(), rect.y() + rect.height(), x, y);
       
   474         xmin = qMin(xmin, x);
       
   475         ymin = qMin(ymin, y);
       
   476         xmax = qMax(xmax, x);
       
   477         ymax = qMax(ymax, y);
       
   478         result = QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
       
   479     }
       
   480     return result;
       
   481 }
       
   482 
       
   483 /*!
       
   484     \fn QRect QMatrix::mapRect(const QRect &rectangle) const
       
   485     \overload
       
   486 
       
   487     Creates and returns a QRect object that is a copy of the given \a
       
   488     rectangle, mapped into the coordinate system defined by this
       
   489     matrix. Note that the transformed coordinates are rounded to the
       
   490     nearest integer.
       
   491 */
       
   492 
       
   493 
       
   494 /*!
       
   495     \fn QPoint operator*(const QPoint &point, const QMatrix &matrix)
       
   496     \relates QMatrix
       
   497 
       
   498     This is the same as \a{matrix}.map(\a{point}).
       
   499 
       
   500     \sa QMatrix::map()
       
   501 */
       
   502 
       
   503 QPoint QMatrix::map(const QPoint &p) const
       
   504 {
       
   505     qreal fx = p.x();
       
   506     qreal fy = p.y();
       
   507     return QPoint(qRound(_m11*fx + _m21*fy + _dx),
       
   508                    qRound(_m12*fx + _m22*fy + _dy));
       
   509 }
       
   510 
       
   511 /*!
       
   512     \fn QPointF operator*(const QPointF &point, const QMatrix &matrix)
       
   513     \relates QMatrix
       
   514 
       
   515     Same as \a{matrix}.map(\a{point}).
       
   516 
       
   517     \sa QMatrix::map()
       
   518 */
       
   519 
       
   520 /*!
       
   521     \overload
       
   522 
       
   523     Creates and returns a QPointF object that is a copy of the given
       
   524     \a point, mapped into the coordinate system defined by this
       
   525     matrix.
       
   526 */
       
   527 QPointF QMatrix::map(const QPointF &point) const
       
   528 {
       
   529     qreal fx = point.x();
       
   530     qreal fy = point.y();
       
   531     return QPointF(_m11*fx + _m21*fy + _dx, _m12*fx + _m22*fy + _dy);
       
   532 }
       
   533 
       
   534 /*!
       
   535     \fn QPoint QMatrix::map(const QPoint &point) const
       
   536     \overload
       
   537 
       
   538     Creates and returns a QPoint object that is a copy of the given \a
       
   539     point, mapped into the coordinate system defined by this
       
   540     matrix. Note that the transformed coordinates are rounded to the
       
   541     nearest integer.
       
   542 */
       
   543 
       
   544 /*!
       
   545     \fn QLineF operator*(const QLineF &line, const QMatrix &matrix)
       
   546     \relates QMatrix
       
   547 
       
   548     This is the same as \a{matrix}.map(\a{line}).
       
   549 
       
   550     \sa QMatrix::map()
       
   551 */
       
   552 
       
   553 /*!
       
   554     \fn QLine operator*(const QLine &line, const QMatrix &matrix)
       
   555     \relates QMatrix
       
   556 
       
   557     This is the same as \a{matrix}.map(\a{line}).
       
   558 
       
   559     \sa QMatrix::map()
       
   560 */
       
   561 
       
   562 /*!
       
   563     \overload
       
   564 
       
   565     Creates and returns a QLineF object that is a copy of the given \a
       
   566     line, mapped into the coordinate system defined by this matrix.
       
   567 */
       
   568 QLineF QMatrix::map(const QLineF &line) const
       
   569 {
       
   570     return QLineF(map(line.p1()), map(line.p2()));
       
   571 }
       
   572 
       
   573 /*!
       
   574     \overload
       
   575 
       
   576     Creates and returns a QLine object that is a copy of the given \a
       
   577     line, mapped into the coordinate system defined by this matrix.
       
   578     Note that the transformed coordinates are rounded to the nearest
       
   579     integer.
       
   580 */
       
   581 QLine QMatrix::map(const QLine &line) const
       
   582 {
       
   583     return QLine(map(line.p1()), map(line.p2()));
       
   584 }
       
   585 
       
   586 /*!
       
   587     \fn QPolygonF operator *(const QPolygonF &polygon, const QMatrix &matrix)
       
   588     \relates QMatrix
       
   589 
       
   590     This is the same as \a{matrix}.map(\a{polygon}).
       
   591 
       
   592     \sa QMatrix::map()
       
   593 */
       
   594 
       
   595 /*!
       
   596     \fn QPolygon operator*(const QPolygon &polygon, const QMatrix &matrix)
       
   597     \relates QMatrix
       
   598 
       
   599     This is the same as \a{matrix}.map(\a{polygon}).
       
   600 
       
   601     \sa QMatrix::map()
       
   602 */
       
   603 
       
   604 QPolygon QMatrix::map(const QPolygon &a) const
       
   605 {
       
   606     int size = a.size();
       
   607     int i;
       
   608     QPolygon p(size);
       
   609     const QPoint *da = a.constData();
       
   610     QPoint *dp = p.data();
       
   611     for(i = 0; i < size; i++) {
       
   612         MAPINT(da[i].x(), da[i].y(), dp[i].rx(), dp[i].ry());
       
   613     }
       
   614     return p;
       
   615 }
       
   616 
       
   617 /*!
       
   618     \fn QPolygonF QMatrix::map(const QPolygonF &polygon) const
       
   619     \overload
       
   620 
       
   621     Creates and returns a QPolygonF object that is a copy of the given
       
   622     \a polygon, mapped into the coordinate system defined by this
       
   623     matrix.
       
   624 */
       
   625 QPolygonF QMatrix::map(const QPolygonF &a) const
       
   626 {
       
   627     int size = a.size();
       
   628     int i;
       
   629     QPolygonF p(size);
       
   630     const QPointF *da = a.constData();
       
   631     QPointF *dp = p.data();
       
   632     for(i = 0; i < size; i++) {
       
   633         MAPDOUBLE(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
       
   634     }
       
   635     return p;
       
   636 }
       
   637 
       
   638 /*!
       
   639     \fn QPolygon QMatrix::map(const QPolygon &polygon) const
       
   640     \overload
       
   641 
       
   642     Creates and returns a QPolygon object that is a copy of the given
       
   643     \a polygon, mapped into the coordinate system defined by this
       
   644     matrix. Note that the transformed coordinates are rounded to the
       
   645     nearest integer.
       
   646 */
       
   647 
       
   648 /*!
       
   649     \fn QRegion operator*(const QRegion &region, const QMatrix &matrix)
       
   650     \relates QMatrix
       
   651 
       
   652     This is the same as \a{matrix}.map(\a{region}).
       
   653 
       
   654     \sa QMatrix::map()
       
   655 */
       
   656 
       
   657 extern QPainterPath qt_regionToPath(const QRegion &region);
       
   658 
       
   659 /*!
       
   660     \fn QRegion QMatrix::map(const QRegion &region) const
       
   661     \overload
       
   662 
       
   663     Creates and returns a QRegion object that is a copy of the given
       
   664     \a region, mapped into the coordinate system defined by this matrix.
       
   665 
       
   666     Calling this method can be rather expensive if rotations or
       
   667     shearing are used.
       
   668 */
       
   669 QRegion QMatrix::map(const QRegion &r) const
       
   670 {
       
   671     if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) { // translate or identity
       
   672         if (_dx == 0.0 && _dy == 0.0) // Identity
       
   673             return r;
       
   674         QRegion copy(r);
       
   675         copy.translate(qRound(_dx), qRound(_dy));
       
   676         return copy;
       
   677     }
       
   678 
       
   679     QPainterPath p = map(qt_regionToPath(r));
       
   680     return p.toFillPolygon().toPolygon();
       
   681 }
       
   682 
       
   683 /*!
       
   684     \fn QPainterPath operator *(const QPainterPath &path, const QMatrix &matrix)
       
   685     \relates QMatrix
       
   686 
       
   687     This is the same as \a{matrix}.map(\a{path}).
       
   688 
       
   689     \sa QMatrix::map()
       
   690 */
       
   691 
       
   692 /*!
       
   693     \overload
       
   694 
       
   695     Creates and returns a QPainterPath object that is a copy of the
       
   696     given \a path, mapped into the coordinate system defined by this
       
   697     matrix.
       
   698 */
       
   699 QPainterPath QMatrix::map(const QPainterPath &path) const
       
   700 {
       
   701     if (path.isEmpty())
       
   702         return QPainterPath();
       
   703 
       
   704     QPainterPath copy = path;
       
   705 
       
   706     // Translate or identity
       
   707     if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) {
       
   708 
       
   709         // Translate
       
   710         if (_dx != 0.0 || _dy != 0.0) {
       
   711             copy.detach();
       
   712             for (int i=0; i<path.elementCount(); ++i) {
       
   713                 QPainterPath::Element &e = copy.d_ptr->elements[i];
       
   714                 e.x += _dx;
       
   715                 e.y += _dy;
       
   716             }
       
   717         }
       
   718 
       
   719     // Full xform
       
   720     } else {
       
   721         copy.detach();
       
   722         for (int i=0; i<path.elementCount(); ++i) {
       
   723             QPainterPath::Element &e = copy.d_ptr->elements[i];
       
   724             qreal fx = e.x, fy = e.y;
       
   725             e.x = _m11*fx + _m21*fy + _dx;
       
   726             e.y =  _m12*fx + _m22*fy + _dy;
       
   727         }
       
   728     }
       
   729 
       
   730     return copy;
       
   731 }
       
   732 
       
   733 /*!
       
   734     \fn QRegion QMatrix::mapToRegion(const QRect &rectangle) const
       
   735 
       
   736     Returns the transformed rectangle \a rectangle as a QRegion
       
   737     object. A rectangle which has been rotated or sheared may result
       
   738     in a non-rectangular region being returned.
       
   739 
       
   740     Use the mapToPolygon() or map() function instead.
       
   741 */
       
   742 #ifdef QT3_SUPPORT
       
   743 QRegion QMatrix::mapToRegion(const QRect &rect) const
       
   744 {
       
   745     QRegion result;
       
   746     if (isIdentity()) {
       
   747         result = rect;
       
   748     } else if (m12() == 0.0F && m21() == 0.0F) {
       
   749         int x = qRound(m11()*rect.x() + dx());
       
   750         int y = qRound(m22()*rect.y() + dy());
       
   751         int w = qRound(m11()*rect.width());
       
   752         int h = qRound(m22()*rect.height());
       
   753         if (w < 0) {
       
   754             w = -w;
       
   755             x -= w - 1;
       
   756         }
       
   757         if (h < 0) {
       
   758             h = -h;
       
   759             y -= h - 1;
       
   760         }
       
   761         result = QRect(x, y, w, h);
       
   762     } else {
       
   763         result = QRegion(mapToPolygon(rect));
       
   764     }
       
   765     return result;
       
   766 
       
   767 }
       
   768 #endif
       
   769 /*!
       
   770     \fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const
       
   771 
       
   772     Creates and returns a QPolygon representation of the given \a
       
   773     rectangle, mapped into the coordinate system defined by this
       
   774     matrix.
       
   775 
       
   776     The rectangle's coordinates are transformed using the following
       
   777     formulas:
       
   778 
       
   779     \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 3
       
   780 
       
   781     Polygons and rectangles behave slightly differently when
       
   782     transformed (due to integer rounding), so
       
   783     \c{matrix.map(QPolygon(rectangle))} is not always the same as
       
   784     \c{matrix.mapToPolygon(rectangle)}.
       
   785 
       
   786     \sa mapRect(), {QMatrix#Basic Matrix Operations}{Basic Matrix
       
   787     Operations}
       
   788 */
       
   789 QPolygon QMatrix::mapToPolygon(const QRect &rect) const
       
   790 {
       
   791     QPolygon a(4);
       
   792     qreal x[4], y[4];
       
   793     if (_m12 == 0.0F && _m21 == 0.0F) {
       
   794         x[0] = _m11*rect.x() + _dx;
       
   795         y[0] = _m22*rect.y() + _dy;
       
   796         qreal w = _m11*rect.width();
       
   797         qreal h = _m22*rect.height();
       
   798         if (w < 0) {
       
   799             w = -w;
       
   800             x[0] -= w;
       
   801         }
       
   802         if (h < 0) {
       
   803             h = -h;
       
   804             y[0] -= h;
       
   805         }
       
   806         x[1] = x[0]+w;
       
   807         x[2] = x[1];
       
   808         x[3] = x[0];
       
   809         y[1] = y[0];
       
   810         y[2] = y[0]+h;
       
   811         y[3] = y[2];
       
   812     } else {
       
   813         qreal right = rect.x() + rect.width();
       
   814         qreal bottom = rect.y() + rect.height();
       
   815         MAPDOUBLE(rect.x(), rect.y(), x[0], y[0]);
       
   816         MAPDOUBLE(right, rect.y(), x[1], y[1]);
       
   817         MAPDOUBLE(right, bottom, x[2], y[2]);
       
   818         MAPDOUBLE(rect.x(), bottom, x[3], y[3]);
       
   819     }
       
   820 #if 0
       
   821     int i;
       
   822     for(i = 0; i< 4; i++)
       
   823         qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], qRound(x[i]), qRound(y[i]));
       
   824     qDebug("width=%f, height=%f", qSqrt((x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0])),
       
   825             qSqrt((x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3])));
       
   826 #endif
       
   827     // all coordinates are correctly, tranform to a pointarray
       
   828     // (rounding to the next integer)
       
   829     a.setPoints(4, qRound(x[0]), qRound(y[0]),
       
   830                  qRound(x[1]), qRound(y[1]),
       
   831                  qRound(x[2]), qRound(y[2]),
       
   832                  qRound(x[3]), qRound(y[3]));
       
   833     return a;
       
   834 }
       
   835 
       
   836 /*!
       
   837     Resets the matrix to an identity matrix, i.e. all elements are set
       
   838     to zero, except \c m11 and \c m22 (specifying the scale) which are
       
   839     set to 1.
       
   840 
       
   841     \sa QMatrix(), isIdentity(), {QMatrix#Basic Matrix
       
   842     Operations}{Basic Matrix Operations}
       
   843 */
       
   844 
       
   845 void QMatrix::reset()
       
   846 {
       
   847     _m11 = _m22 = 1.0;
       
   848     _m12 = _m21 = _dx = _dy = 0.0;
       
   849 }
       
   850 
       
   851 /*!
       
   852     \fn bool QMatrix::isIdentity() const
       
   853 
       
   854     Returns true if the matrix is the identity matrix, otherwise
       
   855     returns false.
       
   856 
       
   857     \sa reset()
       
   858 */
       
   859 
       
   860 /*!
       
   861     Moves the coordinate system \a dx along the x axis and \a dy along
       
   862     the y axis, and returns a reference to the matrix.
       
   863 
       
   864     \sa setMatrix()
       
   865 */
       
   866 
       
   867 QMatrix &QMatrix::translate(qreal dx, qreal dy)
       
   868 {
       
   869     _dx += dx*_m11 + dy*_m21;
       
   870     _dy += dy*_m22 + dx*_m12;
       
   871     return *this;
       
   872 }
       
   873 
       
   874 /*!
       
   875     \fn QMatrix &QMatrix::scale(qreal sx, qreal sy)
       
   876 
       
   877     Scales the coordinate system by \a sx horizontally and \a sy
       
   878     vertically, and returns a reference to the matrix.
       
   879 
       
   880     \sa setMatrix()
       
   881 */
       
   882 
       
   883 QMatrix &QMatrix::scale(qreal sx, qreal sy)
       
   884 {
       
   885     _m11 *= sx;
       
   886     _m12 *= sx;
       
   887     _m21 *= sy;
       
   888     _m22 *= sy;
       
   889     return *this;
       
   890 }
       
   891 
       
   892 /*!
       
   893     Shears the coordinate system by \a sh horizontally and \a sv
       
   894     vertically, and returns a reference to the matrix.
       
   895 
       
   896     \sa setMatrix()
       
   897 */
       
   898 
       
   899 QMatrix &QMatrix::shear(qreal sh, qreal sv)
       
   900 {
       
   901     qreal tm11 = sv*_m21;
       
   902     qreal tm12 = sv*_m22;
       
   903     qreal tm21 = sh*_m11;
       
   904     qreal tm22 = sh*_m12;
       
   905     _m11 += tm11;
       
   906     _m12 += tm12;
       
   907     _m21 += tm21;
       
   908     _m22 += tm22;
       
   909     return *this;
       
   910 }
       
   911 
       
   912 const qreal deg2rad = qreal(0.017453292519943295769);        // pi/180
       
   913 
       
   914 /*!
       
   915     \fn QMatrix &QMatrix::rotate(qreal degrees)
       
   916 
       
   917     Rotates the coordinate system the given \a degrees
       
   918     counterclockwise.
       
   919 
       
   920     Note that if you apply a QMatrix to a point defined in widget
       
   921     coordinates, the direction of the rotation will be clockwise
       
   922     because the y-axis points downwards.
       
   923 
       
   924     Returns a reference to the matrix.
       
   925 
       
   926     \sa setMatrix()
       
   927 */
       
   928 
       
   929 QMatrix &QMatrix::rotate(qreal a)
       
   930 {
       
   931     qreal sina = 0;
       
   932     qreal cosa = 0;
       
   933     if (a == 90. || a == -270.)
       
   934         sina = 1.;
       
   935     else if (a == 270. || a == -90.)
       
   936         sina = -1.;
       
   937     else if (a == 180.)
       
   938         cosa = -1.;
       
   939     else{
       
   940         qreal b = deg2rad*a;                        // convert to radians
       
   941         sina = qSin(b);               // fast and convenient
       
   942         cosa = qCos(b);
       
   943     }
       
   944     qreal tm11 = cosa*_m11 + sina*_m21;
       
   945     qreal tm12 = cosa*_m12 + sina*_m22;
       
   946     qreal tm21 = -sina*_m11 + cosa*_m21;
       
   947     qreal tm22 = -sina*_m12 + cosa*_m22;
       
   948     _m11 = tm11; _m12 = tm12;
       
   949     _m21 = tm21; _m22 = tm22;
       
   950     return *this;
       
   951 }
       
   952 
       
   953 /*!
       
   954     \fn bool QMatrix::isInvertible() const
       
   955 
       
   956     Returns true if the matrix is invertible, otherwise returns false.
       
   957 
       
   958     \sa inverted()
       
   959 */
       
   960 
       
   961 /*!
       
   962     \fn qreal QMatrix::det() const
       
   963 
       
   964     Returns the matrix's determinant.
       
   965 */
       
   966 
       
   967 /*!
       
   968     \fn QMatrix QMatrix::invert(bool *invertible) const
       
   969 
       
   970     Returns an inverted copy of this matrix.
       
   971 
       
   972     Use the inverted() function instead.
       
   973 */
       
   974 
       
   975 /*!
       
   976     Returns an inverted copy of this matrix.
       
   977 
       
   978     If the matrix is singular (not invertible), the returned matrix is
       
   979     the identity matrix. If \a invertible is valid (i.e. not 0), its
       
   980     value is set to true if the matrix is invertible, otherwise it is
       
   981     set to false.
       
   982 
       
   983     \sa isInvertible()
       
   984 */
       
   985 
       
   986 QMatrix QMatrix::inverted(bool *invertible) const
       
   987 {
       
   988     qreal determinant = det();
       
   989     if (determinant == 0.0) {
       
   990         if (invertible)
       
   991             *invertible = false;                // singular matrix
       
   992         return QMatrix(true);
       
   993     }
       
   994     else {                                        // invertible matrix
       
   995         if (invertible)
       
   996             *invertible = true;
       
   997         qreal dinv = 1.0/determinant;
       
   998         return QMatrix((_m22*dinv),        (-_m12*dinv),
       
   999                        (-_m21*dinv), (_m11*dinv),
       
  1000                        ((_m21*_dy - _m22*_dx)*dinv),
       
  1001                        ((_m12*_dx - _m11*_dy)*dinv),
       
  1002                        true);
       
  1003     }
       
  1004 }
       
  1005 
       
  1006 
       
  1007 /*!
       
  1008     \fn bool QMatrix::operator==(const QMatrix &matrix) const
       
  1009 
       
  1010     Returns true if this matrix is equal to the given \a matrix,
       
  1011     otherwise returns false.
       
  1012 */
       
  1013 
       
  1014 bool QMatrix::operator==(const QMatrix &m) const
       
  1015 {
       
  1016     return _m11 == m._m11 &&
       
  1017            _m12 == m._m12 &&
       
  1018            _m21 == m._m21 &&
       
  1019            _m22 == m._m22 &&
       
  1020            _dx == m._dx &&
       
  1021            _dy == m._dy;
       
  1022 }
       
  1023 
       
  1024 /*!
       
  1025     \fn bool QMatrix::operator!=(const QMatrix &matrix) const
       
  1026 
       
  1027     Returns true if this matrix is not equal to the given \a matrix,
       
  1028     otherwise returns false.
       
  1029 */
       
  1030 
       
  1031 bool QMatrix::operator!=(const QMatrix &m) const
       
  1032 {
       
  1033     return _m11 != m._m11 ||
       
  1034            _m12 != m._m12 ||
       
  1035            _m21 != m._m21 ||
       
  1036            _m22 != m._m22 ||
       
  1037            _dx != m._dx ||
       
  1038            _dy != m._dy;
       
  1039 }
       
  1040 
       
  1041 /*!
       
  1042     \fn QMatrix &QMatrix::operator *=(const QMatrix &matrix)
       
  1043     \overload
       
  1044 
       
  1045     Returns the result of multiplying this matrix by the given \a
       
  1046     matrix.
       
  1047 */
       
  1048 
       
  1049 QMatrix &QMatrix::operator *=(const QMatrix &m)
       
  1050 {
       
  1051     qreal tm11 = _m11*m._m11 + _m12*m._m21;
       
  1052     qreal tm12 = _m11*m._m12 + _m12*m._m22;
       
  1053     qreal tm21 = _m21*m._m11 + _m22*m._m21;
       
  1054     qreal tm22 = _m21*m._m12 + _m22*m._m22;
       
  1055 
       
  1056     qreal tdx  = _dx*m._m11  + _dy*m._m21 + m._dx;
       
  1057     qreal tdy =  _dx*m._m12  + _dy*m._m22 + m._dy;
       
  1058 
       
  1059     _m11 = tm11; _m12 = tm12;
       
  1060     _m21 = tm21; _m22 = tm22;
       
  1061     _dx = tdx; _dy = tdy;
       
  1062     return *this;
       
  1063 }
       
  1064 
       
  1065 /*!
       
  1066     \fn QMatrix QMatrix::operator *(const QMatrix &matrix) const
       
  1067 
       
  1068     Returns the result of multiplying this matrix by the given \a
       
  1069     matrix.
       
  1070 
       
  1071     Note that matrix multiplication is not commutative, i.e. a*b !=
       
  1072     b*a.
       
  1073 */
       
  1074 
       
  1075 QMatrix QMatrix::operator *(const QMatrix &m) const
       
  1076 {
       
  1077     qreal tm11 = _m11*m._m11 + _m12*m._m21;
       
  1078     qreal tm12 = _m11*m._m12 + _m12*m._m22;
       
  1079     qreal tm21 = _m21*m._m11 + _m22*m._m21;
       
  1080     qreal tm22 = _m21*m._m12 + _m22*m._m22;
       
  1081 
       
  1082     qreal tdx  = _dx*m._m11  + _dy*m._m21 + m._dx;
       
  1083     qreal tdy =  _dx*m._m12  + _dy*m._m22 + m._dy;
       
  1084     return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true);
       
  1085 }
       
  1086 
       
  1087 /*!
       
  1088     Assigns the given \a matrix's values to this matrix.
       
  1089 */
       
  1090 QMatrix &QMatrix::operator=(const QMatrix &matrix)
       
  1091 {
       
  1092     _m11 = matrix._m11;
       
  1093     _m12 = matrix._m12;
       
  1094     _m21 = matrix._m21;
       
  1095     _m22 = matrix._m22;
       
  1096     _dx  = matrix._dx;
       
  1097     _dy  = matrix._dy;
       
  1098     return *this;
       
  1099 }
       
  1100 
       
  1101 /*!
       
  1102     \since 4.2
       
  1103 
       
  1104     Returns the matrix as a QVariant.
       
  1105 */
       
  1106 QMatrix::operator QVariant() const
       
  1107 {
       
  1108     return QVariant(QVariant::Matrix, this);
       
  1109 }
       
  1110 
       
  1111 Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m)
       
  1112 {
       
  1113     return m.map(p);
       
  1114 }
       
  1115 
       
  1116 
       
  1117 /*****************************************************************************
       
  1118   QMatrix stream functions
       
  1119  *****************************************************************************/
       
  1120 #ifndef QT_NO_DATASTREAM
       
  1121 /*!
       
  1122     \fn QDataStream &operator<<(QDataStream &stream, const QMatrix &matrix)
       
  1123     \relates QMatrix
       
  1124 
       
  1125     Writes the given \a matrix to the given \a stream and returns a
       
  1126     reference to the stream.
       
  1127 
       
  1128     \sa {Format of the QDataStream Operators}
       
  1129 */
       
  1130 
       
  1131 QDataStream &operator<<(QDataStream &s, const QMatrix &m)
       
  1132 {
       
  1133     if (s.version() == 1) {
       
  1134         s << (float)m.m11() << (float)m.m12() << (float)m.m21()
       
  1135           << (float)m.m22() << (float)m.dx()  << (float)m.dy();
       
  1136     } else {
       
  1137         s << double(m.m11())
       
  1138           << double(m.m12())
       
  1139           << double(m.m21())
       
  1140           << double(m.m22())
       
  1141           << double(m.dx())
       
  1142           << double(m.dy());
       
  1143     }
       
  1144     return s;
       
  1145 }
       
  1146 
       
  1147 /*!
       
  1148     \fn QDataStream &operator>>(QDataStream &stream, QMatrix &matrix)
       
  1149     \relates QMatrix
       
  1150 
       
  1151     Reads the given \a matrix from the given \a stream and returns a
       
  1152     reference to the stream.
       
  1153 
       
  1154     \sa {Format of the QDataStream Operators}
       
  1155 */
       
  1156 
       
  1157 QDataStream &operator>>(QDataStream &s, QMatrix &m)
       
  1158 {
       
  1159     if (s.version() == 1) {
       
  1160         float m11, m12, m21, m22, dx, dy;
       
  1161         s >> m11;  s >> m12;  s >> m21;  s >> m22;
       
  1162         s >> dx;   s >> dy;
       
  1163         m.setMatrix(m11, m12, m21, m22, dx, dy);
       
  1164     }
       
  1165     else {
       
  1166         double m11, m12, m21, m22, dx, dy;
       
  1167         s >> m11;
       
  1168         s >> m12;
       
  1169         s >> m21;
       
  1170         s >> m22;
       
  1171         s >> dx;
       
  1172         s >> dy;
       
  1173         m.setMatrix(m11, m12, m21, m22, dx, dy);
       
  1174     }
       
  1175     return s;
       
  1176 }
       
  1177 #endif // QT_NO_DATASTREAM
       
  1178 
       
  1179 #ifndef QT_NO_DEBUG_STREAM
       
  1180 QDebug operator<<(QDebug dbg, const QMatrix &m)
       
  1181 {
       
  1182     dbg.nospace() << "QMatrix("
       
  1183                   << "11=" << m.m11()
       
  1184                   << " 12=" << m.m12()
       
  1185                   << " 21=" << m.m21()
       
  1186                   << " 22=" << m.m22()
       
  1187                   << " dx=" << m.dx()
       
  1188                   << " dy=" << m.dy()
       
  1189                   << ')';
       
  1190     return dbg.space();
       
  1191 }
       
  1192 #endif
       
  1193 
       
  1194 /*!
       
  1195     \fn QRect QMatrix::map(const QRect &rect) const
       
  1196     \compat
       
  1197 
       
  1198     Creates and returns a QRect object that is a copy of the given
       
  1199     rectangle, mapped into the coordinate system defined by this
       
  1200     matrix.
       
  1201 
       
  1202     Use the mapRect() function instead.
       
  1203 */
       
  1204 
       
  1205 
       
  1206 /*!
       
  1207     \fn bool qFuzzyCompare(const QMatrix& m1, const QMatrix& m2)
       
  1208 
       
  1209     \relates QMatrix
       
  1210     \since 4.6
       
  1211 
       
  1212     \brief The qFuzzyCompare function is for comparing two matrices
       
  1213     using a fuzziness factor.
       
  1214     
       
  1215     Returns true if \a m1 and \a m2 are equal, allowing for a small
       
  1216     fuzziness factor for floating-point comparisons; false otherwise.
       
  1217 */
       
  1218 
       
  1219 QT_END_NAMESPACE