From b770651f19741907cd415ea9ad6e087cb32cc948 Mon Sep 17 00:00:00 2001
From: Thierry Bastian <thierry.bastian@nokia.com>
Date: Fri, 14 Aug 2009 13:01:37 +0200
Subject: QVariant: added toFloat and toReal

Made better use of qreal all over the place. We were previously
using QVariant::toDouble a lot. That is triggering unnecessary
conversions between float and double on embedded.

Reviewed-by: ogoffart
---
 src/corelib/kernel/qvariant.cpp             | 57 +++++++++++++++++++++++------
 src/corelib/kernel/qvariant.h               |  2 +
 src/gui/graphicsview/qgraphicsitem.cpp      | 11 +++---
 src/gui/image/qpnghandler.cpp               |  2 +-
 src/gui/itemviews/qitemdelegate.cpp         |  5 ++-
 src/gui/itemviews/qsortfilterproxymodel.cpp |  4 +-
 src/gui/itemviews/qstandarditemmodel.cpp    |  4 +-
 src/gui/itemviews/qstyleditemdelegate.cpp   |  3 +-
 src/gui/painting/qpdf.cpp                   | 10 ++---
 src/gui/painting/qprintengine_win.cpp       |  8 ++--
 src/gui/painting/qprinter.cpp               |  8 ++--
 src/gui/text/qcssparser.cpp                 | 13 +++----
 src/gui/text/qtextdocumentlayout.cpp        |  4 +-
 src/gui/text/qtextformat.cpp                |  7 ++--
 14 files changed, 90 insertions(+), 48 deletions(-)

diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index b26cfdd..3c430eb 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -936,10 +936,10 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result,
         float *f = static_cast<float *>(result);
         switch (d->type) {
         case QVariant::String:
-            *f = float(v_cast<QString>(d)->toDouble(ok));
+            *f = v_cast<QString>(d)->toFloat(ok);
             break;
         case QVariant::ByteArray:
-            *f = float(v_cast<QByteArray>(d)->toDouble(ok));
+            *f = v_cast<QByteArray>(d)->toFloat(ok);
             break;
         case QVariant::Bool:
             *f = float(d->data.b);
@@ -1054,7 +1054,7 @@ static void streamDebug(QDebug dbg, const QVariant &v)
         dbg.nospace() << v.toULongLong();
         break;
     case QMetaType::Float:
-        dbg.nospace() << qVariantValue<float>(v);
+        dbg.nospace() << v.toFloat();
         break;
     case QMetaType::QObjectStar:
         dbg.nospace() << qVariantValue<QObject *>(v);
@@ -2331,16 +2331,17 @@ QBitArray QVariant::toBitArray() const
 }
 
 template <typename T>
-inline T qNumVariantToHelper(const QVariant::Private &d, QVariant::Type t,
+inline T qNumVariantToHelper(const QVariant::Private &d,
                              const QVariant::Handler *handler, bool *ok, const T& val)
 {
+    uint t = qMetaTypeId<T>();
     if (ok)
         *ok = true;
     if (d.type == t)
         return val;
 
     T ret;
-    if (!handler->convert(&d, t, &ret, ok) && ok)
+    if (!handler->convert(&d, QVariant::Type(t), &ret, ok) && ok)
         *ok = false;
     return ret;
 }
@@ -2362,7 +2363,7 @@ inline T qNumVariantToHelper(const QVariant::Private &d, QVariant::Type t,
 */
 int QVariant::toInt(bool *ok) const
 {
-    return qNumVariantToHelper<int>(d, Int, handler, ok, d.data.i);
+    return qNumVariantToHelper<int>(d, handler, ok, d.data.i);
 }
 
 /*!
@@ -2382,7 +2383,7 @@ int QVariant::toInt(bool *ok) const
 */
 uint QVariant::toUInt(bool *ok) const
 {
-    return qNumVariantToHelper<uint>(d, UInt, handler, ok, d.data.u);
+    return qNumVariantToHelper<uint>(d, handler, ok, d.data.u);
 }
 
 /*!
@@ -2397,7 +2398,7 @@ uint QVariant::toUInt(bool *ok) const
 */
 qlonglong QVariant::toLongLong(bool *ok) const
 {
-    return qNumVariantToHelper<qlonglong>(d, LongLong, handler, ok, d.data.ll);
+    return qNumVariantToHelper<qlonglong>(d, handler, ok, d.data.ll);
 }
 
 /*!
@@ -2413,7 +2414,7 @@ qlonglong QVariant::toLongLong(bool *ok) const
 */
 qulonglong QVariant::toULongLong(bool *ok) const
 {
-    return qNumVariantToHelper<qulonglong>(d, ULongLong, handler, ok, d.data.ull);
+    return qNumVariantToHelper<qulonglong>(d, handler, ok, d.data.ull);
 }
 
 /*!
@@ -2440,7 +2441,7 @@ bool QVariant::toBool() const
 
 /*!
     Returns the variant as a double if the variant has type() \l
-    Double, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
+    Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
     UInt, or \l ULongLong; otherwise returns 0.0.
 
     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
@@ -2450,7 +2451,41 @@ bool QVariant::toBool() const
 */
 double QVariant::toDouble(bool *ok) const
 {
-    return qNumVariantToHelper<double>(d, Double, handler, ok, d.data.d);
+    return qNumVariantToHelper<double>(d, handler, ok, d.data.d);
+}
+
+/*!
+    Returns the variant as a float if the variant has type() \l
+    Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
+    UInt, or \l ULongLong; otherwise returns 0.0.
+
+    \since 4.6
+
+    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
+    converted to a double; otherwise \c{*}\a{ok} is set to false.
+
+    \sa canConvert(), convert()
+*/
+float QVariant::toFloat(bool *ok) const
+{
+    return qNumVariantToHelper<float>(d, handler, ok, d.data.d);
+}
+
+/*!
+    Returns the variant as a qreal if the variant has type() \l
+    Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
+    UInt, or \l ULongLong; otherwise returns 0.0.
+
+    \since 4.6
+
+    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
+    converted to a double; otherwise \c{*}\a{ok} is set to false.
+
+    \sa canConvert(), convert()
+*/
+qreal QVariant::toReal(bool *ok) const
+{
+    return qNumVariantToHelper<qreal>(d, handler, ok, d.data.d);
 }
 
 /*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 569355a..79bd5b8 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -250,6 +250,8 @@ class Q_CORE_EXPORT QVariant
     qulonglong toULongLong(bool *ok = 0) const;
     bool toBool() const;
     double toDouble(bool *ok = 0) const;
+    float toFloat(bool *ok = 0) const;
+    qreal toReal(bool *ok = 0) const;
     QByteArray toByteArray() const;
     QBitArray toBitArray() const;
     QString toString() const;
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 537dab7..74b8fe2 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2192,11 +2192,10 @@ qreal QGraphicsItem::effectiveOpacity() const
 void QGraphicsItem::setOpacity(qreal opacity)
 {
     // Notify change.
-    const QVariant newOpacityVariant(itemChange(ItemOpacityChange, double(opacity)));
-    qreal newOpacity = newOpacityVariant.toDouble();
+    const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
 
-    // Normalize.
-    newOpacity = qBound<qreal>(0.0, newOpacity, 1.0);
+    // Normalized opacity
+    qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
 
     // No change? Done.
     if (newOpacity == d_ptr->opacity)
@@ -3696,8 +3695,8 @@ qreal QGraphicsItem::zValue() const
 */
 void QGraphicsItem::setZValue(qreal z)
 {
-    const QVariant newZVariant(itemChange(ItemZValueChange, double(z)));
-    qreal newZ = qreal(newZVariant.toDouble());
+    const QVariant newZVariant(itemChange(ItemZValueChange, z));
+    qreal newZ = newZVariant.toReal();
     if (newZ == d_ptr->z)
         return;
 
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index e3475d6..64bc5d3 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -956,7 +956,7 @@ QVariant QPngHandler::option(ImageOption option) const
 void QPngHandler::setOption(ImageOption option, const QVariant &value)
 {
     if (option == Gamma)
-        d->gamma = value.toDouble();
+        d->gamma = value.toFloat();
     else if (option == Quality)
         d->quality = value.toInt();
     else if (option == Description)
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 75d48a4..2cbde51 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -352,7 +352,10 @@ void QItemDelegate::setClipping(bool clip)
 QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItemV4 &option)
 {
     QString text;
-    switch (value.type()) {
+    switch (value.userType()) {
+        case QMetaType::Float:
+            text = option.locale.toString(value.toFloat(), 'g');
+            break;
         case QVariant::Double:
             text = option.locale.toString(value.toDouble(), 'g', DBL_DIG);
             break;
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index d39506d..8444a5b 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -2316,7 +2316,7 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex
     Q_D(const QSortFilterProxyModel);
     QVariant l = (left.model() ? left.model()->data(left, d->sort_role) : QVariant());
     QVariant r = (right.model() ? right.model()->data(right, d->sort_role) : QVariant());
-    switch (l.type()) {
+    switch (l.userType()) {
     case QVariant::Invalid:
         return (r.type() == QVariant::Invalid);
     case QVariant::Int:
@@ -2327,6 +2327,8 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex
         return l.toLongLong() < r.toLongLong();
     case QVariant::ULongLong:
         return l.toULongLong() < r.toULongLong();
+    case QMetaType::Float:
+        return l.toFloat() < r.toFloat();
     case QVariant::Double:
         return l.toDouble() < r.toDouble();
     case QVariant::Char:
diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp
index 7505ccc..168d423 100644
--- a/src/gui/itemviews/qstandarditemmodel.cpp
+++ b/src/gui/itemviews/qstandarditemmodel.cpp
@@ -1809,7 +1809,7 @@ bool QStandardItem::operator<(const QStandardItem &other) const
     const int role = model() ? model()->sortRole() : Qt::DisplayRole;
     const QVariant l = data(role), r = other.data(role);
     // this code is copied from QSortFilterProxyModel::lessThan()
-    switch (l.type()) {
+    switch (l.userType()) {
     case QVariant::Invalid:
         return (r.type() == QVariant::Invalid);
     case QVariant::Int:
@@ -1820,6 +1820,8 @@ bool QStandardItem::operator<(const QStandardItem &other) const
         return l.toLongLong() < r.toLongLong();
     case QVariant::ULongLong:
         return l.toULongLong() < r.toULongLong();
+    case QMetaType::Float:
+        return l.toFloat() < r.toFloat();
     case QVariant::Double:
         return l.toDouble() < r.toDouble();
     case QVariant::Char:
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 0494d4f..f7c7d12 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -267,7 +267,8 @@ QStyledItemDelegate::~QStyledItemDelegate()
 QString QStyledItemDelegate::displayText(const QVariant &value, const QLocale& locale) const
 {
     QString text;
-    switch (value.type()) {
+    switch (value.userType()) {
+    case QMetaType::Float:
     case QVariant::Double:
         text = locale.toString(value.toDouble());
         break;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 3f5643e..9b3b289 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1471,10 +1471,10 @@ void QPdfBaseEngine::setProperty(PrintEnginePropertyKey key, const QVariant &val
     {
         QList<QVariant> margins(value.toList());
         Q_ASSERT(margins.size() == 4);
-        d->leftMargin = margins.at(0).toDouble();
-        d->topMargin = margins.at(1).toDouble();
-        d->rightMargin = margins.at(2).toDouble();
-        d->bottomMargin = margins.at(3).toDouble();
+        d->leftMargin = margins.at(0).toReal();
+        d->topMargin = margins.at(1).toReal();
+        d->rightMargin = margins.at(2).toReal();
+        d->bottomMargin = margins.at(3).toReal();
         d->hasCustomPageMargins = true;
         break;
     }
@@ -1576,7 +1576,7 @@ QVariant QPdfBaseEngine::property(PrintEnginePropertyKey key) const
             margins << d->leftMargin << d->topMargin
                     << d->rightMargin << d->bottomMargin;
         } else {
-            const int defaultMargin = 10; // ~3.5 mm
+            const qreal defaultMargin = 10; // ~3.5 mm
             margins << defaultMargin << defaultMargin
                     << defaultMargin << defaultMargin;
         }
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index 7ac3224..21c0873 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -1360,10 +1360,10 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
         Q_ASSERT(margins.size() == 4);
         int left, top, right, bottom;
         // specified in 1/100 mm
-        left = (margins.at(0).toDouble()*25.4/72.0) * 100;
-        top = (margins.at(1).toDouble()*25.4/72.0) * 100;
-        right = (margins.at(2).toDouble()*25.4/72.0) * 100;
-        bottom = (margins.at(3).toDouble()*25.4/72.0) * 100;
+        left = (margins.at(0).toReal()*25.4/72.0) * 100;
+        top = (margins.at(1).toReal()*25.4/72.0) * 100;
+        right = (margins.at(2).toReal()*25.4/72.0) * 100;
+        bottom = (margins.at(3).toReal()*25.4/72.0) * 100;
         d->setPageMargins(left, top, right, bottom);
         break;
     }
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index 6910eb3..f8399af 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -1665,10 +1665,10 @@ void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bott
     Q_ASSERT(left && top && right && bottom);
     const qreal multiplier = qt_multiplierForUnit(unit, resolution());
     QList<QVariant> margins(d->printEngine->property(QPrintEngine::PPK_PageMargins).toList());
-    *left = margins.at(0).toDouble() / multiplier;
-    *top = margins.at(1).toDouble() / multiplier;
-    *right = margins.at(2).toDouble() / multiplier;
-    *bottom = margins.at(3).toDouble() / multiplier;
+    *left = margins.at(0).toReal() / multiplier;
+    *top = margins.at(1).toReal() / multiplier;
+    *right = margins.at(2).toReal() / multiplier;
+    *bottom = margins.at(3).toReal() / multiplier;
 }
 
 /*!
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index e0af6d2..181ec7e 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -382,10 +382,7 @@ LengthData ValueExtractor::lengthValue(const Value& v)
     if (data.unit != LengthData::None)
         s.chop(2);
 
-    bool ok;
-    data.number = s.toDouble(&ok);
-    if (!ok)
-        data.number = 0;
+    data.number = s.toDouble();
     return data;
 }
 
@@ -711,7 +708,7 @@ static ColorData parseColorValue(Value v)
 
     for (int i = 0; i < qMin(colorDigits.count(), 7); i += 2) {
         if (colorDigits.at(i).type == Value::Percentage) {
-            colorDigits[i].variant = colorDigits.at(i).variant.toDouble() * 255. / 100.;
+            colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (255. / 100.);
             colorDigits[i].type = Value::Number;
         } else if (colorDigits.at(i).type != Value::Number) {
             return ColorData();
@@ -788,7 +785,7 @@ static BrushData parseBrushValue(const Value &v, const QPalette &pal)
             ColorData cd = parseColorValue(color);
             if(cd.type == ColorData::Role)
                 dependsOnThePalette = true;
-            stops.append(QGradientStop(stop.variant.toDouble(), colorFromData(cd, pal)));
+            stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal)));
         } else {
             parser.next();
             Value value;
@@ -1079,8 +1076,8 @@ static bool setFontSizeFromValue(Value value, QFont *font, int *fontSizeAdjustme
     if (s.endsWith(QLatin1String("pt"), Qt::CaseInsensitive)) {
         s.chop(2);
         value.variant = s;
-        if (value.variant.convert(QVariant::Double)) {
-            font->setPointSizeF(value.variant.toDouble());
+        if (value.variant.convert((QVariant::Type)qMetaTypeId<qreal>())) {
+            font->setPointSizeF(value.variant.toReal());
             valid = true;
         }
     } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) {
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index cfec8e9..e26961f 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -198,8 +198,8 @@ public:
         if (v.isNull()) {
             return cellPadding;
         } else {
-            Q_ASSERT(v.type() == QVariant::Double);
-            return QFixed::fromReal(v.toDouble() * deviceScale);
+            Q_ASSERT(v.userType() == QVariant::Double || v.userType() == QMetaType::Float);
+            return QFixed::fromReal(v.toReal() * deviceScale);
         }
     }
 
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 8e9b892..075f2ff 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -271,6 +271,7 @@ static uint variantHash(const QVariant &variant)
     case QVariant::Invalid: return 0;
     case QVariant::Bool: return variant.toBool();
     case QVariant::Int: return variant.toInt();
+    case QMetaType::Float: return static_cast<int>(variant.toFloat());
     case QVariant::Double: return static_cast<int>(variant.toDouble());
     case QVariant::String: return qHash(variant.toString());
     case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb());
@@ -325,7 +326,7 @@ void QTextFormatPrivate::recalcFont() const
                 f.setFamily(props.at(i).value.toString());
                 break;
             case QTextFormat::FontPointSize:
-                f.setPointSizeF(props.at(i).value.toDouble());
+                f.setPointSizeF(props.at(i).value.toReal());
                 break;
             case  QTextFormat::FontPixelSize:
                 f.setPixelSize(props.at(i).value.toInt());
@@ -352,10 +353,10 @@ void QTextFormatPrivate::recalcFont() const
                 f.setStrikeOut(props.at(i).value.toBool());
                 break;
             case QTextFormat::FontLetterSpacing:
-                f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toDouble());
+                f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toReal());
                 break;
             case QTextFormat::FontWordSpacing:
-                f.setWordSpacing(props.at(i).value.toDouble());
+                f.setWordSpacing(props.at(i).value.toReal());
                 break;
             case QTextFormat::FontCapitalization:
                 f.setCapitalization(static_cast<QFont::Capitalization> (props.at(i).value.toInt()));
-- 
cgit v0.12