Replace 'i < len-1 && func(i+1)' by 'i+1 < len && func(i+1)'
[profile/ivi/qtbase.git] / src / gui / painting / qmatrix.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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 determinant() 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 {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, {Coordinate System}, 
180     {painting/affine}{Affine Transformations Example}, {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     \obsolete
963     \fn qreal QMatrix::det() const
964
965     Returns the matrix's determinant.
966
967     \sa determinant()
968 */
969
970 /*!
971     \since 4.6
972     \fn qreal QMatrix::determinant() const
973
974     Returns the matrix's determinant.
975 */
976
977 /*!
978     \fn QMatrix QMatrix::invert(bool *invertible) const
979
980     Returns an inverted copy of this matrix.
981
982     Use the inverted() function instead.
983 */
984
985 /*!
986     Returns an inverted copy of this matrix.
987
988     If the matrix is singular (not invertible), the returned matrix is
989     the identity matrix. If \a invertible is valid (i.e. not 0), its
990     value is set to true if the matrix is invertible, otherwise it is
991     set to false.
992
993     \sa isInvertible()
994 */
995
996 QMatrix QMatrix::inverted(bool *invertible) const
997 {
998     qreal dtr = determinant();
999     if (dtr == 0.0) {
1000         if (invertible)
1001             *invertible = false;                // singular matrix
1002         return QMatrix(true);
1003     }
1004     else {                                        // invertible matrix
1005         if (invertible)
1006             *invertible = true;
1007         qreal dinv = 1.0/dtr;
1008         return QMatrix((_m22*dinv),        (-_m12*dinv),
1009                        (-_m21*dinv), (_m11*dinv),
1010                        ((_m21*_dy - _m22*_dx)*dinv),
1011                        ((_m12*_dx - _m11*_dy)*dinv),
1012                        true);
1013     }
1014 }
1015
1016
1017 /*!
1018     \fn bool QMatrix::operator==(const QMatrix &matrix) const
1019
1020     Returns true if this matrix is equal to the given \a matrix,
1021     otherwise returns false.
1022 */
1023
1024 bool QMatrix::operator==(const QMatrix &m) const
1025 {
1026     return _m11 == m._m11 &&
1027            _m12 == m._m12 &&
1028            _m21 == m._m21 &&
1029            _m22 == m._m22 &&
1030            _dx == m._dx &&
1031            _dy == m._dy;
1032 }
1033
1034 /*!
1035     \fn bool QMatrix::operator!=(const QMatrix &matrix) const
1036
1037     Returns true if this matrix is not equal to the given \a matrix,
1038     otherwise returns false.
1039 */
1040
1041 bool QMatrix::operator!=(const QMatrix &m) const
1042 {
1043     return _m11 != m._m11 ||
1044            _m12 != m._m12 ||
1045            _m21 != m._m21 ||
1046            _m22 != m._m22 ||
1047            _dx != m._dx ||
1048            _dy != m._dy;
1049 }
1050
1051 /*!
1052     \fn QMatrix &QMatrix::operator *=(const QMatrix &matrix)
1053     \overload
1054
1055     Returns the result of multiplying this matrix by the given \a
1056     matrix.
1057 */
1058
1059 QMatrix &QMatrix::operator *=(const QMatrix &m)
1060 {
1061     qreal tm11 = _m11*m._m11 + _m12*m._m21;
1062     qreal tm12 = _m11*m._m12 + _m12*m._m22;
1063     qreal tm21 = _m21*m._m11 + _m22*m._m21;
1064     qreal tm22 = _m21*m._m12 + _m22*m._m22;
1065
1066     qreal tdx  = _dx*m._m11  + _dy*m._m21 + m._dx;
1067     qreal tdy =  _dx*m._m12  + _dy*m._m22 + m._dy;
1068
1069     _m11 = tm11; _m12 = tm12;
1070     _m21 = tm21; _m22 = tm22;
1071     _dx = tdx; _dy = tdy;
1072     return *this;
1073 }
1074
1075 /*!
1076     \fn QMatrix QMatrix::operator *(const QMatrix &matrix) const
1077
1078     Returns the result of multiplying this matrix by the given \a
1079     matrix.
1080
1081     Note that matrix multiplication is not commutative, i.e. a*b !=
1082     b*a.
1083 */
1084
1085 QMatrix QMatrix::operator *(const QMatrix &m) const
1086 {
1087     qreal tm11 = _m11*m._m11 + _m12*m._m21;
1088     qreal tm12 = _m11*m._m12 + _m12*m._m22;
1089     qreal tm21 = _m21*m._m11 + _m22*m._m21;
1090     qreal tm22 = _m21*m._m12 + _m22*m._m22;
1091
1092     qreal tdx  = _dx*m._m11  + _dy*m._m21 + m._dx;
1093     qreal tdy =  _dx*m._m12  + _dy*m._m22 + m._dy;
1094     return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true);
1095 }
1096
1097 /*!
1098     Assigns the given \a matrix's values to this matrix.
1099 */
1100 QMatrix &QMatrix::operator=(const QMatrix &matrix)
1101 {
1102     _m11 = matrix._m11;
1103     _m12 = matrix._m12;
1104     _m21 = matrix._m21;
1105     _m22 = matrix._m22;
1106     _dx  = matrix._dx;
1107     _dy  = matrix._dy;
1108     return *this;
1109 }
1110
1111 /*!
1112     \since 4.2
1113
1114     Returns the matrix as a QVariant.
1115 */
1116 QMatrix::operator QVariant() const
1117 {
1118     return QVariant(QVariant::Matrix, this);
1119 }
1120
1121 Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m)
1122 {
1123     return m.map(p);
1124 }
1125
1126
1127 /*****************************************************************************
1128   QMatrix stream functions
1129  *****************************************************************************/
1130 #ifndef QT_NO_DATASTREAM
1131 /*!
1132     \fn QDataStream &operator<<(QDataStream &stream, const QMatrix &matrix)
1133     \relates QMatrix
1134
1135     Writes the given \a matrix to the given \a stream and returns a
1136     reference to the stream.
1137
1138     \sa {Serializing Qt Data Types}
1139 */
1140
1141 QDataStream &operator<<(QDataStream &s, const QMatrix &m)
1142 {
1143     if (s.version() == 1) {
1144         s << (float)m.m11() << (float)m.m12() << (float)m.m21()
1145           << (float)m.m22() << (float)m.dx()  << (float)m.dy();
1146     } else {
1147         s << double(m.m11())
1148           << double(m.m12())
1149           << double(m.m21())
1150           << double(m.m22())
1151           << double(m.dx())
1152           << double(m.dy());
1153     }
1154     return s;
1155 }
1156
1157 /*!
1158     \fn QDataStream &operator>>(QDataStream &stream, QMatrix &matrix)
1159     \relates QMatrix
1160
1161     Reads the given \a matrix from the given \a stream and returns a
1162     reference to the stream.
1163
1164     \sa {Serializing Qt Data Types}
1165 */
1166
1167 QDataStream &operator>>(QDataStream &s, QMatrix &m)
1168 {
1169     if (s.version() == 1) {
1170         float m11, m12, m21, m22, dx, dy;
1171         s >> m11;  s >> m12;  s >> m21;  s >> m22;
1172         s >> dx;   s >> dy;
1173         m.setMatrix(m11, m12, m21, m22, dx, dy);
1174     }
1175     else {
1176         double m11, m12, m21, m22, dx, dy;
1177         s >> m11;
1178         s >> m12;
1179         s >> m21;
1180         s >> m22;
1181         s >> dx;
1182         s >> dy;
1183         m.setMatrix(m11, m12, m21, m22, dx, dy);
1184     }
1185     return s;
1186 }
1187 #endif // QT_NO_DATASTREAM
1188
1189 #ifndef QT_NO_DEBUG_STREAM
1190 QDebug operator<<(QDebug dbg, const QMatrix &m)
1191 {
1192     dbg.nospace() << "QMatrix("
1193                   << "11=" << m.m11()
1194                   << " 12=" << m.m12()
1195                   << " 21=" << m.m21()
1196                   << " 22=" << m.m22()
1197                   << " dx=" << m.dx()
1198                   << " dy=" << m.dy()
1199                   << ')';
1200     return dbg.space();
1201 }
1202 #endif
1203
1204 /*!
1205     \fn QRect QMatrix::map(const QRect &rect) const
1206     \compat
1207
1208     Creates and returns a QRect object that is a copy of the given
1209     rectangle, mapped into the coordinate system defined by this
1210     matrix.
1211
1212     Use the mapRect() function instead.
1213 */
1214
1215
1216 /*!
1217     \fn bool qFuzzyCompare(const QMatrix& m1, const QMatrix& m2)
1218
1219     \relates QMatrix
1220     \since 4.6
1221
1222     \brief The qFuzzyCompare function is for comparing two matrices
1223     using a fuzziness factor.
1224     
1225     Returns true if \a m1 and \a m2 are equal, allowing for a small
1226     fuzziness factor for floating-point comparisons; false otherwise.
1227 */
1228
1229 QT_END_NAMESPACE