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