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