src/gui/painting/qtransform.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
--- a/src/gui/painting/qtransform.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/painting/qtransform.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -47,6 +47,7 @@
 #include "qpainterpath.h"
 #include "qvariant.h"
 #include <qmath.h>
+#include <qnumeric.h>
 
 #include <private/qbezier_p.h>
 
@@ -410,6 +411,12 @@
 {
     if (dx == 0 && dy == 0)
         return *this;
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(dx) | qIsNaN(dy)) {
+        qWarning() << "QTransform::translate with NaN called";
+        return *this;
+    }
+#endif
 
     switch(inline_type()) {
     case TxNone:
@@ -447,6 +454,12 @@
 */
 QTransform QTransform::fromTranslate(qreal dx, qreal dy)
 {
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(dx) | qIsNaN(dy)) {
+        qWarning() << "QTransform::fromTranslate with NaN called";
+        return QTransform();
+}
+#endif
     QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true);
     if (dx == 0 && dy == 0)
         transform.m_type = TxNone;
@@ -466,6 +479,12 @@
 {
     if (sx == 1 && sy == 1)
         return *this;
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(sx) | qIsNaN(sy)) {
+        qWarning() << "QTransform::scale with NaN called";
+        return *this;
+    }
+#endif
 
     switch(inline_type()) {
     case TxNone:
@@ -501,6 +520,12 @@
 */
 QTransform QTransform::fromScale(qreal sx, qreal sy)
 {
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(sx) | qIsNaN(sy)) {
+        qWarning() << "QTransform::fromScale with NaN called";
+        return QTransform();
+}
+#endif
     QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true);
     if (sx == 1. && sy == 1.)
         transform.m_type = TxNone;
@@ -520,6 +545,12 @@
 {
     if (sh == 0 && sv == 0)
         return *this;
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(sh) | qIsNaN(sv)) {
+        qWarning() << "QTransform::shear with NaN called";
+        return *this;
+    }
+#endif
 
     switch(inline_type()) {
     case TxNone:
@@ -575,6 +606,12 @@
 {
     if (a == 0)
         return *this;
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(a)) {
+        qWarning() << "QTransform::rotate with NaN called";
+        return *this;
+    }
+#endif
 
     qreal sina = 0;
     qreal cosa = 0;
@@ -660,6 +697,12 @@
 */
 QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
 {
+#ifndef QT_NO_DEBUG
+    if (qIsNaN(a)) {
+        qWarning() << "QTransform::rotateRadians with NaN called";
+        return *this;
+    }
+#endif
     qreal sina = qSin(a);
     qreal cosa = qCos(a);
 
@@ -1037,8 +1080,18 @@
 #ifndef QT_NO_DEBUG_STREAM
 QDebug operator<<(QDebug dbg, const QTransform &m)
 {
-    dbg.nospace() << "QTransform("
-                  << "11="  << m.m11()
+    static const char *typeStr[] =
+    {
+        "TxNone",
+        "TxTranslate",
+        "TxScale",
+        "TxRotate",
+        "TxShear",
+        "TxProject"
+    };
+
+    dbg.nospace() << "QTransform(type=" << typeStr[m.type()] << ','
+                  << " 11=" << m.m11()
                   << " 12=" << m.m12()
                   << " 13=" << m.m13()
                   << " 21=" << m.m21()
@@ -1048,6 +1101,7 @@
                   << " 32=" << m.m32()
                   << " 33=" << m.m33()
                   << ')';
+
     return dbg.space();
 }
 #endif
@@ -1491,12 +1545,19 @@
 
     return true;
 }
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
 
 static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo)
 {
     // Convert projective xformed curves to line
     // segments so they can be transformed more accurately
-    QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon();
+
+    qreal scale;
+    qt_scaleForTransform(transform, &scale);
+
+    qreal curveThreshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale);
+
+    QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(curveThreshold);
 
     for (int i = 0; i < segment.size() - 1; ++i)
         if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo))